天天看點

Android ExpandableListView的使用技巧

Android ExpandableListView的使用技巧

轉載請注明 作者:田野光 位址:http://blog.csdn.net/lovefish2/article/details/45920917

ExpandableListView是listview的官方擴充元件, 垂直方向上item分為兩層, group item和child item,點選group item可以展開和折疊child item.基礎的使用方法也非常簡單. 與之對應的是BaseExpandableListAdapter. 這是隻說一下一些常用需求的方法.

指定 預設展開的item

ExpandableListView vListView = (ExpandableListView) findViewById(R  .id.***);
vListView.expandGroup(); //預設展開第一項
           

隐藏分割線

android:childDivider="@null"
android:childIndicator="@null"
android:divider="@null"
android:groupIndicator="@null"
           

限制最多隻展開一項child item

vListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {

            int previousGroup = ;  //最初展開的item,若未指定,可設為-1

            @Override
            public void onGroupExpand(int groupPosition) {
                if (groupPosition != previousGroup)
                    vListView.collapseGroup(previousGroup);
                previousGroup = groupPosition;
            }
        });
           

與SwipeRefreshLayout搭配使用下拉重新整理

我們知道, SwipeRefreshLayout 會監聽滑動操作,并相應觸發下拉重新整理,如果布局檔案中内含了可滑動的控件,如ScrollView等,則很有可能會在錯誤的時候觸發下拉重新整理(譬如當你下拉頁面想要浏覽上方内容), 好消息是所有AbsListView 子類,包括listview, ExpandableListView 等控件,隻要是XML布局内部的直接下級,SwipeRefreshLayout都内置了判斷方法,可以避免錯誤的觸發.不過其他情況就需要單獨處理了.

<SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

      <ExpandableListView
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

</SwipeRefreshLayout>
           
  • 非直接下級的AbsListView

    參考(http://stackoverflow.com/questions/23341735/swiperefreshlayout-swipe-down-to-refresh-but-not-move-the-view-pull-down)

<SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

          <ExpandableListView
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    </LinearLayout>

</SwipeRefreshLayout>
           

解決辦法:

listView.setOnScrollListener(new OnScrollListener() {

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    boolean enable = false;
    if(listView != null && listView.getChildCount() > ){
        boolean firstItemVisible = listView.getFirstVisiblePosition() == ;
        boolean topOfFirstItemVisible = listView.getChildAt().getTop() == ;
        enable = firstItemVisible && topOfFirstItemVisible;
    }
    swipeRefreshLayout.setEnabled(enable);
}});
           
  • 和RecyclerView

    可以參考我的這篇部落格: Android開發 解決RecyclerView in SwipeRefreshLayout觸發下拉重新整理的bug

增加item擴充和折疊的動畫

ExpandableListView預設折疊和展開item簡單粗暴,通常情況下我們想要平滑一點,輕柔一點(别想歪了-_-), 我們看到API裡,官方有提供動畫的方案

public boolean expandGroup (int groupPos, boolean animate)

但缺點是動畫很粗糙,可以參見源碼的處理:

AnimatedExpandableListView vListView = (AnimatedExpandableListView) findViewById(R  .id.***);
public boolean expandGroup(int groupPos, boolean animate) {
        ExpandableListPosition elGroupPos = ExpandableListPosition.obtain(
                ExpandableListPosition.GROUP, groupPos, -, -);
        PositionMetadata pm = mConnector.getFlattenedPos(elGroupPos);
        elGroupPos.recycle();
        boolean retValue = mConnector.expandGroup(pm);

        if (mOnGroupExpandListener != null) {
            mOnGroupExpandListener.onGroupExpand(groupPos);
        }

        if (animate) {
            final int groupFlatPos = pm.position.flatListPos;

            final int shiftedGroupPosition = groupFlatPos + getHeaderViewsCount();
            //動畫僅僅是這樣
            smoothScrollToPosition(shiftedGroupPosition + mAdapter.getChildrenCount(groupPos),
                    shiftedGroupPosition);
        }
        pm.recycle();

        return retValue;
    }
           

而且API要求大于14.是以通常我們都是采用其他方式,這裡我推薦AnimatedExpandableListView,一個第三方寫的ExpandableListView類, 用法很簡單,繼承AnimatedExpandableListAdapter類,手動調用Animation方法

listView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {

            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                if (vBusInfo.isGroupExpanded(groupPosition)) {
                    vBusInfo.collapseGroupWithAnimation(groupPosition);
                } else {
                    vBusInfo.expandGroupWithAnimation(groupPosition);
                }
                return true;
            }

        });
           

好啦,關于ExpandableListView的介紹就先到這啦,歡迎大家提出批評建議,謝謝大家~