证券炒股软件经常会遇到有很多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="center"
android:text="@string/bound_search_result_head_ksr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView6"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_fxjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView7"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_sjfxze"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView8"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_jxfs"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView9"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_fxzq"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView10"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_pmll"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView11"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_lc"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView12"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zjll"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView13"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqqx"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView14"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqpj"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView15"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ztpj"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView16"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqpjjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView17"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ztpjjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView18"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqzwdjr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView19"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ltr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView20"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_jzghr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView21"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_qxr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView22"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_dqr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
</LinearLayout>
</com.hvscorlllistviewdemo.ObserverHScrollView>
</com.hvscorlllistviewdemo.ObserverHScrollViewIntercept>
</RelativeLayout>
接下来编写主类的布局文件activity_hvscorll_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<include
android:id="@+id/head"
layout="@layout/activity_hvscorll_listview_head" />
<ListView
android:id="@+id/listView1"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="none"/>
</LinearLayout>
最后在主文件HVScorllListviewActivity中找到对应的控件:下面有两个必须注意的是要把头部控件必须设置
两个属性 mListviewHead.setFocusable(true);//将控件设置成可获取焦点状态,默认是无法获取焦点的,只有设置成true,才能获取控件的点击事件
mListviewHead.setClickable(true);//设置为true时,表明控件可以点击两个属性必须同时设置,不然点击头部是不能滑动的。
为了HorizontalScrollView和ListView控件联动起来,必须重写一个触摸事件,把这个触摸事件传递给这两个控件,使他们联动起来。
/**
* 列头/Listview触摸事件监听器<br>
* 当在列头 和 listView控件上touch时,将这个touch的事件分发给 ScrollView
*/
private View.OnTouchListener mHeadListTouchLinstener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mHorizontalScrollView.onTouchEvent(event);
return false;
}
};
最后设置ListView的适配器,并且把触摸事件传递给每一个Item使他们整体联动起来,再把这个滚动的状态通过接口回调回去,实现控件的接口方法,smoothScrollTo(l,t)移动到对应位置
/**
* 实现接口,获得滑动回调
*/
private class OnScrollChangedListenerImp implements ObserverHScrollView.OnScrollChangedListener {
ObserverHScrollView mScrollViewArg;
public OnScrollChangedListenerImp(ObserverHScrollView scrollViewar) {
mScrollViewArg = scrollViewar;
}
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
mScrollViewArg.smoothScrollTo(l, t);
}
}
下面是在适配器中把他们联动起来的代码
//列表水平滚动条
ObserverHScrollView scrollView1 = (ObserverHScrollView)
convertView.findViewById(R.id.horizontalScrollView1);
holder.scrollView = (ObserverHScrollView) convertView.findViewById
(R.id.horizontalScrollView1);
//列表表头滚动条
ObserverHScrollView headSrcrollView = (ObserverHScrollView)
mListviewHead.findViewById(R.id.horizontalScrollView1);
headSrcrollView.AddOnScrollChangedListener(new OnScrollChangedListenerImp
(scrollView1));
到这里整个控件的使用就完成了。
下面是每个文件的代码:
ObserverHScrollViewIntercept类
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;
/**
*一个视图容器控件
* 阻止 拦截 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类
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);
}
}
activity_hvscorll_listview_head.xml
<?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="center"
android:text="@string/bound_search_result_head_ksr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView6"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_fxjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView7"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_sjfxze"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView8"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_jxfs"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView9"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_fxzq"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView10"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_pmll"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView11"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_lc"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView12"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zjll"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView13"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqqx"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView14"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqpj"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView15"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ztpj"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView16"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqpjjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView17"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ztpjjg"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView18"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_zqzwdjr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView19"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_ltr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView20"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_jzghr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView21"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_qxr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
<TextView
android:id="@+id/textView22"
android:layout_width="@dimen/bond_table_header_width"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/bound_search_result_head_dqr"
android:textColor="@color/black"
android:textSize="@dimen/bond_table_header_text" />
</LinearLayout>
</com.hvscorlllistviewdemo.ObserverHScrollView>
</com.hvscorlllistviewdemo.ObserverHScrollViewIntercept>
</RelativeLayout>
activity_hvscorll_listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<include
android:id="@+id/head"
layout="@layout/activity_hvscorll_listview_head" />
<ListView
android:id="@+id/listView1"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:scrollbars="none"/>
</LinearLayout>
HVScorllListviewActivitylei类
import android.app.Activity;
import android.content.Context;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.HorizontalScrollView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import static android.R.attr.data;
public class HVScorllListviewActivity extends Activity {
private MyAdapter mAdapter;
/**
* 列表表头容器
**/
private RelativeLayout mListviewHead;
/**
* 列表ListView
**/
private ListView mListView;
/**
* 列表ListView水平滚动条
**/
private HorizontalScrollView mHorizontalScrollView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hvscorll_listview);
initView();
}
private void initView() {
//初始化列表表头
mListviewHead = (RelativeLayout) findViewById(R.id.head);
//下面这个两个属性必须同时设置,不然点击头部是不能滑动的
mListviewHead.setFocusable(true);//将控件设置成可获取焦点状态,默认是无法获取焦点的,只有设置成true,才能获取控件的点击事件
mListviewHead.setClickable(true);//设置为true时,表明控件可以点击
mListviewHead.setBackgroundColor(ContextCompat.getColor(this,R.color.table_header));
mListviewHead.setOnTouchListener(mHeadListTouchLinstener);//头部设置触摸事件同时把触摸事件传递给水平滑动控件
mHorizontalScrollView = (HorizontalScrollView) mListviewHead.findViewById(R.id.horizontalScrollView1);
//初始化listview
mListView = (ListView) findViewById(R.id.listView1);
//准备数据
//设置适配器
mAdapter = new MyAdapter(this,mListviewHead);
mListView.setOnTouchListener(mHeadListTouchLinstener);
mListView.setAdapter(mAdapter);
}
/**
* 列头/Listview触摸事件监听器<br>
* 当在列头 和 listView控件上touch时,将这个touch的事件分发给 ScrollView
*/
private View.OnTouchListener mHeadListTouchLinstener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
mHorizontalScrollView.onTouchEvent(event);
return false;
}
};
class MyAdapter extends BaseAdapter{
/**列表表头容器**/
private RelativeLayout mListviewHead;
private Context mContext;
public MyAdapter(Context context,RelativeLayout mListviewHead){
this.mContext = context;
this.mListviewHead = mListviewHead;
}
@Override
public int getCount() {
return 20;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 查找控件
ViewHolder holder = null;
if (null == convertView) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.activity_hvscorll_listview_head, null);
holder = new ViewHolder();
holder.txt1 = (TextView) convertView.findViewById(R.id.textView1);
holder.txt2 = (TextView) convertView.findViewById(R.id.textView2);
holder.txt3 = (TextView) convertView.findViewById(R.id.textView3);
holder.txt4 = (TextView) convertView.findViewById(R.id.textView4);
holder.txt5 = (TextView) convertView.findViewById(R.id.textView5);
holder.txt6 = (TextView) convertView.findViewById(R.id.textView6);
holder.txt7 = (TextView) convertView.findViewById(R.id.textView7);
holder.txt8 = (TextView) convertView.findViewById(R.id.textView8);
holder.txt9 = (TextView) convertView.findViewById(R.id.textView9);
holder.txt10 = (TextView) convertView.findViewById(R.id.textView10);
holder.txt11 = (TextView) convertView.findViewById(R.id.textView11);
holder.txt12 = (TextView) convertView.findViewById(R.id.textView12);
holder.txt13 = (TextView) convertView.findViewById(R.id.textView13);
holder.txt14 = (TextView) convertView.findViewById(R.id.textView14);
holder.txt15 = (TextView) convertView.findViewById(R.id.textView15);
holder.txt16 = (TextView) convertView.findViewById(R.id.textView16);
holder.txt17 = (TextView) convertView.findViewById(R.id.textView17);
holder.txt18 = (TextView) convertView.findViewById(R.id.textView18);
holder.txt19 = (TextView) convertView.findViewById(R.id.textView19);
holder.txt20 = (TextView) convertView.findViewById(R.id.textView20);
holder.txt21 = (TextView) convertView.findViewById(R.id.textView21);
holder.txt22 = (TextView) convertView.findViewById(R.id.textView22);
//列表水平滚动条
ObserverHScrollView scrollView1 = (ObserverHScrollView) convertView.findViewById(R.id.horizontalScrollView1);
holder.scrollView = (ObserverHScrollView) convertView.findViewById(R.id.horizontalScrollView1);
//列表表头滚动条
ObserverHScrollView headSrcrollView = (ObserverHScrollView) mListviewHead.findViewById(R.id.horizontalScrollView1);
headSrcrollView.AddOnScrollChangedListener(new OnScrollChangedListenerImp(scrollView1));
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.txt1.setText("国债");
holder.txt2.setText("简称");
holder.txt3.setText("000000");
holder.txt4.setText("财政部");
holder.txt5.setText("2016-11-15");
holder.txt6.setText("100.00");
holder.txt7.setText("200.00");
holder.txt8.setText("附息式固定利率");
holder.txt9.setText("12");
holder.txt10.setText("2.4200");
holder.txt11.setText("--");
holder.txt12.setText("--");
holder.txt13.setText("--");
holder.txt14.setText("--");
holder.txt15.setText("--");
holder.txt16.setText("--");
holder.txt17.setText("--");
holder.txt18.setText("--");
holder.txt19.setText("--");
holder.txt20.setText("--");
holder.txt21.setText("--");
holder.txt22.setText("结束");
return convertView;
}
}
/**
* 实现接口,获得滑动回调
*/
private class OnScrollChangedListenerImp implements ObserverHScrollView.OnScrollChangedListener {
ObserverHScrollView mScrollViewArg;
public OnScrollChangedListenerImp(ObserverHScrollView scrollViewar) {
mScrollViewArg = scrollViewar;
}
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {
mScrollViewArg.smoothScrollTo(l, t);
}
}
private class ViewHolder {
TextView txt1;
TextView txt2;
TextView txt3;
TextView txt4;
TextView txt5;
TextView txt6;
TextView txt7;
TextView txt8;
TextView txt9;
TextView txt10;
TextView txt11;
TextView txt12;
TextView txt13;
TextView txt14;
TextView txt15;
TextView txt16;
TextView txt17;
TextView txt18;
TextView txt19;
TextView txt20;
TextView txt21;
TextView txt22;
HorizontalScrollView scrollView;
}
}