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);
            }
        }
    
    }

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

  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/chengzhengfu/p/4578872.html
Copyright © 2011-2022 走看看