2012-04-25 117 views
12

我有一個佈局,在左側的一個片段中有一個可擴展列表,右側有一個細節片段。這一切工作正常。突出顯示可擴展列表中的選定項目

現在我想指出左側的項目是否在右側顯示了詳細信息,在這裏我遇到了問題。

在正常的列表視圖中,我已經通過將列表視圖的選擇模式設置爲單一,然後使用基於「激活」狀態的可繪製狀態來實現此目的。當我點擊該項目時,背景設置爲我選擇的顏色並保持不變,直到我選擇列表中的其他項目。

我試圖將此應用於我的可擴展列表視圖,它是/是一個令人沮喪的失敗。沒有錯誤,但所選項目未保持其顏色狀態。我不知道如果我沒有正確設置選擇模式(我已經在佈局文件中以編程方式嘗試過它,它似乎沒有什麼區別),或者指向錯誤的東西(不知道如何可能,但...)

任何幫助/指針讚賞(即使它是在一個完全不同的方向)。

大多數當前的失敗:

膨脹列表視圖代碼

private void fillData(String group, String child) { 
    ExpandableListView lv; 
    mGroupsCursor = mDbHelper.fetchGroup(group); 
    getActivity().startManagingCursor(mGroupsCursor); 
    mGroupsCursor.moveToFirst(); 
    lv = (ExpandableListView) getActivity().findViewById(R.id.explist); 
    lv.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE);   

    mAdapter = new MyExpandableListAdapter(mGroupsCursor, getActivity(), 
      R.layout.explistlayout, 
      R.layout.explistlayout, 
      new String[] { "_id" }, 
      new int[] { android.R.id.text1 }, 
      new String[] { child }, 
      new int[] { android.R.id.text1 }); 
    lv.setAdapter(mAdapter); 
    registerForContextMenu(lv); 

    lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { 
     @Override 
     public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) 
     { 
      mRowId = id; 
      EventDisplayFragment eventdisplay = new EventDisplayFragment(); 
      getFragmentManager().beginTransaction().replace(R.id.rightpane, eventdisplay).commit(); 
      return true; 
     } 
     }); 
} 

public class MyExpandableListAdapter extends SimpleCursorTreeAdapter { 

    public MyExpandableListAdapter(Cursor cursor, Context context, 
      int groupLayout, int childLayout, String[] groupFrom, 
      int[] groupTo, String[] childrenFrom, int[] childrenTo) { 
     super(context, cursor, groupLayout, groupFrom, groupTo, 
       childLayout, childrenFrom, childrenTo); 
    } 
    @Override 
    protected Cursor getChildrenCursor(Cursor groupCursor) { 
     Cursor childCursor = mDbHelper.fetchChildren(mGroup, groupCursor 
       .getString(groupCursor 
         .getColumnIndex(AttendanceDB.EVENT_ROWID))); 
     getActivity().startManagingCursor(childCursor); 
     childCursor.moveToFirst(); 
     return childCursor; 
    } 
} 

item_selector.xml

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item 
    android:state_pressed="true" 
    android:drawable="@color/green" /> 
    <item 
    android:state_selected="true" 
    android:drawable="@color/blue" /> 
    <item 
    android:state_focused="true" 
    android:drawable="@color/violet" /> 
    <item 
    android:state_activated="true" 
    android:drawable="@color/blue" /> 
</selector> 
+0

你的問題是當你點擊它很好,但當你的列表視圖向上或向下移動它只是失去了它的顏色 – 2012-04-25 15:25:45

+0

不,這不是我的問題。我的問題與我所說的完全相同。我選擇了該項目並且不保留突出顯示。它爲「按下」狀態閃爍顏色,但不會變爲/保持「激活」狀態的顏色。 – Barak 2012-04-25 15:30:42

回答

28

執行以下操作上ExpandableListView:

第1步:設置選擇模式單(可以用XML來實現爲機器人:choiceMode = 「singleChoice」

步驟2.使用選擇XML作爲背景(機器人:listSelector =「 @繪製/ selector_list_item」

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
    android:exitFadeDuration="@android:integer/config_mediumAnimTime"> 

    <item android:drawable="@android:color/holo_blue_bright" android:state_pressed="true"/> 
    <item android:drawable="@android:color/holo_blue_light" android:state_selected="true"/> 
    <item android:drawable="@android:color/holo_blue_dark" android:state_activated="true"/> 

</selector> 

第3步:呼叫expandableListView.setItemChecked(指數,真正的)在onChildClick()回調。

指數是作爲計算出的子項的0的索引如下

組1 [指數= 0]

  • 兒童項目1
  • 兒童項目2
  • 子項目3 [index = 3]

組2 [指數= 4]

  • 兒童項目1
  • 兒童項目2
  • 兒童項目3 [指數= 7]

組3 [指數= 8]

  • 子項目1
  • 子項2
  • 兒童項目3 [指數= 11]

如果我們有表頭爲好,他們也佔指數值。

這裏是一個工作示例:

@Override 
public boolean onChildClick(ExpandableListView parent, View v, 
     int groupPosition, int childPosition, long id) { 
    ... 

    int index = parent.getFlatListPosition(ExpandableListView.getPackedPositionForChild(groupPosition, childPosition)); 
    parent.setItemChecked(index, true); 


    return true; 
} 
+2

]中的'selectedStatus [] []'在這個基礎上,出於某種原因,我無法得到android:listSelector =「@ drawable/selector_list_item「正常工作,我的解決方案是在列表中執行android:listSelector =」@ android:color/transparent「,然後在列表中的項目的實際佈局中,android:background =」@ drawable/selector_list_item 「 – 2014-03-13 15:03:40

+0

hi,'getFlatListPosition(1,3)'總是返回'1'而不是子元素的平面位置我想根據首選項數據設置singleChoice ExpandableListView的各種元素 – nmxprime 2014-06-10 08:38:16

+0

pfff最好的解決方案,不存在任何與此類似的解決方案.... Awesome !! – delive 2015-04-09 08:43:35

2

我在我通過添加

固定此相同的問題3210
v.setSelected(true); 

這裏是我的代碼示例:像這樣

expandableListDetailsLevel.setChoiceMode(ExpandableListView.CHOICE_MODE_SINGLE); 
     expandableListDetailsLevel 
       .setOnGroupExpandListener(new OnGroupExpandListener() { 

        public void onGroupExpand(int groupPosition) { 

         if(groupPosition!=1){ 
          expandableIsThere = false; 
         } 

         for (int i = 0; i < len; i++) { 
          if (i != groupPosition) { 
           expandableListDetailsLevel.collapseGroup(i); 
          } 
         } 
        } 
       }); 

     expandableListDetailsLevel 
       .setOnChildClickListener(new OnChildClickListener() { 

        @Override 
        public boolean onChildClick(ExpandableListView parent, 
          View v, int groupPosition, int childPosition, 
          long id) { 


         v.setSelected(true); 

         } 

我的項目XML

<?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="wrap_content" 
android:orientation="horizontal" 
android:background="@drawable/selector" > 


<TextView 
    android:id="@+id/TVChild" 
    android:layout_width="fill_parent" 
    android:layout_height="match_parent" 
    android:textColor="#000" 
    android:textSize="12dp"/> 

</LinearLayout> 

屬性android:drawSelectorOnTop="true"在XML文件(而不是項目的孩子或集團)ExpandableListView元素:

<ExpandableListView 
       android:id="@+id/expandableViewDetailsBriefing" 
       android:layout_width="fill_parent" 
       android:layout_height="match_parent" 
       android:background="#fff" 
       android:drawSelectorOnTop="true" 
       android:dividerHeight="1px" 
       android:childDivider="@color/Gris" 
       android:indicatorRight="690dp" 
       android:textFilterEnabled="true" > 
      </ExpandableListView> 
+0

不幸的是,這不適合我。 – Barak 2012-10-22 14:48:51

+0

我忘了指出在xml文件(不是項目子組或組)中的ExpandableListView元素中的屬性android:drawSelectorOnTop =「true」 2012-10-22 16:33:31

5

我終於想出瞭如何使這項工作(用於我)。這似乎有點破解,但這是我設法爲此工作的唯一一件事。

基本上我創建了一個二維數組來保存孩子的選擇狀態,在適配器構造函數中初始化它,然後在我的getChildView方法中引用該方法(以防當前選擇的孩子滾動出視圖)和我的onChildClick方法(改變當前的選擇並關閉舊的)。

private selectedStatus[][]; // array to hold selected state 
private View oldView;  // view to hold so we can set background back to normal after selection of another view 

構造初始化數組

public MyExpandableListAdapter(Cursor cursor, Context context, 
      int groupLayout, int childLayout, String[] groupFrom, 
      int[] groupTo, String[] childrenFrom, int[] childrenTo) { 
     super(context, cursor, groupLayout, groupFrom, groupTo, 
       childLayout, childrenFrom, childrenTo); 
     selectedStatus = new boolean[cursor.getCount()][]; 
     for (int i = 0; i < cursor.getCount(); i++) { 
      cursor.moveToPosition(i); 
      Cursor childCheckCursor = mDbHelper.fetchChildren(mGroup, 
        cursor.getString(cursor 
          .getColumnIndex(AttendanceDB.EVENT_ROWID))); 
      getActivity().startManagingCursor(childCheckCursor); 
      selectedStatus[i] = new boolean[childCheckCursor.getCount()]; 
      for (int j = 0; j < childCheckCursor.getCount(); j++) { 
       selectedStatus[i][j] = false; 
      } 
     } 

    } 

getChildView所需子滾動時出觀

@Override 
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { 
     final View v = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent); 
     if(selectedStatus[groupPosition][childPosition] == true){ 
      v.setBackgroundResource(R.color.blue);       
     } else { 
      v.setBackgroundResource(R.color.black); 
     } 
     return v; 
    } 

onChildClick改變所選項目

lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { 
     @Override 
     public boolean onChildClick(ExpandableListView parent, View v, 
       int groupPosition, int childPosition, long id) { 
      mRowId = id; 
      EventDisplayFragment eventdisplay = new EventDisplayFragment(); 
      getFragmentManager().beginTransaction() 
        .replace(R.id.rightpane, eventdisplay).commit(); 
      if(oldView != null){ 
       oldView.setBackgroundResource(R.color.black); // change the background of the old selected item back to default black     } 
      oldView = v;          // set oldView to current view so we have a reference to change back on next selection 
      for (int i = 0; i < selectedStatus.length; i++) { 
       for (int j = 0; j < checkedStatus[i].length; j++) { 
        if(i == groupPosition && j == childPosition){ // set the current view to true and all others to false 
         selectedStatus[i][j] = true; 
        } else { 
         selectedStatus[i][j] = false; 
        } 
       } 
      } 
      v.setBackgroundResource(R.color.blue); 
      return true; 
     } 
    }); 
+0

哇......那麼脂肪=)我找到了更輕量級的解決方案。看看上面。 – Rusfearuth 2014-07-16 05:40:52

+0

是你的適配器在活動類(嵌套)。如何訪問'lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener(){' – 2016-05-12 12:18:07

12

花費3-4個小時後,它是由它的這麼簡單無需創建額外的XML文件只是檢查組項目展開,如果是,則選擇顏色在else語句讓他們,因爲他們是....

@Override 
//in this method you must set the text to see the parent/group on the list 
public View getGroupView(final int i, boolean b, View view, ViewGroup viewGroup) { 

    if (view == null) { 
     view = inflater.inflate(R.layout.list_item_parent, viewGroup,false); 
    } 

    if(b){ 
     view.setBackgroundResource(R.color.waterblue); 
    }else{ 
     view.setBackgroundColor(color.transparent); 
    } 


    //return the entire view 
    return view; 
} 
+0

不錯的一個。你救了我一天兄弟!謝謝亞爾..,@ prakash – Radhey 2016-01-08 06:10:41

+0

很簡單,工作很棒!謝謝 – Dayan 2016-02-23 18:25:51

-2

只需使用下面的

<ExpandableListView 
     android:id="@+id/expandable_list" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:layout_gravity="start" 
     android:childDivider="#474043" 
     android:groupIndicator="@null" 
     android:listSelector = "@drawable/item_selector" 
     android:background="#555" 
     android:drawSelectorOnTop="true" 
     android:textFilterEnabled="true" 
     /> 

和您的item_selector.xml如下

<?xml version="1.0" encoding="utf-8"?> 
<selector xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:drawable="@color/selection_color_for_ex_list" android:state_pressed="true"/> 
    <item android:drawable="@color/selection_color_for_ex_list" android:state_selected="true"/> 
    <item android:drawable="@color/selection_color_for_ex_list" android:state_focused="true"/> 

</selector> 
+0

沒有爲我做。 – 2014-01-05 01:05:12

+0

不起作用,因爲它關閉指示器而不是listSelector for group – Rusfearuth 2014-07-16 05:59:40

1

下一個解決方案幫助您爲組和兒童不同的列表選擇。

首先,你需要禁用的ExpendableListView列表選擇:

 

... 
    <ExpandableListView 
      ... 
      android:listSelector="@android:color/transparent" 
      ... 
      /> 
... 
 

後,你需要複製一個空listSelector。你可以這樣做

 

... 
private Drawable empty; 
... 

// binding view here. Name of ExpandableListView will be elv 
empty = elv.getSelector(); 

 

現在,我們需要知道什麼時候我們將啓用列表選擇器或禁用。您應該添加後續更改適配器爲:

 

my adapter here { 
... 
    @Override 
    public View getGroupView(int groupPosition, boolean isExpanded, View view, ViewGroup parent) 
    { 
     ... 
     // after, we've got view of goup 
     view.setOnTouchListener(new View.OnTouchListener() 
     { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) 
      { 
       elv.setSelector(empty); 
       return false; 
      } 
     }); 
     ... 
    } 
... 
    @Override 
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) 
    { 
     ... 
     // after, we've got view of child 
     view.setOnTouchListener(new View.OnTouchListener() 
     { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) 
      { 
       elv.setSelector(R.drawable.my_custom_list_selector); 
       return false; 
      } 
     }); 
     ... 
    } 
