1. 程式人生 > >自定義ExpandableListView以及實現其分頁

自定義ExpandableListView以及實現其分頁

我在網上找了很久也沒看到類似百度貼吧評論以及再次評論的例項,但因為工作需要不得不寫,經過研究自己寫了一個例子供大家參考

自定義ExpandableListPageView實現分頁效果
public class ExpandableListPageView extends ExpandableListView implements
  OnScrollListener {
// private static String Tag = "ListPageView";
public Boolean canLoad = false; // 是否能夠載入資料
public int currentPageIndex = 0; // 記錄頁索引
public int pageSize = 0; // 每頁顯示專案數
public String loadMessage = "正在載入...."; // 進度條提示訊息
public LinearLayout footerLayout;// 頁尾
public OnPageLoadListener listener;// 分佈偵聽事件
public Context context;

public ExpandableListPageView(Context context) {
  super(context);
 
}

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

/**
  * 設定第頁顯示專案數
  *
  * @param pageSize
  *            第頁顯示專案數
  */
public void setPageSize(int pageSize) {
  this.pageSize = pageSize;
}

/**
  * 進度條顯示的訊息文字
  *
  * @param msg
  */
public void setLoadMessage(String msg) {
  this.loadMessage = msg;
}

/*
  * 設定資料來源
  *
  * @see android.widget.ListView#setAdapter(android.widget.ListAdapter)
  */
@Override
public void setAdapter(ExpandableListAdapter adapter) {
  this.setOnScrollListener(this);
  // 必須在setAdapter()方法之前構建進度條並新增到頁尾
  this.BuildProgressBar();
  super.setAdapter(adapter);
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
  if (this.canLoad && (scrollState == OnScrollListener.SCROLL_STATE_IDLE)) {
   // 載入資料
   if (listener != null) {
    this.currentPageIndex++;
    listener.onPageChanging(this.pageSize, currentPageIndex);
//  System.out.println("----####------this.pageSize-------"+this.pageSize);
//  System.out.println("----####------this.currentPageIndex-------"+currentPageIndex);
   }
  }
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
   int visibleItemCount, int totalItemCount) {

//  Log.i("####", "listener = " + listener + " firstVisibleItem = " +
//  firstVisibleItem + " visibleItemCount = "
//  + visibleItemCount + " totalItemCount = " + totalItemCount);
  this.canLoad = false;

  if (this.listener == null) {
   return;
  }
  if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
   this.canLoad = this.listener.canLoadData();
  }
// Log.i("####", "判斷canLoad = " + canLoad);
}

/**
  * 是否顯示進度條
  *
  * @param isVisible
  *            true:顯示,false:不顯示
  */

public void setProggressBarVisible(Boolean isVisible) {
  if (this.footerLayout == null) {
   return;
  }
  int visibility = View.VISIBLE;
  if (!isVisible) {
   visibility = View.GONE;
  }

  // 定位到最後一行,必須設定,要不然進度條看不到
  this.setSelection(this.getAdapter().getCount());

  this.footerLayout.setVisibility(visibility);

  // 設定頁尾中元件的顯示狀態
  for (int i = 0; i < this.footerLayout.getChildCount(); i++) {
   View v = this.footerLayout.getChildAt(i);
   v.setVisibility(visibility);
  }

}

/**
  * 建立頁尾顯示進度條,必須在setAdapter()方法之前呼叫.
  *
  * @return
  */
private void BuildProgressBar() {
  if (this.getFooterViewsCount() != 0) {
   return;
  }
  footerLayout = new LinearLayout(this.getContext());
  footerLayout.setGravity(Gravity.CENTER);
  footerLayout.setPadding(0, 0, 0, 0);
  footerLayout.setOrientation(LinearLayout.HORIZONTAL);
  ProgressBar bar = new ProgressBar(this.getContext());
  footerLayout.addView(bar);
  footerLayout.setBackgroundResource(R.color.white);
  TextView txt = new TextView(this.getContext());
  txt.setText(this.loadMessage);
  footerLayout.addView(txt);
  footerLayout.setVisibility(View.GONE);
  this.addFooterView(footerLayout);
}

/**
  * 設定頁載入偵聽事件
  *
  * @param listener
  */
public void setOnPageLoadListener(OnPageLoadListener listener) {
  this.listener = listener;
  }

public interface OnPageLoadListener {
  /**
   * 觸發分頁事件
   *
   * @param pageSize
   * @param pageIndex
   */
  public void onPageChanging(int pageSize, int pageIndex);

