1. 程式人生 > >RadioGroup--RadioButton結合Viewpager實現頁面滑動

RadioGroup--RadioButton結合Viewpager實現頁面滑動

 

先上圖:

 

首先是Activity佈局

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center"
        android:layout_margin="@dimen/dp_16"
        android:background="@drawable/shape_director_total_earning_bg"
        android:gravity="center">

        <TextView
            android:id="@+id/tv_total_money_desc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="累計收益"
            android:textColor="@color/white"
            android:textSize="@dimen/dimen_12sp" />

        <TextView
            android:id="@+id/tv_total_money"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/tv_total_money_desc"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="@dimen/dp_5"
            android:text="0元"
            android:textColor="@color/white"
            android:textSize="@dimen/dimen_24sp" />

    </RelativeLayout>

    <View style="@style/Line.Horizontal" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_margin="@dimen/dp_10"
        android:text="收益明細"
        android:textColor="@color/tc_gray_3"
        android:textSize="@dimen/sp_18" />

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="@dimen/titleHeight"
        android:background="@color/app_bg_gray"
        android:orientation="horizontal">

        <RadioButton
            android:id="@+id/radio_one"
            android:layout_width="@dimen/dimen_0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/shape_director_time_radio"
            android:button="@null"
            android:checked="true"
            android:gravity="center"
            android:text="近一月"
            android:textColor="@drawable/shape_director_time_text_radio" />

        <!--<View-->
            <!--android:layout_width="@dimen/dp_0.5"-->
            <!--android:layout_height="@dimen/dimen_30dp"-->
            <!--android:layout_gravity="center_vertical"-->
            <!--android:background="@color/dividerColor" />-->

        <RadioButton
            android:id="@+id/radio_three"
            android:layout_width="@dimen/dimen_0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/shape_director_time_radio"
            android:button="@null"
            android:gravity="center"
            android:text="近三月"
            android:textColor="@drawable/shape_director_time_text_radio" />

        <!--<View-->
            <!--android:layout_width="@dimen/dp_0.5"-->
            <!--android:layout_height="@dimen/dimen_30dp"-->
            <!--android:layout_gravity="center_vertical"-->
            <!--android:background="@color/dividerColor" />-->

        <RadioButton
            android:id="@+id/radio_custom"
            android:layout_width="@dimen/dimen_0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/shape_director_time_radio"
            android:button="@null"
            android:gravity="center"
            android:text="自定義"
            android:textColor="@drawable/shape_director_time_text_radio" />
    </RadioGroup>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>
 

然後是Activity:

package com.dyh.drivingschool.ui.director;

import android.os.Bundle;
import android.support.annotation.IdRes;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;

import com.dyh.drivingschool.R;
import com.dyh.drivingschool.ui.director.fragment.ProfitCustomFragment;
import com.dyh.drivingschool.ui.director.fragment.ProfitFixedFragment;
import com.dyh.library.base.TitleFragmentActivity;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

import static com.dyh.drivingschool.R.id.radio_one;

/**
 * 累計收益
 */

public class ProfitTotalActivity extends TitleFragmentActivity {

    @BindView(R.id.tv_total_money)
    TextView tvTotalMoney;
    @BindView(R.id.radioGroup)
    RadioGroup radioGroup;
    @BindView(R.id.viewpager)
    ViewPager viewpager;

    @BindView(R.id.radio_one)
    RadioButton mRadio_one;

    @BindView(R.id.radio_three)
    RadioButton mRadio_three;

    @BindView(R.id.radio_custom)
    RadioButton mRadio_custom;


