双向滚动ListView

因为最近一个项目的需求,写了一个双向的ListView.

主要的原因的需要显示的数据量大,屏幕放不下,所以需要滚动来显示.在这个基础上还需要是ListView的上侧和左侧的部分保持相对的不滚动.其实上下的滚动系统的ListView自己就可以完成,但是横向的滚动该如何实现呢,尤其是要在纵向的滚动的同时要兼顾左右的滚动.开始的时候没有什么思路,后来也上网查了很多.其中一种的实现思路是在ListView中放置HorizontalScrollView,然后使用dispathTouchEvent方法来分发对滑动事件的响应.然后我也这样做了,但是总不理想,可能是自己的考虑不周到,事件的响应经常会出问题,然后会导致ListView的每一个Item出现不同不的问题.

甚至还试过在左侧放置ListView,右侧放置HorizontalScrollView,然后在右侧的ScrollView里面在放置一个ListView,然后通过事件分发,是左右两侧的ListView上下滚动的时候保持同步,但是总是会出现左右不同步的现象,这样是不行的,即使出现一点的不同步,整个View看起来也会很怪,这样是不能用的.

还有一种思路就是在ListView上层就屏蔽滑动事件,然后使ListView自动响应滚动事件,并同时手工的移动每一个ScrollView.也就是我这里使用的方法.经过测试,这个方法是可行的.并且达到了很好的同步效果.

想到一直以来都是从网上拿东西,也应该有贡献精神.所以这里把代码共享,本人尽量的屏蔽了实现的细节.以下提供API,希望对大家有帮助.

附图:

以下代码属本人原创,转载请注明出处.

 

API使用方法:

  • 要使用双向ListView需要拷贝以下类文件到项目中:

├─adapter

│      BothwayListViewAdapter.java(BothwayListView的Adapter)

│     

└─widget

        BothwayListView.java(要使用的ListView)

        HeaderHorizontalScrollView.java(Header和Item中能够滑动的部分的上层View)

        InterceptLinearLayout.java(HeaderHorizontalScrollView的上层View)

  • 建立相应的Layout文件.

双向滚动的ListView需要有Header.应该与ListView在同一层次放置,并且其结构应该与Item的结构保持一致,即左侧不可以滑动的位置的宽度,右侧可以滚动的View的结构等.推荐直接在ListView上面直接include一个Item的View.这样其结构就会和Item保持完全一致.

例:

(main:)

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2             xmlns:tools="http://schemas.android.com/tools"
 3             android:layout_width="match_parent"
 4             android:layout_height="match_parent"
 5             android:orientation="vertical" >
 6           <!--这里是Header部分,就是在ListView上部不会随ListView的Item上下滑动的部分.
 7         这里直接导入一个Item使用-->
 8             <include
 9                 android:id="@+id/top_header"
10                 layout="@layout/item" >
11             </include>
12        <!—-这里是今天的重点,ListView-->
13             <com.group_06.bothwaylistviewapi.widget.BothwayListView
14                 android:id="@+id/main_listview"
15                 android:layout_width="match_parent"
16                 android:layout_height="match_parent" >
17             </com.group_06.bothwaylistviewapi.widget.BothwayListView>
18 </LinearLayout>

(item:)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3             android:layout_width="match_parent"
 4             android:layout_height="50dp"
 5             android:gravity="center"
 6             android:orientation="horizontal" >
 7           <!--这个TextView就是每一个Item的左侧不会左右滑动的部分.-->
 8             <TextView
 9                 android:layout_width="100dp"