  /**
   * 是否能夠載入資料 此方法返回結果為true時觸發OnPageChanging事件,否則不做任何處理
   *
   * @return
   */
  public boolean canLoadData();
}

}


/***
*  例項類
*
*/
public class PostActivity extends Activity implements
  OnPageLoadListener, OnClickListener {
PostAdapter adapter;
private ExpandableListPageView listView;
int page = 1;

private int pageSize = 5;// 分頁每頁顯示資料
long messageSize = 0;
int lastItem = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main_liaoyiliaopost);

   into();
 
}

public void into() {
  listView = (ExpandableListPageView) this
    .findViewById(R.id.post_list_view);
  // 構建空的介面卡
  registerForContextMenu(listView);
  this.adapter = new PostAdapter(this);
  listView.setOnPageLoadListener(this);
  // 設定進度條提示訊息
  listView.setLoadMessage("load");
  listView.setAdapter(adapter);

  // 設定每次載入顯示數量
  listView.setPageSize(pageSize);
  // 設定監聽事件
 
  // 預設載入第1頁資料
  LoadBindData load = new LoadBindData(5, 0);
  load.execute();
}

@Override
public void onPageChanging(final int pageSize, final int pageIndex) {
  // 載入資料
  LoadBindData load = new LoadBindData(pageSize, pageIndex);
  load.execute();

}

@Override
public boolean canLoadData() {

  // return (this.adapter.getCount() >= 5) ? false : true;
  return (adapter.getGroupCount() >= messageSize) ? false : true;
}

/**
  * @author RUJC 非同步讀取資料
  */
public class LoadBindData extends AsyncTask<String, String, String> {
  private List<PostGroup> list;
  private int pageSize;
  private int pageIndex;

  /**
   * 建構函式
   *
   * @param pageSize
   *            每次載入的專案數
   * @param pageIndex
   *            頁索引
   */
  public LoadBindData(int pageSize, int pageIndex) {
   this.pageSize = pageSize;
   this.pageIndex = pageIndex;
   if (pageIndex == 0) {
    page = 1;
   } else {
    page++;
   }
  }

  @Override
  protected void onPreExecute() {
   // 在doInBackground執行之前觸發.
   // 顯示進度條
   listView.setProggressBarVisible(true);
   super.onPreExecute();
  }

  @Override
  protected void onPostExecute(String result) {
   // doInBackground執行完後觸發,result是doInBackground執行後的返回值.
   // 更新資料並關閉進度條顯示
   if (list != null) {
    adapter.add(list);
   
   }

   // 更新介面資料顯示
   adapter.notifyDataSetChanged();

   // 關閉進度條
   listView.setProggressBarVisible(false);
   super.onPostExecute(result);
  
  }

  @Override
  protected String doInBackground(String... params) {

   // 讀取資料
   list = getData(pageSize, pageIndex);

   return null;
  }
}

/**
  * 資料來源
  *
  * @param pageSize
  *            每次載入顯示的專案數
  * @param pageIndex
  *            頁索引
  * @return
  */
private List<PostGroup> getData(int pageSize, int pageIndex) {
  List<PostInfo> childList = null;
  List<PostGroup> groupList = null;
  PostInfo childInfo;
  PostGroup groupInfo;

  try { 
                            groupList = new ArrayList<PostGroup>();  
  
    for (int i = 0; i < nArray.length(); i++) {//nArray是獲取網路資料的一個List集合
     JSONObject myObj = nArray.getJSONObject(i);
     String userAlias = "userAlias "
   
     String username = "username";
    
     childList = new ArrayList<Info>();
     groupInfo = new PostInfo ();   
     groupInfo.setUserAlias(userAlias);
     groupInfo.setUname(username);
   

     JSONArray childs = myObj.getJSONArray("childs");

     for (int j = 0; j < childs.length(); j++) {
    
      childInfo = new PostInfo();
     
      String userAliass = childsObj.getString("userAlias");
     
      String usernames = childsObj.getString("username");   
      childInfo.setUserAlias(userAliass);
     
      childList.add(childInfo);
      childInfo = null;
     }

     groupInfo.setPostInfo(childList);
     groupList.add(groupInfo);
     groupInfo = null;
    }

  } catch (Exception e) {
   // TODO: handle exception
  }

  return groupList;

}

}