    private List<Fragment> fragmentList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addLayout(R.layout.activity_profit_total);
        ButterKnife.bind(this);

        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, @IdRes int checkedId) {
                switch (checkedId) {
                    case radio_one:
                        viewpager.setCurrentItem(0);

                        break;
                    case R.id.radio_three:
                        viewpager.setCurrentItem(1);

                        break;
                    case R.id.radio_custom:
                        viewpager.setCurrentItem(2);

                        break;
                }
            }
        });

        fragmentList.add(ProfitFixedFragment.newInstance("1"));
        fragmentList.add(ProfitFixedFragment.newInstance("2"));
        fragmentList.add(new ProfitCustomFragment());
        viewpager.setAdapter(new FragmentStatePagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return fragmentList.get(position);
            }

            @Override
            public int getCount() {
                return fragmentList.size();
            }
        });
        viewpager.setOffscreenPageLimit(2);
        viewpager.setCurrentItem(0);

        viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

                if (position == 0){
                    mRadio_one.setChecked(true);
                }else if (position == 1){
                    mRadio_three.setChecked(true);
                }else if (position == 2){
                    mRadio_custom.setChecked(true);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        /**
         * 為 RadioGroup 設定選中變化事件監聽,當 RadioButton 狀態變化,我們同步 Viewpager 的選中頁面
         **/
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == mRadio_one.getId()) viewpager.setCurrentItem(0);
                else if (checkedId == mRadio_three.getId()) viewpager.setCurrentItem(1);
                else if (checkedId == mRadio_custom.getId()) viewpager.setCurrentItem(2);

            }
        });

        //設定預設選中頁

    }


    @Override
    protected void initTitileBar() {
        titleLayout.showCenterLeftIconView("累計收益");
    }


}

 

然後是其中的fragment:

package com.dyh.drivingschool.ui.director.fragment;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ExpandableListView;

import com.dyh.drivingschool.R;
import com.dyh.drivingschool.ui.director.adapter.ProfitMonthAdapter;
import com.dyh.drivingschool.uinew.earnmoney.bean.ArticleChildBean;
import com.dyh.frame.BaseFragment;
import com.dyh.frame.widget.PinnedHeaderExpandableListView;
import com.dyh.library.base.PageHelperNew;
import com.dyh.library.widget.NoDataView;
import com.scwang.smartrefresh.layout.SmartRefreshLayout;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
* 收益列表
*/

public class ProfitFixedFragment extends BaseFragment {

    private static final String FIXED_TIME = "fixed_time";

    @BindView(R.id.expandable_listview)
    PinnedHeaderExpandableListView expandableListview;
    @BindView(R.id.refreshLayout)
    SmartRefreshLayout refreshLayout;
    @BindView(R.id.no_date_layout)
    NoDataView noDateLayout;

    private Unbinder unbinder;

    private String key;

    private PageHelperNew pageHelper;
    private ProfitMonthAdapter adapter;
    private List<Integer> groupList = new ArrayList<>();
    private List<List<ArticleChildBean.ArticleChildJson>> childList = new ArrayList<>();

    public static ProfitFixedFragment newInstance(String key) {
        ProfitFixedFragment fragment = new ProfitFixedFragment();
        Bundle bundle = new Bundle();
        bundle.putString(FIXED_TIME, key);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        rootView = inflater.inflate(R.layout.fragment_profit_fixed, container, false);
        unbinder = ButterKnife.bind(this, rootView);

        pageHelper = pageHelper.getNewInstance();
        pageHelper.setPageSize(10);
        refreshLayout.setEnableRefresh(false);
        refreshLayout.setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore(@NonNull RefreshLayout layout) {
                if (pageHelper.pullUp(refreshLayout)) {

                }
            }
        });

        expandableListview.setHeaderView(mContext.getLayoutInflater().inflate(R.layout.item_earning_detail_group, null));
        adapter = new ProfitMonthAdapter(mContext, null, null, expandableListview);
        expandableListview.setAdapter(adapter);
        expandableListview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
                return false;
            }
        });
        expandableListview.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
                return true;
            }
        });

        if (getArguments() != null) {
            key = getArguments().getString(FIXED_TIME);
        }
        reqData();

        return rootView;
    }

    private void reqData() {
        for (int i = 0; i < 3; i++) {
            groupList.add(i);
            List<ArticleChildBean.ArticleChildJson> list = new ArrayList<>();
            for (int j = 0; j < 2; j++) {
                ArticleChildBean.ArticleChildJson json = new ArticleChildBean.ArticleChildJson();
                list.add(json);
            }
            childList.add(list);
        }
        adapter.setGroupList(groupList);
        adapter.setChildList(childList);
        adapter.notifyDataSetChanged();

        for (int i = 0; i < adapter.getGroupList().size(); i++) {
            expandableListview.expandGroup(i);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        unbinder.unbind();
    }
}



fragment佈局:

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.scwang.smartrefresh.layout.SmartRefreshLayout
        android:id="@+id/refreshLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="visible">

        <com.dyh.frame.widget.PinnedHeaderExpandableListView
            android:id="@+id/expandable_listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:childDivider="@color/dividerColor"
            android:divider="@color/dividerColor"
            android:dividerHeight="@dimen/dp_0.5" />
    </com.scwang.smartrefresh.layout.SmartRefreshLayout>

    <com.dyh.library.widget.NoDataView
        android:id="@+id/no_date_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
