編輯:關於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
首先看下效果圖一:布局代碼鍵盤由0~9的數字,刪除鍵和完成鍵組成,也可以根據需求通過GridView適配器的getItemViewType方法來定義。點擊鍵的時候背景有變
本文實例講述了Android編程重寫ViewGroup實現卡片布局的方法。分享給大家供大家參考,具體如下:實現效果如圖:實現思路1. 重寫onMeasure(int wi
1.概述 Android中關於控制開關和頁面/狀態切換的使用場景還是比較多的。源生做的支持也有比如RadioGroup 和Tabhost等。這裡准備通過自定
一 概述本文是Android導航分組列表系列上,因時間和篇幅原因分上下,