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的同步滚动显示的更多相关文章

  1. VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法

    原文:VS编程,WPF中两个滚动条 ScrollViewer 同步滚动的一种方法 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/ar ...

  2. Android实现两个ScrollView互相联动,同步滚动的效果

    公众号:smart_android 作者:loonggg 点击"阅读原文",可查看更多内容和干货 最近在做一个项目,用到了两个ScrollView互相联动的效果,简单来说联动效果意 ...

  3. ScrollView中嵌套ListView时,listview高度显示的问题

    方法一:直接更改listview的控件高度,动态获取(根据条目和每个条目的高度获取) 前几天因为项目的需要,要在一个ListView中放入另一个ListView,也即在一个ListView的每个Lis ...

  4. Android 解决ScrollView嵌入ListView | GridView | ScrollView显示问题

    一.ScrollView中嵌套ListView ScrollView和ListView都是滚动结构,很明显如果在ScrollView中加入ListView,可以预见性的知道,肯定会有显示/滚动的问题, ...

  5. Android ScrollView嵌套ViewPager,嵌套的ViewPager无法显示

    记录:ScrollView嵌套ViewPager,嵌套的ViewPager无法显示 项目中所需要布局:LinearLayout中包含(orientation="vertical") ...

  6. C#超简单方法实现两个richtextbox控件滚动条同步滚动

    此文章属于作者原创,转载请注明,谢谢 有时候我们需要实现对照文章等,往往将文本放到两个richtextbox控件中,但是,如果我们需要同步滚动查看,来达到更好的观看效果. 当然,传统的方法重载控件或者 ...

  7. WPF学习笔记(5):两个DataGrid的滚动条实现同步滚动

    效果:两个DataGrid的滚动条实现同步滚动. 代码参考了博客园chuncn的文章<.net中同步多个ScrollViewer滚动的四种方法>,原文是针对ListBox的.现改为针对Da ...

  8. SQL DATACOMPARE 实现两个数据库的同步处理.

    1. SQL DATACOMPARE 实现 两个数据库的同步 安装破解. 然后进行对比 然后进行 deploy 生成sql 等. 貌似很好用 但是前提是数据库是可用的... 这里面能够看到 生成的脚本 ...

  9. iOS之两个ImageView实现图片滚动

    原创作者:codingZero 导语 在不少项目中,都会有图片轮播这个功能,现在网上关于图片轮播的框架层出不穷,千奇百怪,笔者根据自己的思路,用两个imageView也实现了图片轮播,这里说说笔者的主 ...

随机推荐

  1. Android 热门技术干货

    http://mp.weixin.qq.com/s?__biz=MzIwMzYwMTk1NA==&mid=2247484939&idx=1&sn=d1871b09de55ca6 ...

  2. 使用3DES+Base64来加密传输iOS应用数据

    本文转载至 http://www.erblah.com/post/objective-c/shi-yong-3des-base64lai-jia-mi-chuan-shu-iosying-yong-s ...

  3. 【BZOJ3302】[Shoi2005]树的双中心 DFS

    [BZOJ3302][Shoi2005]树的双中心 Description Input 第一行为N,1<N<=50000,表示树的节点数目,树的节点从1到N编号.接下来N-1行,每行两个整 ...

  4. Python闲谈(二)聊聊最小二乘法以及leastsq函数

    1 最小二乘法概述 自从开始做毕设以来,发现自己无时无刻不在接触最小二乘法.从求解线性透视图中的消失点,m元n次函数的拟合,包括后来学到的神经网络,其思想归根结底全都是最小二乘法. 1-1 “多线→一 ...

  5. java Filter的简单使用

    java web中的过滤器的简单使用.直接上代码.1.web.xml <?xml version="1.0" encoding="UTF-8"?> ...

  6. 九度OJ 1261:寻找峰值点 (基础题)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:500 解决:37 题目描述: 给定一个整数序列,该整数序列存在着这几种可能:先递增后递减.先递减后递增.全递减.全递增. 请找出那个最大值的 ...

  7. js函数的caller属性

    funcName.caller : 返回一个对函数的引用, 该函数调用了当前函数 function test() { if (test.caller) { var a = test.caller.to ...

  8. make编译一

    在C和C++中,首先要把源文件编译成中间代码文件,在windows下就是obj文件,linux下就是.o文件:object file.这个动作叫做编译,然后再把大量的object file合成执行文件 ...

  9. c++得到本地username和IP

    bool CDlgResetAlarmInfo::GetLocalUserNameAddIP(CString &a_lstrUserName ,CString &a_IpStr) { ...

  10. php7下 xhprof安装与使用

    需要测试下 代码的性能,使用了 xhprof + xhgui 1. 下载xhprof, 这里下载吧 :https://github.com/longxinH/xhprof.git 2, 安装 cd x ...