Idea-ChainSelector

臨近年終了,來了新需求,博主無奈啊,花了點時間搞出了下圖效果

思路分析

上圖效果大致分爲兩部分組成:橫向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。大致業務邏輯如下

  1. 添加Tab
  2. 移除點擊以後的tab
  3. 刷新Tab
  4. 滑動到ScrollView底部
  5. ListView滑動到頂部
  6. PinnedSectionListView源碼改造
  7. Adapter適配器改造
  8. 數據源包裝

首先根據以前玩過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);
    }

至於其他的方法都比較簡單了,這裏不逼逼叨叨了,源碼和調用實例都比較簡單,喜歡的朋友可以看看。

代碼託管地址:

https://github.com/lanyan520/Idea-ChainSelector

發佈了104 篇原創文章 · 獲贊 99 · 訪問量 34萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章