突出显示可展开列表中的选定项目

Bar*_*rak 14 android android-widget android-layout

我有一个布局,我在左边的片段中有一个可扩展列表,右边有一个细节片段.一切正常.

现在我想说明左边的哪个项目正在显示右边的详细信息,这里我遇到了问题.

在普通列表视图中,我通过将列表视图的选择模式设置为单个,然后使用基于"激活"状态的可绘制状态来实现此目的.当我单击该项目时,背景将设置为我选择的颜色并保持这种状态,直到我在列表中选择另一个项目.

我试着将它应用到我的可扩展列表视图中,这是一个令人沮丧的失败.没有错误,但所选项目没有保持其颜色状态.我不确定我是不是正确设置了它的选择模式(我已经在布局文件中尝试了它以及编程方式,它似乎没有什么区别),或者指向错误的东西(不知道那是怎么回事,但......)

任何帮助/指示赞赏(即使它是在一个完全不同的方向).

目前大多数失败:

可扩展的列表视图代码

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

Him*_*ani 32

在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>
Run Code Online (Sandbox Code Playgroud)

步骤3.呼叫expandableListView.setItemChecked(指数,真正的)在onChildClick()回调.

index是如下计算的子项的基于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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这非常有帮助.为了构建这个,由于某种原因我无法获得android:listSelector ="@ drawable/selector_list_item"才能正常工作.我的解决方案是在列表上执行android:listSelector ="@ android:color/transparent",然后在列表中项目的实际布局中,android:background ="@ drawable/selector_list_item" (2认同)

小智 14

花了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;
}
Run Code Online (Sandbox Code Playgroud)


Bar*_*rak 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
Run Code Online (Sandbox Code Playgroud)

构造 函数初始化数组

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

    }
Run Code Online (Sandbox Code Playgroud)

当孩子滚出视野时需要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; 
    } 
Run Code Online (Sandbox Code Playgroud)

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;
        }
    });
Run Code Online (Sandbox Code Playgroud)