Вопрос по android, android-layout, android-widget – Выделите для выбранного элемента в раскрывающемся списке

13

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

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

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

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

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

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

expandable listview code

<code>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;
    }
}
</code>

item_selector.xml

<code><?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>
</code>
Ваша проблема в том, что когда вы нажимаете, это нормально, но когда ваш список движется вверх или вниз, он просто теряет свой цвет Bharat Sharma
Нет, это не моя проблема. Моя проблема именно так, как я это сказал. Я выбираю пункт, и выделение не сохраняется. Он мигает цветом для «нажатой» состояние, но не меняет цвет на / поддерживает цвет для "активированного" государство. Barak

Ваш Ответ

11   ответов
6

как заставить это работать (для меня). Это кажется чем-то вроде взлома, но это единственное, что мне удалось добиться для этого.

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

Constructor initialize the array

    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 needed for when the child scrolls out of view

    @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 change selected item

    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;
        }
    });
Error: User Rate Limit ExceededselectedStatus[][]Error: User Rate Limit Exceededlv.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
Error: User Rate Limit Exceeded
30

Step 1. Установить режим выбора на один (Может быть сделано в XML какandroid:choiceMode = "singleChoice")

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

Step 3. ВызовexpandableListView.setItemChecked(index,true) в обратном вызове onChildClick ().

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

Group 1   [index = 0]

Child item 1 Child item 2 Child item 3 [index = 3]

Group 2  [индекс = 4]

Child item 1 Child item 2 Child item 3 [index = 7]

Group 3 [index = 8]

Child item 1 Child item 2 Child item 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;
}
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededgetFlatListPosition(1,3)Error: User Rate Limit Exceeded1Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0
expListView.setOnChildClickListener(new OnChildClickListener() {

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



                for (int i = 1; i < expListView.getChildCount(); i++) {
                    View child = (View) expListView.getChildAt(i);
                    child.setBackgroundColor(Color.BLACK);
                }


                if(childPosition==0){
                    initWebView("URL");

                }
                if(childPosition==1) {
                    initWebView("URL");

                }
                if(childPosition==2) {

                    initWebView("URL");

                }
                if(childPosition==3) {
                    initWebView("URL");

                }
                if(childPosition==4) {
                    initWebView("URL");

                }
                if(childPosition==5) {
                    initWebView("URL");
                }

                v.setBackgroundColor(Color.GRAY);


                expListView.setVisibility(View.GONE);
                webView.setVisibility(View.VISIBLE);
                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 истина в адаптере.

1

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

I have a layout where I have an expandable list in a fragment on the left and a details fragment on the right. This all works fine. Now I would like to indicate what item on the left is having it's details shown on the right and here I'm having a problem.

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

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>
Error: User Rate Limit Exceeded Barak
Error: User Rate Limit Exceeded
-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>
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
2

ребенка.

Прежде всего, вам нужно отключить селектор списка для 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

вления в ваших слушателях щелчков:

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

чтобы сделать это настолько простым, что нет необходимости создавать дополнительные файлы 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;
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
0
expListView.setOnChildClickListener(new OnChildClickListener() {

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



            for (int i = 1; i < expListView.getChildCount(); i++) {
                View child = (View) expListView.getChildAt(i);
                child.setBackgroundColor(Color.BLACK);
            }


            if(childPosition==0){
                initWebView("URL");

            }
            if(childPosition==1) {
                initWebView("URL");

            }
            if(childPosition==2) {

                initWebView("URL");

            }
            if(childPosition==3) {
                initWebView("URL");

            }
            if(childPosition==4) {
                initWebView("URL");

            }
            if(childPosition==5) {
                initWebView("URL");
            }

            v.setBackgroundColor(Color.GRAY);


            expListView.setVisibility(View.GONE);
            webView.setVisibility(View.VISIBLE);
            return false;
        }
    });
}
Error: User Rate Limit Exceededstackoverflow.com/help/how-to-answer

Похожие вопросы