2012-04-25 2 views
12

У меня есть макет, где у меня есть расширяемый список в фрагменте слева и фрагмент деталей справа. Все это прекрасно работает.Выделите выделенный элемент в расширяемом списке

Теперь я хотел бы указать, какой элемент слева содержит детали, показанные справа, и здесь у меня проблема.

В обычном виде списка я достиг этого, установив режим выбора для представления списка в одиночный, а затем используя состояние, которое можно вывести на основе «активированного» состояния. Когда я нажимаю элемент, фон устанавливается на мой выбранный цвет и остается таким, пока я не выберу другой элемент в списке.

Я попытался применить это к моему расширяемому списку, и это был/был мрачный сбой. Ошибок не было, но выбранный элемент не поддерживал его состояние цвета. Я не уверен, что я не правильно настрою режим выбора (я пробовал его в файле макета, а также программно, это, похоже, не имеет значения), или указывая на неправильную вещь (не знаю, как это может быть, но ...)

Любая помощь/указатели оценена (даже если она находится в совершенно другом направлении).

Большинство современных недостаточность:

расширяемый код ListView

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

Ваша проблема в том, когда вы нажимаете, это нормально, но когда ваш список вверх или вниз, он просто потерял свой цвет –

+0

Нет, это не моя проблема. Моя проблема в том, как я это сказал. Я выбираю элемент, и подсветка не поддерживается. Он мигает цветом для «нажатого» состояния, но не меняет цвет и сохраняет его для «активированного» состояния. – Barak

ответ

28

Выполните следующие действия на ExpandableListView:

Шаг 1. Set Выбор режима для одного (может быть сделано в 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 [индекс = 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

Это было очень полезно. Чтобы построить это, по какой-то причине я не смог получить android: listSelector = "@ drawable/selector_list_item ". Я решил сделать андроид: listSelector =" @ android: color/transparent "в списке, а затем в фактическом макете элемента в списке, android: background =" @ drawable/selector_list_item " –

+0

hi,' getFlatListPosition (1,3) 'всегда возвращает' 1' вместо плоского положения дочернего элемента. Я хочу установить различные элементы singleChoice ExpandableListView на основе данных предпочтений – nmxprime

+0

pfff Лучшее решение, не существует никакого решения, подобного этому .... Awesome !! – delive

2

У меня была та же проблема, я фиксированной это путем добавления

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" в элементе ExpandableListView в файле XML (а не дочерний элемент или группа), как это:

<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

+0

Я забыл указать атрибут android: drawSelectorOnTop = "true" в элементе ExpandableListView в файле xml (не дочерний элемент или группа), подобный этому

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

Wow ... So fat =) Я нашел более легкое решение. Посмотрите выше. – Rusfearuth

+0

- ваш адаптер в классе активности (вложен). как вы обращаетесь к 'selectedStatus [] []' в 'lv.setOnChildClickListener (новый ExpandableListView.OnChildClickListener() {' –

12

Потратив 3-4 часа он сделал его так просто не нужно создавать дополнительные файлы XML просто проверить, если элемент группы расширяется, если да, то выберите цвет и в другом заявлении сделать их как они есть ....

@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

хорошо один. ты спас мой день! !!! спасибо yaar .., @ prakash – Radhey

+0

очень просто и отлично работает! Спасибо – Dayan

-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

Не сделал это для меня .. –

+0

Не работает, потому что он выключает индикатор вместо спискаВыбор для группы – Rusfearuth

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 установить цвет фона Вид ст.

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

сделать это установить isChildSelectable истина в адаптере.

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 (в макете) и выберите цвет для спискаSelector.

Смежные вопросы