重写ScrollView实现两个ScrollView的同步滚动显示
1.背景介绍
最近项目用到两个ScrollView的同步显示,即拖动左边的ScrollView滚动的同时,实现右边的ScrollView同步滚动。此种情形常用在复杂界面布局中,比如左边的ScrollView显示主要项目,只需上下滚动即可;右边项目是次要项目,可以实现上下或者左右滚动,当上下滚动时,需要左右两边的同步显示。

如图所示,左侧是主项目(日期和股票代码),右侧是次要项目(开盘价、最高价、成交量....等等信息)。因为信息比较多,左侧的主项目需要上下拖动显示,而右侧则需要上下左右都可以拖动才能显示完全(ScrollView嵌套一个HorizontalScrollView)。我们希望左侧或右侧上下拖动时,能够实现同步。这就需要实现两个ScrollView的同步显示。因为Android控件中没有此种功能,因此需要重写ScrollView。
2.思路介绍
我们首先想到使用ScrollView的类似与setOnScrollChangedListener的方法来实现,当一个ScrollView滚动时,触发该方法进而使另外一个ScrollView滚动。不过很遗憾,谷歌没有提供该方法。通过查询相应的源代码,我们发现该方法的原型
protected void onScrollChanged(int x, int y, int oldx, int oldy)
该方法是protected类型,不能直接调用,于是需要重新实现ScrollView。
3.具体实现
首先,定一个一个接口(ScrollViewListener.java):
public interface ScrollViewListener {
void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
}
我们需要重写ScrollView才能实现该借口,因此有下面的代码(ObservableScrollView.java):
package com.devin; import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView; public class ObservableScrollView extends ScrollView { private ScrollViewListener scrollViewListener = null; public ObservableScrollView(Context context) {
super(context);
} public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
} @Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
super.onScrollChanged(x, y, oldx, oldy);
if(scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
}
} }
接下来是界面的XML,这里是一个简单的Demo,如下(main.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#ffffff"
android:orientation="horizontal" > <com.devin.ObservableScrollView
android:id="@+id/scrollview1"
android:layout_width="400dp"
android:layout_height="wrap_content" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" > <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="monday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="tuesday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="wednesday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="thursday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="friday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="saturday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="sunday"
android:textColor="#000000" />
</LinearLayout>
</com.devin.ObservableScrollView> <com.devin.ObservableScrollView
android:id="@+id/scrollview2"
android:layout_width="400dp"
android:layout_height="wrap_content" > <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" > <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="monday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="tuesday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="wednesday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="thursday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="friday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="saturday"
android:textColor="#000000" /> <TextView
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_weight="1"
android:text="sunday"
android:textColor="#000000" />
</LinearLayout>
</com.devin.ObservableScrollView> </LinearLayout>
最后是我们的主程调用(PadTestActivity.java):
package com.devin; import android.app.Activity;
import android.os.Bundle; public class PadTestActivity extends Activity implements ScrollViewListener { private ObservableScrollView scrollView1 = null;
private ObservableScrollView scrollView2 = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); scrollView1 = (ObservableScrollView) findViewById(R.id.scrollview1);
scrollView1.setScrollViewListener(this);
scrollView2 = (ObservableScrollView) findViewById(R.id.scrollview2);
scrollView2.setScrollViewListener(this);
} public void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy) {
if(scrollView == scrollView1) {
scrollView2.scrollTo(x, y);
} else if(scrollView == scrollView2) {
scrollView1.scrollTo(x, y);
}
} }
代码一目了然,具体就不讲解了,关键是思路,即如何才能想到是怎么实现的。如有疑问,欢迎留言。谢谢。
重写ScrollView实现两个ScrollView的同步滚动显示的更多相关文章
- VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法
原文:VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/ar ...
- Android实现两个ScrollView互相联动,同步滚动的效果
公众号:smart_android 作者:loonggg 点击"阅读原文",可查看更多内容和干货 最近在做一个项目,用到了两个ScrollView互相联动的效果,简单来说联动效果意 ...
- ScrollView中嵌套ListView时,listview高度显示的问题
方法一:直接更改listview的控件高度,动态获取(根据条目和每个条目的高度获取) 前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个Lis ...
- Android 解决ScrollView嵌入ListView | GridView | ScrollView显示问题
一.ScrollView中嵌套ListView ScrollView和ListView都是滚动结构,很明显如果在ScrollView中加入ListView,可以预见性的知道,肯定会有显示/滚动的问题, ...
- Android ScrollView嵌套ViewPager,嵌套的ViewPager无法显示
记录:ScrollView嵌套ViewPager,嵌套的ViewPager无法显示 项目中所需要布局:LinearLayout中包含(orientation="vertical") ...
- C#超简单方法实现两个richtextbox控件滚动条同步滚动
此文章属于作者原创,转载请注明,谢谢 有时候我们需要实现对照文章等,往往将文本放到两个richtextbox控件中,但是,如果我们需要同步滚动查看,来达到更好的观看效果. 当然,传统的方法重载控件或者 ...
- WPF学习笔记(5):两个DataGrid的滚动条实现同步滚动
效果:两个DataGrid的滚动条实现同步滚动. 代码参考了博客园chuncn的文章<.net中同步多个ScrollViewer滚动的四种方法>,原文是针对ListBox的.现改为针对Da ...
- SQL DATACOMPARE 实现两个数据库的同步处理.
1. SQL DATACOMPARE 实现 两个数据库的同步 安装破解. 然后进行对比 然后进行 deploy 生成sql 等. 貌似很好用 但是前提是数据库是可用的... 这里面能够看到 生成的脚本 ...
- iOS之两个ImageView实现图片滚动
原创作者:codingZero 导语 在不少项目中,都会有图片轮播这个功能,现在网上关于图片轮播的框架层出不穷,千奇百怪,笔者根据自己的思路,用两个imageView也实现了图片轮播,这里说说笔者的主 ...
随机推荐
- Linq系列(7)——表达式树之ExpressionVisitor
大家好,由于今天项目升级,大家都在获最新代码,所以我又有时间在这里写点东西,跟大家分享. 在上一篇的文章中我介绍了一个dll,使大家在debug的时候可以可视化的看到ExpressionTree的Bo ...
- iOS 线程管理的学习记录
本文转载至 http://www.2cto.com/kf/201312/265451.html 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...
- sgu Theodore Roosevelt【判断点是否在凸多边形内模板】
链接: http://acm.sgu.ru/problem.php?contest=0&problem=253 http://acm.hust.edu.cn/vjudge/contest/vi ...
- 【译】StackOverflow——Java 中的 finally 代码块是否总会被执行?
问题 有一个 try/catch 代码块,其中包含一个打印语句.finally代码块总会被调用么? 示例: try { something(); return success; } catch (Ex ...
- linux c编程:信号(三) sigprocmask和sigpending函数
信号源为目标进程产生了一个信号,然后由内核来决定是否要将该信号传递给目标进程.从信号产生到传递给目标进程的流程图如下图所示: 进程可以阻塞信号的传递.当信号源为目标进程产生了一个信号之后,内核会执行依 ...
- 在Ubuntu安装go编译环境
在Ubuntu安装go编译环境 好记性不如烂笔头,所以趁热打铁记录下golang编译环境的安装过程. 首先下载一些依赖包: sudo apt-get install bison ed gawk gcc ...
- (转)Javascript模块化编程(二):AMD规范
这个系列的第一部分介绍了Javascript模块的基本写法,今天介绍如何规范地使用模块. (接上文) 七.模块的规范 先想一想,为什么模块很重要? 因为有了模块,我们就可以更方便地使用别人的代码,想要 ...
- angularjs 中的iframe 标签 ng-src 路径 z-index 必须有position
如果直接写路径到iframe标签里的ng-src中会出现报错: 解决方法: 1.ng里面有个属性是专门用来解决跨域问题的 $sce. 用法: $scope.someUrl = $sce.trustAs ...
- linux删除文件夹的命令
使用rm -rf 目录名字 命令即可 -r 就是向下递归,不管有多少级目录,一并删除-f 就是直接强行删除,不作任何提示的意思 eg 删除文件夹实例:rm -rf /var/log/httpd/acc ...
- eclipse---个人设置
window---- preferences -----修改背景颜色 -----修改字体 ----修改窗口主题 ----设置编码 -----设置编译环境 ----设置web项目JDK编译的版本 --- ...