Android ExpandableListView長按事件的完美解決辦法_Android

來源:互聯網
上載者:User
關於ExpandableListView長按事件處理,網上很多都是使用將操作功能表註冊到ExpandableListView上實現長按事件。

這樣做弊端顯而易見,不夠靈活,不能分別對父項、子項、父項之間、子項之間彈出內容做區分。
下面來說我的解決方案,方法有點投機取巧。首先說明一點,使用我這種方法必須使用自訂的BaseExpandableListAdapter,至於為什麼,具體後面講到。

ExpandableListView本身有繼承自AdapterView的setOnItemLongClickListener(AdapterView.OnItemLongClickListener listener)方法。
實現監聽器:
複製代碼 代碼如下:

/**
  * 長按郵箱快捷選項
  * @author King
  */
 private class QuickWayListener implements OnItemLongClickListener{
  @Override
  public boolean onItemLongClick(AdapterView<?> arg0, View view,
    int pos, long id) {
   //pos不可用說明見下文
   return false;
  }
 }

如果這個方法是用在ListView長按事件中剛剛好,但在ExpandableListView中,第三個參數pos不能區分開點擊的是父項還是子項,以及哪個父項或子項。

在ExpandableListView響應的onItemLongCkick方法中,pos參數值為:從上到下,父項+展現的子項到點擊位置的數目(注意:是展現的,隱藏的子項不包括,從0開始)。
例如:
父項1(隱藏3個子項)
父項2
 |—子項2-0
 |—子項2-1
 |—子項2-2
長按子項2-1時,pos值為3。顯然根據pos值是無法確定點擊的是哪個子項或父項的。
因此依賴pos是很難處理點擊位置的。

如果可以直接在onItemLongClick方法中擷取groupPos,及childPos該多好呢?

於是看到了onItemLongClick方法第二個參數:view。這裡的view是你按中的位置對應的view。view有個方法getTag(int key)。如果在建立此view的時候就把groupPos,childPos通過setTag(int key, Object value)設定進去,在響應onItemLongClick不就可以直接拿出來用了麼。

現在就要講到必須使用自訂的BaseExpandableListAdapter的理由了。

要把groupPos,childPos通過setTag的方式綁定到view中,就必須操作該view的建立過程。要控制這個過程就必須要在自訂BaseExpandableListAdapter中重寫getGroupView及getChildView方法進行操作。如下:
複製代碼 代碼如下:

public class AccountListAdapter extends BaseExpandableListAdapter {
 ...省略其他方法
 @Override
 public View getChildView(int groupPosition, int childPosition,
   boolean isLastChild, View convertView, ViewGroup parent) {
  //我這裡僅通過自己寫的mkChildView()方法建立TextView來顯示文字,更複雜的可以通過LayoutInflater來填充一個view
  TextView childTv = mkChildView();
  // 標記位置
  // 必須使用資源Id當key(不是資源id會出現運行時異常),android本意應該是想用tag來儲存資源id對應組件。
  // 將groupPosition,childPosition通過setTag儲存,在onItemLongClick方法中就可以通過view參數直接拿到了!
                childTv.setTag(R.id.xxx01, groupPosition);
  childTv.setTag(R.id.xxx02, childPosition);
  return childTv;
 }
 @Override
 public View getGroupView(int groupPosition, boolean isExpanded,
   View convertView, ViewGroup parent) {
  TextView groupTv = mkGroupView();
  // 設定同getChildView一樣
  groupTv.setTag(R.id.xxx01, groupPosition);
  groupTv.setTag(R.id.xxx02, -1); //設定-1表示長按時點擊的是父項,到時好判斷。
  groupTv.setText(groups[groupPosition]);
  return groupTv;
 }
}

完成了這一步,我們只需要在ExpandableListView響應的onItemLongClick方法時通過view.getTag(R.id.xxx01),view.getTag(R.id.xxx02)即可拿到groupPos,childPos.
如下:
複製代碼 代碼如下:

       /**
  * 長按郵箱快捷選項
  * @author King
  */
 private class QuickWayListener implements OnItemLongClickListener{
  @Override
  public boolean onItemLongClick(AdapterView<?> arg0, View view,
    int pos, long id) {
   int groupPos = (Integer)view.getTag(R.id.xxx01); //參數值是在setTag時使用的對應資源id號
   int childPos = (Integer)view.getTag(R.id.xxx02);
   if(childPos == -1){//長按的是父項
       //根據groupPos判斷你長按的是哪個父項,做相應處理(彈框等)
   } else {
       //根據groupPos及childPos判斷你長按的是哪個父項下的哪個子項,然後做相應處理。 
   }
   return false;
  }
 }

到這就寫完了,貌似比較囉嗦。重寫BaseExpandableListAdapter寫的比較簡潔,沒看明白的朋友可以先到網上查下怎麼自訂BaseExpandableListAdapter,和自訂BaseAdapter其實是一樣的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.