Android开源项目QuickReturnHeader分析
扫描二维码
随时随地手机看文章
最近项目开发,碰到一个ListView的需求。
向上滑动,隐藏Header。向下滑动,迅速显示Header。
在GitHub中,找到了QuickReturnHeader项目,虽然最终因为我们的特殊需求,没有采用这个开源项目,但觉得这个项目不错,就对其进行了分析。
项目的使用方式很简单,下载master工程下来,将library目录倒入到eclipse中(我用的eclipse),其他项目使用的使用,作为library引用即可。
使用方式如下:
这是本项目中的给出的例子:
在要使用的的Activity中onCreate方法中
?
| 1 2 3 | QuickReturnHeaderHelper helper = newQuickReturnHeaderHelper(this, R.layout.activity_listview, R.layout.header);View view = helper.createView();setContentView(view); | 
R.layout.activity_listview 就是我们的ListView布局,代码如下,
项目中使用了系统默认的ListView的id:@android:id/list。并且在QuickReturnHeader源码中,固定的使用了这个id。这应该是项目需要改进的地方。
?
| 1 2 | <listview android:id="@android:id/list"android:layout_height="match_parent"android:layout_width="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"></listview> | 
R.layout.header 就是我们的header布局文件,下面是例子中的布局文件
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <framelayout android:background="@color/abs__background_holo_light"android:layout_height="@dimen/abs__action_bar_default_height"android:layout_width="match_parent"    <linearlayout android:id="@+id/frame"android:layout_gravity="center"android:layout_height="match_parent"android:layout_width="match_parent"android:orientation="horizontal">        <imagebutton android:layout_height="wrap_content"android:layout_weight="1"android:layout_width="0dp"android:src="@drawable/ic_navigation_accept"style="@style/actionBarButton">        <imagebutton android:layout_height="wrap_content"android:layout_weight="1"android:layout_width="0dp"android:src="@drawable/ic_navigation_cancel"style="@style/actionBarButton">        <imagebutton android:layout_height="wrap_content"android:layout_weight="1"android:layout_width="0dp"android:src="@drawable/ic_navigation_refresh"style="@style/actionBarButton">        <imagebutton android:layout_height="wrap_content"android:layout_weight="1"android:layout_width="0dp"android:src="@drawable/ic_action_help"style="@style/actionBarButton">    </imagebutton></imagebutton></imagebutton></imagebutton></linearlayout>    <view android:background="#3333"android:layout_gravity="bottom"android:layout_height="1dp"android:layout_width="match_parent"></view></framelayout> | 
以上就是,这个开源项目的使用,很简单。下面就实现的的原理,进行分析。
简单总结就是一句话,QuickRetrunHeaderHelper,将我们的ListView布局和Header布局,放在了一个FrameLayout中。同时为ListView提供一个Header布局同样高度的空白的ListViewHeader。
用一张图来说明
下面是开源库中的关键代码:
构造函数:
?
| 1 2 3 4 5 | publicQuickReturnHeaderHelper(Context context, intcontentResId, intheaderResId) {        this.context = context;        this.contentResId = contentResId;        this.headerResId = headerResId;    } | 
createView方法:
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | publicView createView() {        inflater = LayoutInflater.from(context);        content = inflater.inflate(contentResId, null);        realHeader = inflater.inflate(headerResId, null);        realHeaderLayoutParams = newFrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,  LayoutParams.WRAP_CONTENT);        realHeaderLayoutParams.gravity = Gravity.TOP;        // Use measured height here as an estimate of the header height,  later on after the layout is complete         // we‘ll use the actual height        intwidthMeasureSpec =  MeasureSpec.makeMeasureSpec(LayoutParams.MATCH_PARENT,  MeasureSpec.EXACTLY);        intheightMeasureSpec =  MeasureSpec.makeMeasureSpec(LayoutParams.WRAP_CONTENT,  MeasureSpec.EXACTLY);        realHeader.measure(widthMeasureSpec, heightMeasureSpec);        headerHeight = realHeader.getMeasuredHeight();        listView = (ListView)  content.findViewById(android.R.id.list);        if(listView != null) {            createListView();        } else{            createScrollView();        }        returnroot;    } | 
createListView方法(此开源库同样适用于ScrollView,通过createScrollView创建,代码类似):
?
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | privatevoidcreateListView() {        root = (FrameLayout) inflater.inflate(R.layout.qrh__listview_container,  null);        root.addView(content);        listView.getViewTreeObserver().addOnGlobalLayoutListener(this);        ListViewScrollObserver observer = newListViewScrollObserver(listView);        //        listView.setOnScrollListener(this);        observer.setOnScrollUpAndDownListener(newOnListViewScrollListener() {            @Override            publicvoidonScrollUpDownChanged(intdelta, intscrollPosition, booleanexact) {                onNewScroll(delta);                snap(headerTop == scrollPosition);            }            @Override            publicvoidonScrollIdle() {                QuickReturnHeaderHelper.this.onScrollIdle();            }        });        root.addView(realHeader, realHeaderLayoutParams);        dummyHeader = newView(context);        AbsListView.LayoutParams params = newAbsListView.LayoutParams(LayoutParams.MATCH_PARENT,  headerHeight);        dummyHeader.setLayoutParams(params);        listView.addHeaderView(dummyHeader);    } | 
添加好布局以后,监听ListView的onScroll,向上滑动就逐渐隐藏我们自定义的Header,向下滑动就将Header显示出来。
以上就是全部分析了,大家看了源码,估计很快就能明白。
我认为项目可能还有很多改进的地方,也不一定适合大家的需求,(好多时候我们自定义的ListView,已经使用了ListView的HeadView,这样再增加空白HeadView就不合适了)
但项目提供了一种可以借鉴的思路,相信再很多时候还是很有用的。

 
						
			 
			 下载文档
下载文档



 
		 