水平/垂直滚动联动

证券炒股软件经常会遇到有很多Tab要显示,使得控件的上下/垂直滚动联动经常要使用到,比如撤单,查询等业务都要用到这个控件,今天刚好项目没那么紧,就把这个控件的实现总结一下。
先看看我们实现后的效果效果图
分析:这里我们用一个水平滑动控件HorizontalScrollView和一个ListView组合实现水平滑动和垂直滑动
一、自定义一个LinearLayout的视图容器控件,截取掉子控件的触摸监听事件,阻止 拦截 ontouch事件传递给其子控件
步骤:新建一个ObserverHScrollViewIntercept类继承LinearLayout重写onInterceptTouchEvent方法,把触摸事件消费掉,不要往子类继续传递。

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

/**
 *一个视图容器控件
 * 阻止 拦截 ontouch事件传递给其子控件
 * Created by willkong on 2016/11/15.
 */

public class ObserverHScrollViewIntercept extends LinearLayout{
   
    public ObserverHScrollViewIntercept(Context context) {
        this(context,null);
    }

    public ObserverHScrollViewIntercept(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ObserverHScrollViewIntercept(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return true;
    }
}

二、新建一个ObserverHScrollView类继承HorizontalScrollView
这里主要的技术是写了一个监听观察者,ScrollViewObserver。先给控件添加滑动变化的监听,只要用户一滑动,就通知观察者。
先在该类中写一个观察者类ScrollViewObserver。这个类的主要作用是把监听到的滑动变化回调给调用者,所以,我们要先写一个滑动变化监听回调接口OnScrollChangedListener

    /*
     * 当发生了滚动事件时,调用这个接口,根据坐标滑动到对应的位置
     */
    public static interface OnScrollChangedListener {
        public void onScrollChanged(int l, int t, int oldl, int oldt);
    }

在观察者类中定义一个list,把监听到的每一次的滚动事件保存起来。并且写两个添加监听和移除监听的方法,还有一个回调接口方法,把监听到的发生滚动事件回调给调用者。

    /*
     * 观察者
     */
    public static class ScrollViewObserver {
        List<OnScrollChangedListener> mList;

        public ScrollViewObserver() {
            super();
            mList = new ArrayList<OnScrollChangedListener>();
        }

        public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
            mList.add(listener);
        }

        public void RemoveOnScrollChangedListener(
                OnScrollChangedListener listener) {
            mList.remove(listener);
        }

        public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {
            if (mList == null || mList.size() == 0) {
                return;
            }
            for (int i = 0; i < mList.size(); i++) {
                if (mList.get(i) != null) {
                    mList.get(i).onScrollChanged(l, t, oldl, oldt);
                }
            }
        }
    }

整个类代码:


import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;

import java.util.ArrayList;
import java.util.List;

/**
 * 自定义的 滚动控件
 * 重载了 onScrollChanged(滚动条变化),监听每次的变化通知给 观察(此变化的)观察者
 * 可使用 AddOnScrollChangedListener 来订阅本控件的 滚动条变化
 * Created by willkong on 2016/11/15.
 */

public class ObserverHScrollView extends HorizontalScrollView{
   
    //新建一个监听者,接口回调使用
    ScrollViewObserver mScrollViewObserver = new ScrollViewObserver();

    public ObserverHScrollView(Context context) {
        this(context,null);
    }

    public ObserverHScrollView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ObserverHScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return super.onTouchEvent(ev);
    }

    /**
     * 监听控件的滑动变化
     * @param l
     * @param t
     * @param oldl
     * @param oldt
     */
    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        /*
         * 当滚动条移动后,引发 滚动事件。通知给观察者,观察者会传达给其他的。
         */
        if (mScrollViewObserver != null /*&& (l != oldl || t != oldt)*/) {
            mScrollViewObserver.NotifyOnScrollChanged(l, t, oldl, oldt);
        }
        super.onScrollChanged(l, t, oldl, oldt);
    }

    /*
     * 订阅 本控件 的 滚动条变化事件
     * */
    public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
        mScrollViewObserver.AddOnScrollChangedListener(listener);
    }

    /*
     * 取消 订阅 本控件 的 滚动条变化事件
     * */
    public void RemoveOnScrollChangedListener(OnScrollChangedListener listener) {
        mScrollViewObserver.RemoveOnScrollChangedListener(listener);
    }


    /**
     * 观察者
     */
    public static class ScrollViewObserver{
   
        List<OnScrollChangedListener> mList;
        public ScrollViewObserver(){
            super();
            mList = new ArrayList<OnScrollChangedListener>();

        }

        /**
         * 订阅 本控件 的 滚动条变化事件
         * @param listener
         */
        public void AddOnScrollChangedListener(OnScrollChangedListener listener) {
            mList.add(listener);
        }

        /**
         * 取消 订阅 本控件 的 滚动条变化事件
         * @param listener
         */
        public void RemoveOnScrollChangedListener(
                OnScrollChangedListener listener) {
            mList.remove(listener);
        }

        public void NotifyOnScrollChanged(int l, int t, int oldl, int oldt) {
            if (mList == null || mList.size() == 0) {
                return;
            }
            for (int i = 0; i < mList.size(); i++) {
                if (mList.get(i) != null) {
                    mList.get(i).onScrollChanged(l, t, oldl, oldt);
                }
            }
        }

    }

    /*
     * 当发生了滚动事件时,调用这个接口
     */
    public static interface OnScrollChangedListener {
   
        public void onScrollChanged(int l, int t, int oldl, int oldt);
    }
}

到这里控件就已经编写完毕了,下面我们来讲,怎么使用这个控件。
三、新建一个类HVScorllListviewActivity
首先新建一个头部标题ativity_hvscorll_listview_item的布局文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/demo_list_selector"
    android:descendantFocusability="blocksDescendants"
    android:orientation="horizontal"
    android:paddingBottom="10dp"
    android:paddingTop="10dp"
    tools:context="com.hvscorlllistviewdemo.HVScorllListviewActivity">
    <TextView
        android:id="@+id/textView1"
        android:layout_width="@dimen/bond_table_header_width"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:gravity="center"
        android:text="@string/bound_search_result_head_zqmc"
        android:textColor="@color/black"
        android:textSize="@dimen/bond_table_header_text" />
    <com.hvscorlllistviewdemo.ObserverHScrollViewIntercept
        android:id="@+id/scroollContainter"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/textView1"
        android:focusable="false">
        <com.hvscorlllistviewdemo.ObserverHScrollView
            android:id="@+id/horizontalScrollView1"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:focusable="false"
            android:scrollbars="none">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:focusable="false"
                android:gravity="center"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/textView2"
                    android:layout_width="@dimen/bond_table_header_width"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="@string/bound_search_result_head_zqjc"
                    android:textColor="@color/black"
                    android:textSize="@dimen/bond_table_header_text" />

                <TextView
                    android:id="@+id/textView3"
                    android:layout_width="@dimen/bond_table_header_width"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="@string/bound_search_result_head_zqdm"
                    android:textColor="@color/black"
                    android:textSize="@dimen/bond_table_header_text" />

                <TextView
                    android:id="@+id/textView4"
                    android:layout_width="@dimen/bond_table_header_width"
                    android:layout_height="wrap_content"
                    android:gravity="center"
                    android:text="@string/bound_search_result_head_fxjc"
                    android:textColor="@color/black"
                    android:textSize="@dimen/bond_table_header_text" />

                <TextView
                    android:id="@+id/textView5"
                    android:layout_width="@dimen/bond_table_header_width"
                    android:layout_height="wrap_content"
                    android:gravity=&
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值