</RelativeLayout>

 

這是fragment介面卡:

package com.dyh.drivingschool.ui.director.adapter;

import android.content.Context;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.dyh.common.utils.DisplayOption;
import com.dyh.drivingschool.R;
import com.dyh.drivingschool.uinew.earnmoney.bean.ArticleChildBean;
import com.dyh.drivingschool.uinew.earnmoney.bean.ArticleGroupBean;
import com.dyh.frame.util.ListUtil;
import com.dyh.frame.widget.PinnedHeaderExpandableListView;
import com.nostra13.universalimageloader.core.ImageLoader;

import java.util.List;

/**
 * 月份列表介面卡
 */

public class ProfitMonthAdapter extends BaseExpandableListAdapter implements PinnedHeaderExpandableListView.HeaderAdapter {


    private PinnedHeaderExpandableListView listView;
    private LayoutInflater mInflater;
    private List<ArticleGroupBean.ArticleGroupJson> configList;
    private List<Integer> groupList;
    private List<List<ArticleChildBean.ArticleChildJson>> childList;


    public ProfitMonthAdapter(Context mContext, List<Integer> groupList, List<List<ArticleChildBean.ArticleChildJson>> childList, PinnedHeaderExpandableListView listView) {
        this.listView = listView;
        this.groupList = groupList;
        this.childList = childList;
        this.mInflater = LayoutInflater.from(mContext);

    }

    @Override
    public int getGroupCount() {
        return ListUtil.isNullOrEmpty(groupList) ? 0 : groupList.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return ListUtil.isNullOrEmpty(childList) ? 0 : childList.get(groupPosition).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return groupList.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return childList.get(groupPosition).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.item_earning_detail_group, parent, false);
        }

        return convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        ArticleChildBean.ArticleChildJson dataItem = (ArticleChildBean.ArticleChildJson) getChild(groupPosition, childPosition);

        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.item_earning_detail_child, parent, false);
        }


        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    @Override
    public int getHeaderState(int groupPosition, int childPosition) {
        final int childCount = getChildrenCount(groupPosition);
        if (childPosition == childCount - 1) {
            return PINNED_HEADER_PUSHED_UP;
        } else if (childPosition == -1 && !listView.isGroupExpanded(groupPosition)) {
            return PINNED_HEADER_GONE;
        } else {
            return PINNED_HEADER_VISIBLE;
        }
    }

    @Override
    public void configureHeader(View header, int groupPosition, int childPosition, int alpha) {
        Integer id = (Integer) getGroup(groupPosition);
        if (!ListUtil.isNullOrEmpty(configList)) {
            for (int i = 0; i < configList.size(); i++) {
                ArticleGroupBean.ArticleGroupJson dataItem = configList.get(i);
                if (dataItem.getCfgId() == id) {
                    View view = header.findViewById(R.id.v_shadow);
                    ImageView complete = header.findViewById(R.id.iv_complete);
                    ImageView icon = header.findViewById(R.id.iv_config_icon);
                    TextView money = header.findViewById(R.id.tv_config_money);
                    TextView desc = header.findViewById(R.id.tv_config_desc);
                    ImageLoader.getInstance().displayImage(dataItem.getIconUrl(), icon, DisplayOption.getRoundedOptions());
                    money.setText(dataItem.getShareNum() + "條/" + dataItem.getAllNum() + "條");
                    desc.setText(dataItem.getDescp());
                }
            }
        }
    }

    private SparseIntArray groupStatusMap = new SparseIntArray();

    @Override
    public void setGroupClickStatus(int groupPosition, int status) {
        groupStatusMap.put(groupPosition, status);
    }

    @Override
    public int getGroupClickStatus(int groupPosition) {
        if (groupStatusMap.keyAt(groupPosition) >= 0) {
            return groupStatusMap.get(groupPosition);
        } else {
            return 0;
        }
    }

    public List<Integer> getGroupList() {
        return groupList;
    }

    public void setGroupList(List<Integer> groupList) {
        this.groupList = groupList;
    }

    public List<List<ArticleChildBean.ArticleChildJson>> getChildList() {
        return childList;
    }

    public void setChildList(List<List<ArticleChildBean.ArticleChildJson>> childList) {
        this.childList = childList;
    }

    public void setConfigList(List<ArticleGroupBean.ArticleGroupJson> configList) {
        this.configList = configList;
    }
}

 

