重写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也实现了图片轮播,这里说说笔者的主 ...
随机推荐
- ajax Form提交与Payload提交
后端处理前端提交的数据时,既可以使用Form解析,也可以使用JSON解析Payload字符串. Form解析可以直接从Request对象中获取请求参数,这样对象转换与处理相对容易,但在大片JSON数据 ...
- python多任务处理
多任务解析 什么叫“多任务”呢?简单地说,就是操作系统可以同时运行多个任务. 现在,多核CPU已经非常普及了,但是,即使过去的单核CPU,也可以执行 多任务.由于CPU执行代码都是顺序执行的,那么,单 ...
- SpringBoot中的配置文件
http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
- 关于iOS的手势UIGestureRecognizer问题
typedef NS_ENUM(NSInteger, UIGestureRecognizerState) { UIGestureRecognizerStatePossible, // 尚未识别是何种手 ...
- HTML 与 SGML关系
HTML :超文本标记语言,“超文本”就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素 SGML:标准通用标记语言 HTML 是SGML下的一个应用
- Linux学习路线指南
转载的,感觉写的挺好的,我自己知识复制了下,忘记了转载地址,抱歉! Linux学习路线指南 很多同学接触Linux不多,对Linux平台的开发更是一无所知.而现在的趋势越来越表明,作为一个优秀的软件开 ...
- shell脚本调试运行
1.在命令行提供参数:$sh -x script.sh 但是有的shell脚本只能用 ./xxx.sh的方式运行,不能用sh命令解析执行.则此方法会报错.2.脚本开头提供参数:#!/bin/sh ...
- 【学员管理系统】0x02 学生信息管理功能
[学员管理系统]0x02 学生信息管理功能 写在前面 项目详细需求参见:Django项目之[学员管理系统] Django框架大致处理流程 捋一下Django框架相关的内容: 浏览器输入URL到页面展示 ...
- python __name__及__main()__的妙处
#hello.py def sayHello(): str="hello" print(str); if __name__ == "__main__": pri ...
- shell中替换json中指定的值
在linux中部署软件的时候,有时会遇到用shell动态改动json格式的配置文件,比如一下rabbitmq.json文件: { "rabbitmq": { "ssl&q ...