... 
} 
 

這就是全部。我希望這個解決方案保持你的時間。

1

如果你只需要子項目顏色比onchildclick方法來改變背景顏色設置到視圖V。

@Override 
      public boolean onChildClick(ExpandableListView parent, View v, 
        int groupPosition, int childPosition, long id) { 
       // TODO Auto-generated method stub 
       v.setBackgroundColor(Color.RED); 
} 

這樣做在適配器設置isChildSelectable爲true。

1

您可以保存當前視圖和更改視圖背景色的點擊偵聽器中:

View currentView; 
ExpandableListView elv; 

elv.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { 
    @Override 
    public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { 
     if(currentView != null) { 
      currentView.setBackgroundColor(Color.parseColor("#FFFFFF")); 
     } 
     v.setBackgroundColor(Color.parseColor("#EEEEEE")); 
     currentDrawerView = view; 

     //do something 

     return false; 
    } 
}); 
elv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { 
    @Override 
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { 
     if(currentView != null) { 
      currentView.setBackgroundColor(Color.parseColor("#FFFFFF")); 
     } 
     v.setBackgroundColor(Color.parseColor("#EEEEEE")); 
     currentDrawerView = view; 

     //do something 

     return false; 
    } 
}); 
1

這種簡單的解決方案幫助我,當我面臨着像筆者

同樣的問題

我有一個佈局,其中我在左側的 的片段中有一個可擴展列表,右側有一個細節片段。這一切工作正常。現在我 想要指出左側的項目是它的詳細信息 顯示在右側,這裏我有一個問題。

要指示選中可擴展列表中的項目,請轉到ExpandableListView屬性(在佈局中)併爲listSelector選擇顏色。

相關問題