這是fragment其中的頭佈局介面卡:

 

package com.dyh.frame.widget;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.OnGroupClickListener;

public class PinnedHeaderExpandableListView extends ExpandableListView implements OnScrollListener, OnGroupClickListener {
   public PinnedHeaderExpandableListView(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      registerListener();
   }

   public PinnedHeaderExpandableListView(Context context, AttributeSet attrs) {
      super(context, attrs);
      registerListener();
   }

   public PinnedHeaderExpandableListView(Context context) {
      super(context);
      registerListener();
   }

   /**
    * Adapter 介面 . 列表必須實現此介面 .
    */
   public interface HeaderAdapter {
      int PINNED_HEADER_GONE = 0;
      int PINNED_HEADER_VISIBLE = 1;
      int PINNED_HEADER_PUSHED_UP = 2;

      /**
       * 獲取 Header 的狀態
       * 
       * @param groupPosition
       * @param childPosition
       * @return 
       *         PINNED_HEADER_GONE,PINNED_HEADER_VISIBLE,PINNED_HEADER_PUSHED_UP
       *         其中之一
       */
      int getHeaderState(int groupPosition, int childPosition);

      /**
       * 配置 Header, 讓 Header 知道顯示的內容
       * 
       * @param header
       * @param groupPosition
       * @param childPosition
       * @param alpha
       */
      void configureHeader(View header, int groupPosition, int childPosition, int alpha);

      /**
       * 設定組按下的狀態
       * 
       * @param groupPosition
       * @param status
       */
      void setGroupClickStatus(int groupPosition, int status);

      /**
       * 獲取組按下的狀態
       * 
       * @param groupPosition
       * @return
       */
      int getGroupClickStatus(int groupPosition);

   }

   private static final int MAX_ALPHA = 255;

   private HeaderAdapter mAdapter;

   /**
    * 用於在列表頭顯示的 View,mHeaderViewVisible 為 true 才可見
    */
   private View mHeaderView;

   /**
    * 列表頭是否可見
    */
   private boolean mHeaderViewVisible;

   private int mHeaderViewWidth;

   private int mHeaderViewHeight;

   public void setHeaderView(View view) {
      mHeaderView = view;
      AbsListView.LayoutParams lp = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
      view.setLayoutParams(lp);

      if (mHeaderView != null) {
         setFadingEdgeLength(0);
      }

      requestLayout();
   }

   private void registerListener() {
      setOnScrollListener(this);
      setOnGroupClickListener(this);
   }

   /**
    * 點選 HeaderView 觸發的事件
    */
   private void headerViewClick() {
      long packedPosition = getExpandableListPosition(this.getFirstVisiblePosition());

      int groupPosition = ExpandableListView.getPackedPositionGroup(packedPosition);

      if (mAdapter.getGroupClickStatus(groupPosition) == 1) {
         this.collapseGroup(groupPosition);
         mAdapter.setGroupClickStatus(groupPosition, 0);
      } else {
         this.expandGroup(groupPosition);
         mAdapter.setGroupClickStatus(groupPosition, 1);
      }

      this.setSelectedGroup(groupPosition);
   }

   private float mDownX;
   private float mDownY;

   /**
    * 如果 HeaderView 是可見的 , 此函式用於判斷是否點選了 HeaderView, 並對做相應的處理 , 因為 HeaderView
    * 是畫上去的 , 所以設定事件監聽是無效的 , 只有自行控制 .
    */
   @Override
   public boolean onTouchEvent(MotionEvent ev) {
      if (mHeaderViewVisible) {
         switch (ev.getAction()) {
         case MotionEvent.ACTION_DOWN:
            mDownX = ev.getX();
            mDownY = ev.getY();
            if (mDownX <= mHeaderViewWidth && mDownY <= mHeaderViewHeight) {
               return true;
            }
            break;
         case MotionEvent.ACTION_UP:
            float x = ev.getX();
            float y = ev.getY();
            float offsetX = Math.abs(x - mDownX);
            float offsetY = Math.abs(y - mDownY);
            // 如果 HeaderView 是可見的 , 點選在 HeaderView 內 , 那麼觸發 headerClick()
            if (x <= mHeaderViewWidth && y <= mHeaderViewHeight && offsetX <= mHeaderViewWidth && offsetY <= mHeaderViewHeight) {
               if (mHeaderView != null) {
//                headerViewClick();
               }

               return true;
            }
            break;
         default:
            break;
         }
      }

      return super.onTouchEvent(ev);

   }