介面卡
public class PostAdapter extends BaseExpandableListAdapter {
private LayoutInflater mChildInflater;
Context context;

private List<PostGroup> groupList = new ArrayList<PostGroup>();

public LiaoYiLiaoPostAdapter(Context context) {
  mChildInflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
}

public void add(List<PostGroup> messages) {
  groupList.addAll(messages);
}

@Override
public int getGroupCount() {
  return groupList.size();
}

@Override
public int getChildrenCount(int groupPosition) {
  int s = 0;
  if (null != groupList.get(groupPosition).getPostInfo()) {
   s = groupList.get(groupPosition).getPostInfo().size();
  } else {
   s = 0;
  }
  return s;
}

@Override
public LiaoYiLiaoPostGroup getGroup(int groupPosition) {

  return groupList.get(groupPosition);
}

@Override
public PostInfo getChild(int groupPosition, int childPosition) {

  return groupList.get(groupPosition).getPostInfo()
    .get(childPosition);
}

@Override
public long getGroupId(int groupPosition) {
  // TODO Auto-generated method stub
  return groupPosition;
}

@Override
public long getChildId(int groupPosition, int childPosition) {
  // TODO Auto-generated method stub
  return childPosition;
}

@Override
public boolean hasStableIds() {
  // TODO Auto-generated method stub
  return false;
}

/**
  * 設定父組樣式
  *
  * **/
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
   View convertView, ViewGroup parent) {
  FriendHolder holder;
  if (convertView == null) {
   holder = new FriendHolder();

   convertView = mChildInflater
     .inflate(R.layout.list_post_group, null);
   holder.userheadimg = (ImageView) convertView
     .findViewById(R.id.userheadimg);
   holder.but_post = (ImageView) convertView
     .findViewById(R.id.but_post);
   holder.username = (TextView) convertView
     .findViewById(R.id.username);

   holder.time = (TextView) convertView.findViewById(R.id.time);
   holder.floor = (TextView) convertView.findViewById(R.id.floor);
   holder.info = (TextView) convertView.findViewById(R.id.info);
   convertView.setTag(holder);
  } else {
   holder = (FriendHolder) convertView.getTag();
  }
  String headimg = "http://www.homefoot.com"
    + groupList.get(groupPosition).getUsrImg();// 頭像
  String name = groupList.get(groupPosition).getUserAlias();// 暱稱
  String times = groupList.get(groupPosition).getDate();
  CharSequence content = groupList.get(groupPosition).getInfoSequence();
  holder.info.setText(content);
  holder.time.setText(times);
  holder.username.setText(name);
  int floor = groupPosition + 1;
  String flor = "      " + floor + "樓";
  holder.floor.setText(flor);
  ImageLoader iLoader = new ImageLoader(context);
  iLoader.DisplayImage(headimg, holder.userheadimg, false);

  return convertView;
}

@Override
public View getChildView(int groupPosition, int childPosition,
   boolean isLastChild, View convertView, ViewGroup parent) {
  FriendHolder holder;
  if (convertView == null) {
   holder = new FriendHolder();
   convertView = mChildInflater
     .inflate(R.layout.list_post_child, null);
   holder.uname = (TextView) convertView.findViewById(R.id.uname);
  
   convertView.setTag(holder);
  } else {
   holder = (FriendHolder) convertView.getTag();
  }

  LiaoYiLiaoPostInfo groupname = groupList.get(groupPosition)
    .getPostInfo().get(childPosition);
  holder.uname.setText(groupname.getUserAlias());// 好友名稱
 
 
  return convertView;
}

@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
  // TODO Auto-generated method stub
  return true;
}

class FriendHolder {

  // 父類
  ImageView userheadimg;// 頭像
  ImageView but_post;// 回覆按鈕
  TextView username;// 使用者名稱
 
  // 子類

  TextView uname;// 使用者名稱
  TextView coinfo;// 內容

}

}

建立一個main.xml檔案
< ?xml version="1.0" encoding="utf-8"?>
< LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/contact_list_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/gray_back"
    android:orientation="vertical" >


    <com.demo.util.ExpandableListPageView<!--com.demo.util 所在的包名  -->
        android:id="@+id/liao_post_list_view"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:cacheColorHint="#00000000"
        android:childDivider="@drawable/interval_line"
        android:divider="@drawable/interval_line"
        android:dividerHeight="1dp"
        android:fadingEdge="none"
        android:groupIndicator="@null"
        android:listSelector="@drawable/list_item_bg" />

</LinearLayout>

我只提供了一個思路,如果要執行需要改程式碼 ,不清楚的地方可以相互交流下