重写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;}@Overrideprotected 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.ObservableScrollViewandroid:id="@+id/scrollview1"android:layout_width="400dp"android:layout_height="wrap_content" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical" ><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="monday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="tuesday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="wednesday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="thursday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="friday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="saturday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="sunday"android:textColor="#000000" /></LinearLayout></com.devin.ObservableScrollView><com.devin.ObservableScrollViewandroid:id="@+id/scrollview2"android:layout_width="400dp"android:layout_height="wrap_content" ><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical" ><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="monday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="tuesday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="wednesday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="thursday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="friday"android:textColor="#000000" /><TextViewandroid:layout_width="wrap_content"android:layout_height="200dp"android:layout_weight="1"android:text="saturday"android:textColor="#000000" /><TextViewandroid: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;@Overrideprotected 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);}}}
代码一目了然,具体就不讲解了,关键是思路,即如何才能想到是怎么实现的。如有疑问,欢迎留言。谢谢。
转载于:https://www.cnblogs.com/chengzhengfu/p/4578872.html
重写ScrollView实现两个ScrollView的同步滚动显示相关推荐
- vue中两个iframe滚动条同步滚动问题总结
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.问题分析 二.记录爬坑过程 1.获取dom 错误操作:在mounted里面this.$nextTick,如果场景里面有t ...
- vue实现两个区域滚动条同步滚动
项目开发中,遇到一个比较两个form差异的需求,但当item过多就需要滚动条,这里就用到了滚动条同步的地方,其实原理和git的差异比较差不多,这里来做一下分析.这是效果图 要点分析: 其实主要是通过r ...
- 同步滚动两个DataGrid
拿到这个首先想到的就是重写Scroll方法,可是想想工作量有些大,所以想在Form级别上做做手脚,看看DataGrid的成员列表可以看到这样两个保护性的方法: GridHScrolled ...
- 城轨的两类时钟系统均同步于_基于两台SDS3000示波器同步产生“8通道”示波器...
在很多应用场合需要4通道以上的示波器,但是市面上极大部分示波器最多只有四通道,而且没有外部输入的同步时钟接口. 有什么快捷的方法获得更多通道功能的示波器? 最简便的方法是:将两台示波器的辅助输入信号作 ...
- SQL DATACOMPARE 实现两个数据库的同步处理.
1. SQL DATACOMPARE 实现 两个数据库的同步 安装破解. 然后进行对比 然后进行 deploy 生成sql 等. 貌似很好用 但是前提是数据库是可用的... 这里面能够看到 生成的脚本 ...
- 关于git中,两个branch自动同步的问题和解决
关于git中,两个branch自动同步的问题和解决 1问题描述 2问题原因 3解决方法 1问题描述 在git中,如果在一个branch中对代码进行了修改,切不做任何操作直接checkout另一个bra ...
- 文件共享两台电脑不同步
最近在网络上看到网友问:文件共享两台电脑不同步怎么解决?文件共享的两天电脑之间文件做了修改,不能同步,好蛋疼!小编想说,在工作学习中,我们经常会用到两台电脑互相传输文件件,如何高效简洁的完成文件共享, ...
- SwiftUI ScrollView 高级技巧之 01 单击按钮手动滚动到某个位置
实战需求 SwiftUI ScrollView 高级技巧之 01 单击按钮手动滚动到某个位置 开发过程中,有时开发人员希望以编程方式滚动到特定位置,或者希望从下到上滚动,例如聊天视图.交易视图等,我们 ...
- git 局域网 两台电脑之间同步 (不用安装Java和Gitblit和OpenSSH)
git 两台电脑之间同步,两台电脑同属一个局域网,可以是windows和windows,也可以是windows和ubuntu. (不用安装Java和Gitblit和OpenSSH),可以不用连接外网. ...
最新文章
- php中常见的错误类型有,JavaScript中常见的错误类型有哪些?(详细介绍)
- MPB:微生物所王军组-​人类肠道病毒粒子富集及纳米孔测序
- BAT面试必知:DubboZookeeper面试集锦
- OpenGL键盘消息实例
- java客户姓名添加和查找_java类与对象 演练 客户姓名添加与查看
- 计算机学院创新实验室,ACM创新实验室概况
- 搜索——下沙小面的2(hdu1572)
- PCL中点云可视化:坐标字段、随机、单一颜色、法向量
- 【Spring学习】01
- 麦肯锡指出布局金融生态圈对中国国内银行意义重大
- 微博回应用户被“劫持”;途牛否认破产清算;微软宣布开源 MsQuic | 极客头条...
- 迪杰斯特拉算法(dijkstra)
- 专硕考数二英二的计算机专业,专硕难度升级!英二改考英一,数二改考数一
- 使用Travis CI实现C++ CMake工程多平台编译
- 小象学院—小象学院—Python学习联盟09—空气质量指数计算
- 三星android7要更新8,三星Bixby Voice将停止支持安卓7.0/8.0,用户可以升级系统使用...
- android 第三方视频库,android视频播放库
- 算法之算法的时间复杂度
- 为什么要做数仓分层,不做行吗?
- linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