   @Override
   public void setAdapter(ExpandableListAdapter adapter) {
      super.setAdapter(adapter);
      mAdapter = (HeaderAdapter) adapter;
   }

   /**
    * 
    * 點選了 Group 觸發的事件 , 要根據根據當前點選 Group 的狀態來
    */
   @Override
   public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
      if (mAdapter.getGroupClickStatus(groupPosition) == 0) {
         mAdapter.setGroupClickStatus(groupPosition, 1);
         parent.expandGroup(groupPosition);
         // Header自動置頂
         // parent.setSelectedGroup(groupPosition);

      } else if (mAdapter.getGroupClickStatus(groupPosition) == 1) {
         mAdapter.setGroupClickStatus(groupPosition, 0);
         parent.collapseGroup(groupPosition);
      }

      // 返回 true 才可以彈回第一行 , 不知道為什麼
      return true;
   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
      super.onMeasure(widthMeasureSpec, heightMeasureSpec);
      if (mHeaderView != null) {
         measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);
         mHeaderViewWidth = mHeaderView.getMeasuredWidth();
         mHeaderViewHeight = mHeaderView.getMeasuredHeight();
      }
   }

   private int mOldState = -1;

   @Override
   protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
      super.onLayout(changed, left, top, right, bottom);
      final long flatPostion = getExpandableListPosition(getFirstVisiblePosition());
      final int groupPos = ExpandableListView.getPackedPositionGroup(flatPostion);
      final int childPos = ExpandableListView.getPackedPositionChild(flatPostion);
      int state = mAdapter.getHeaderState(groupPos, childPos);
      if (mHeaderView != null && mAdapter != null && state != mOldState) {
         mOldState = state;
         mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
      }

      configureHeaderView(groupPos, childPos);
   }

   public void configureHeaderView(int groupPosition, int childPosition) {
      if (mHeaderView == null || mAdapter == null || ((ExpandableListAdapter) mAdapter).getGroupCount() == 0) {
         return;
      }

      int state = mAdapter.getHeaderState(groupPosition, childPosition);

      switch (state) {
      case HeaderAdapter.PINNED_HEADER_GONE: {
         mHeaderViewVisible = false;
         break;
      }

      case HeaderAdapter.PINNED_HEADER_VISIBLE: {
         mAdapter.configureHeader(mHeaderView, groupPosition, childPosition, MAX_ALPHA);

         if (mHeaderView.getTop() != 0) {
            mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);
         }

         mHeaderViewVisible = true;

         break;
      }

      case HeaderAdapter.PINNED_HEADER_PUSHED_UP: {
         View firstView = getChildAt(0);
         int bottom = firstView.getBottom();

         // intitemHeight = firstView.getHeight();
         int headerHeight = mHeaderView.getHeight();

         int y;

         int alpha;

         if (bottom < headerHeight) {
            y = (bottom - headerHeight);
            alpha = MAX_ALPHA * (headerHeight + y) / headerHeight;
         } else {
            y = 0;
            alpha = MAX_ALPHA;
         }

         mAdapter.configureHeader(mHeaderView, groupPosition, childPosition, alpha);

         if (mHeaderView.getTop() != y) {
            mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);
         }

         mHeaderViewVisible = true;
         break;
      }
      }
   }

   @Override
   /**
    * 列表介面更新時呼叫該方法(如滾動時)
    */
   protected void dispatchDraw(Canvas canvas) {
      super.dispatchDraw(canvas);
      if (mHeaderViewVisible) {
         // 分組欄是直接繪製到介面中,而不是加入到ViewGroup中
         drawChild(canvas, mHeaderView, getDrawingTime());
      }
   }

   @Override
   public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
      final long flatPos = getExpandableListPosition(firstVisibleItem);
      int groupPosition = ExpandableListView.getPackedPositionGroup(flatPos);
      int childPosition = ExpandableListView.getPackedPositionChild(flatPos);

      configureHeaderView(groupPosition, childPosition);
   }

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