臨近年終了,來了新需求,博主無奈啊,花了點時間搞出了下圖效果
思路分析
上圖效果大致分爲兩部分組成:橫向ScrollView+ListView.由於本人對於開源項目瞭解比較多,滑動懸停效果的PinnedSectionListView(任玉剛)有這個開源庫可以實現,可以down 下來加以修改源碼。scrollview部分只能自己寫了,自定義一個容器inflater下面佈局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<HorizontalScrollView
android:id="@+id/chainTabView"
android:layout_width="match_parent"
android:scrollbars="none"
android:fadingEdge="none"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/tabParent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>
<idea.analyzesystem.hover.pinnedsection.PinnedSectionListView
android:id="@+id/pinnedSectionListView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:cacheColorHint="#00000000"
android:scrollbars="none" />
</LinearLayout>
構造函數初始化控件,在使用時候通過一個方法傳入參數,讓PinnedSectionListView綁定adapter,這裏adapter使用到洪洋的BaseAdapter庫ViewHolder。大致業務邏輯如下
- 添加Tab
- 移除點擊以後的tab
- 刷新Tab
- 滑動到ScrollView底部
- ListView滑動到頂部
- PinnedSectionListView源碼改造
- Adapter適配器改造
- 數據源包裝
首先根據以前玩過PinnedSectionListView的經驗,修改源碼如下
void createPinnedShadow(int position) {
//layoutParams = (LayoutParams) generateDefaultLayoutParams();
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
pinnedView.setLayoutParams(layoutParams);
}
接着改造Adapter(其他方法大致相同)
@Override
public View getView(int position, View converView, ViewGroup viewGrop) {
ViewHolder viewHolder = null ;
if (converView == null)
{
View itemView = LayoutInflater.from(context).inflate(setLayoutRes(), viewGrop,false);
viewHolder = new ViewHolder(context, itemView, viewGrop, position);
viewHolder.mLayoutId = setLayoutRes();
} else {
viewHolder = (ViewHolder) converView.getTag();
viewHolder.mPosition = position;
}
T itemBean = getItem(position);
if (itemBean.getType()== T.SECTION) {
convertSection(viewHolder, getItem(position), position);
}else{
convertItem(viewHolder, getItem(position), position);
}
return viewHolder.getConvertView();
}
protected abstract void convertSection(ViewHolder viewHolder, T item, int position);
protected abstract void convertItem(ViewHolder viewHolder, T item, int position);
經過簡單改造後測試滑動懸停基本搞定,剩下的就是與ScrollView的聯動。在PinnedSectionListView setAdapter同時需要添加第一個tab,此處我們需要一個數據集合用於存放。當我們點擊了Item 不同類型有不同響應,如果是組類型需要請求網絡數據,返回後ScrollView的LinearLayout動態添加tab。而點擊了每個Tab需要刷新ListView以及刷新Tab的UI,並調整Tab和ListView的位置。
listView滑動到頂部只需要設置setSection(0),而ScrollView 這裏有個小知識點,ScrollView自帶fullScroll方法,調用時最好延時操作(可能你add 、remove childView還沒結束)
private void compileScroll() {
postDelayed(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(ScrollView.FOCUS_RIGHT);
}
}, 100);
}
至於其他的方法都比較簡單了,這裏不逼逼叨叨了,源碼和調用實例都比較簡單,喜歡的朋友可以看看。
代碼託管地址: