Подтвердить что ты не робот

Выделение выделенного элемента в расширяемом списке

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

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

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

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

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

Самый текущий сбой:

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

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>
4b9b3361

Ответ 1

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

Шаг 1. Установите режим выбора в одиночный (можно сделать в xml как android: choiceMode = "singleChoice" )

Шаг 2. Используйте селектор xml в качестве фона (android: listSelector = "@drawable/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(index, true) в обратном вызове onChildClick().

index - это индекс, основанный на 0 дочернего элемента, рассчитанный следующим образом

Группа 1 [index = 0]

  • Детский элемент 1
  • Детский элемент 2
  • Детский элемент 3 [index = 3]

Группа 2 [index = 4]

  • Детский элемент 1
  • Детский элемент 2
  • Детский элемент 3 [index = 7]

Группа 3 [index = 8]

  • Детский элемент 1
  • Детский элемент 2
  • Детский элемент 3 [index = 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

Проведя 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;
}

Ответ 3

Наконец-то я понял, как сделать эту работу (для меня). Кажется, это немного взломанный, но это единственное, что мне удалось найти для этого.

В основном я создаю двухмерный массив, чтобы удерживать выбранное состояние дочерних элементов, инициализировать его в конструкторе адаптера, тогда я ссылаюсь на это в моем методе 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;
        }
    });

Ответ 4

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

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>

Ответ 5

Следующее решение поможет вам создать другой селектор списка для группы и ребенка.

Прежде всего, вам нужно отключить селектор списков для ExpendableListView:


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

После этого вам нужно скопировать пустой списокSelector. Вы можете сделать это вам нравится


...
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;
           }
       });
       ...
    }
...
}

Это все. Надеюсь, что это решение не оставляет времени.

Ответ 6

Если вам нужно изменить только цвет дочернего элемента, чем в методе 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 в адаптере.

Ответ 7

Вы можете сохранить текущий вид и изменить цвет фона для просмотра в своих кликах:

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;
    }
});

Ответ 8

Это простое решение помогло мне, когда я столкнулся с тем же вопросом, что и автор

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

Чтобы указать, какой элемент в расширяемом списке выбран, перейдите в свойства ExpandableListView (в макете) и выберите цвет для спискаSelector.

Ответ 9

просто используйте ниже

    <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>