zoukankan      html  css  js  c++  java
  • 重写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);
            }
        }
    
    }

       代码一目了然,具体就不讲解了,关键是思路,即如何才能想到是怎么实现的。如有疑问,欢迎留言。谢谢。

     欢迎关注公众号"Devin说",会不定期更新技术知识

  • 相关阅读:
    LeetCode 42. Trapping Rain Water
    LeetCode 209. Minimum Size Subarray Sum
    LeetCode 50. Pow(x, n)
    LeetCode 80. Remove Duplicates from Sorted Array II
    Window10 激活
    Premiere 关键帧缩放
    AE 「酷酷的藤」特效字幕制作方法
    51Talk第一天 培训系列1
    Premiere 视频转场
    Premiere 暴徒生活Thug Life
  • 原文地址:https://www.cnblogs.com/devinzhang/p/2590222.html
Copyright © 2011-2022 走看看