10                 android:layout_height="match_parent"
11                 android:gravity="center"
12                 android:text="LEFT_SIDE" />
13           <!--以下是Item中可以左右滑动的部分,外层的InterceptLinearLayout是用来
14           屏蔽滑动事件的,即下面的HorizontalScrollView不会自动的跟随用户的滑动事件
15           滚动,他们的滚动都是由代码中手工移动的.-->
16             <com.group_06.bothwaylistviewapi.widget.InterceptLinearLayout
17                 android:id="@+id/top_linearlayout"
18                 android:layout_width="wrap_content"
19                 android:layout_height="match_parent" >
20               <!--这是HorizontalScrollView,左右滚动全靠它.-->
21                 <com.group_06.bothwaylistviewapi.widget.HeaderHorizontalScrollView
22                     android:id="@+id/my_scrollview"
23                     android:layout_width="wrap_content"
24                     android:layout_height="match_parent"
25                     android:scrollbars="none" >
26                         <LinearLayout
27                             android:layout_width="wrap_content"
28                             android:layout_height="match_parent"
29                             android:orientation="horizontal" >
30                                 <TextView
31                                     android:layout_width="50dp"
32                                     android:layout_height="match_parent"
33                                     android:text="AAAA" />
34                                 <TextView
35                                     android:layout_width="50dp"
36                                    android:layout_height="match_parent"
37                                     android:text="BBBB" />
38 
39                    .. .. .. .. .. .. .. ..
40                 
41                                 <TextView
42                                     android:layout_width="50dp"
43                                     android:layout_height="match_parent"
44                                     android:text="HHHH" />
45                         </LinearLayout>
46                 </com.group_06.bothwaylistviewapi.widget.HeaderHorizontalScrollView>
47             </com.group_06.bothwaylistviewapi.widget.InterceptLinearLayout>
48 </LinearLayout>
  • Java代码:
 1 public class MainActivity extends Activity
 2 {
 3             private View mTopParentLinearLayout;
 4             private HeaderHorizontalScrollView mTopScrollView;
 5             private BothwayListView mBothwayListView;
 6             private BothwayListViewAdapter mBothwayListViewAdapter;
 7 
 8             @Override
 9             public void onCreate(Bundle savedInstanceState)
10             {
11                 super.onCreate(savedInstanceState);
12                 setContentView(R.layout.activity_main);
13                 initViews();
14             }
15             private void initViews()
16             {
17                 mTopParentLinearLayout = (View) findViewById(R.id.top_header);
18                 mTopScrollView = (HeaderHorizontalScrollView) mTopParentLinearLayout
19                         .findViewById(R.id.my_scrollview);
20                 mBothwayListView = (BothwayListView) findViewById(R.id.main_listview);
21                 mBothwayListView.initListView(mTopParentLinearLayout, mTopScrollView);
22                 mBothwayListViewAdapter = new MyAdapter(MainActivity.this,
23                         mTopScrollView);
24                 mBothwayListView.setAdapter(mBothwayListViewAdapter);
25             }
26             @Override
27             protected void onDestroy()
28             {
29                 if (null != mBothwayListView)
30                 {
31                     mBothwayListView.unRegisterReceiver();
32                 }
33                 super.onDestroy();
34             }
35 }
  • HorizontalScrollView的Adapter:

Adapter中只有这个方法不同,即需要多返回一个ScrollView,即每一个Item中的HorizontalScrollView.若ConvertView不为空时,即重用之前的Item时,可以将Item的ScrollView设为null传回.

 1 @Override
 2 public ConvertViewAndScrollView getFullView(int position, View convertView,
 3                     ViewGroup parent)
 4 {
 5   if (convertView == null)
 6   {
 7     convertView = inflater.inflate(R.layout.item, null, false);
 8     ......
 9     HorizontalScrollView scrollView = (HorizontalScrollView) convertView
10     .findViewById(R.id.my_scrollview);
11     return new ConvertViewAndScrollView(convertView, scrollView);
12   }
13   ......
14     return new ConvertViewAndScrollView(convertView, null);
15 }

 

代码下载:https://files.cnblogs.com/group-06/BothwayListViewAPI.zip

posted @ 2013-01-06 01:51  Xiao.Yang  阅读(1693)  评论(9编辑  收藏  举报