編輯:關於Android編程
最近項目開發,碰到一個ListView的需求。
向上滑動,隱藏Header。向下滑動,迅速顯示Header。
在GitHub中,找到了QuickReturnHeader項目,雖然最終因為我們的特殊需求,沒有采用這個開源項目,但覺得這個項目不錯,就對其進行了分析。
項目的使用方式很簡單,下載master工程下來,將library目錄倒入到eclipse中(我用的eclipse),其他項目使用的使用,作為library引用即可。
使用方式如下:
這是本項目中的給出的例子:

在要使用的的Activity中onCreate方法中
QuickReturnHeaderHelper helper = new QuickReturnHeaderHelper(this, R.layout.activity_listview, R.layout.header); View view = helper.createView(); setContentView(view);
項目中使用了系統默認的ListView的id:@android:id/list。並且在QuickReturnHeader源碼中,固定的使用了這個id。這應該是項目需要改進的地方。
<framelayout android:background="@color/abs__background_holo_light" android:layout_height="@dimen/abs__action_bar_default_height" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android">
</framelayout>
以上就是,這個開源項目的使用,很簡單。下面就實現的的原理,進行分析。
簡單總結就是一句話,QuickRetrunHeaderHelper,將我們的ListView布局和Header布局,放在了一個FrameLayout中。同時為ListView提供一個Header布局同樣高度的空白的ListViewHeader。
用一張圖來說明

下面是開源庫中的關鍵代碼:
構造函數:
public QuickReturnHeaderHelper(Context context, int contentResId, int headerResId) {
this.context = context;
this.contentResId = contentResId;
this.headerResId = headerResId;
}
public View createView() {
inflater = LayoutInflater.from(context);
content = inflater.inflate(contentResId, null);
realHeader = inflater.inflate(headerResId, null);
realHeaderLayoutParams = new FrameLayout.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
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(LayoutParams.MATCH_PARENT, MeasureSpec.EXACTLY);
int heightMeasureSpec = 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();
}
return root;
}
private void createListView() {
root = (FrameLayout) inflater.inflate(R.layout.qrh__listview_container, null);
root.addView(content);
listView.getViewTreeObserver().addOnGlobalLayoutListener(this);
ListViewScrollObserver observer = new ListViewScrollObserver(listView);
// listView.setOnScrollListener(this);
observer.setOnScrollUpAndDownListener(new OnListViewScrollListener() {
@Override
public void onScrollUpDownChanged(int delta, int scrollPosition, boolean exact) {
onNewScroll(delta);
snap(headerTop == scrollPosition);
}
@Override
public void onScrollIdle() {
QuickReturnHeaderHelper.this.onScrollIdle();
}
});
root.addView(realHeader, realHeaderLayoutParams);
dummyHeader = new View(context);
AbsListView.LayoutParams params = new AbsListView.LayoutParams(LayoutParams.MATCH_PARENT, headerHeight);
dummyHeader.setLayoutParams(params);
listView.addHeaderView(dummyHeader);
}
添加好布局以後,監聽ListView的onScroll,向上滑動就逐漸隱藏我們自定義的Header,向下滑動就將Header顯示出來。
以上就是全部分析了,大家看了源碼,估計很快就能明白。
我認為項目可能還有很多改進的地方,也不一定適合大家的需求,(好多時候我們自定義的ListView,已經使用了ListView的HeadView,這樣再增加空白HeadView就不合適了)
但項目提供了一種可以借鑒的思路,相信再很多時候還是很有用的。
如何搭配最新的安卓開發環境
本章只是寫了如何配置JDK,以及adt-bundle的配置。對於以前的adt-bundle的版本,會自帶CPU/ABI系統鏡像,經過本文所描述的兩個步驟後可以直接創建AV
Android仿支付寶、京東的密碼鍵盤和輸入框
首先看下效果圖一:布局代碼鍵盤由0~9的數字,刪除鍵和完成鍵組成,也可以根據需求通過GridView適配器的getItemViewType方法來定義。點擊鍵的時候背景有變
Android編程重寫ViewGroup實現卡片布局的方法
本文實例講述了Android編程重寫ViewGroup實現卡片布局的方法。分享給大家供大家參考,具體如下:實現效果如圖:實現思路1. 重寫onMeasure(int wi
UI--Android中的狀態切換按鈕自定義
1.概述 Android中關於控制開關和頁面/狀態切換的使用場景還是比較多的。源生做的支持也有比如RadioGroup 和Tabhost等。這裡准備通過自定
【Android 仿微信通訊錄 導航分組列表-上】使用ItemDecoration為RecyclerView打造帶懸停頭部的分組列表
一 概述本文是Android導航分組列表系列上,因時間和篇幅原因分上下,