突出显示可展开列表中的选定项目
Posted
技术标签:
【中文标题】突出显示可展开列表中的选定项目【英文标题】:Highlight for selected item in expandable list 【发布时间】:2012-05-06 07:31:22 【问题描述】:我有一个布局,其中左侧的片段中有一个可扩展列表,右侧有一个详细信息片段。这一切都很好。
现在我想指出左侧的哪个项目的详细信息显示在右侧,这里我遇到了问题。
在普通的列表视图中,我通过将列表视图的选择模式设置为单一然后使用基于“激活”状态的可绘制状态来实现这一点。当我单击该项目时,背景将设置为我选择的颜色并保持这种状态,直到我选择列表中的另一个项目。
我试图将它应用到我的可扩展列表视图中,但它是/现在是一个惨淡的失败。没有错误,但所选项目未保持其颜色状态。我不确定我是否没有为它正确设置选择模式(我已经在布局文件中以及以编程方式尝试过它,它似乎没有任何区别),或者将它指向错误的东西(不知道怎么可能,但是...)
感谢任何帮助/指针(即使它的方向完全不同)。
最新故障:
可扩展的列表视图代码
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>
【问题讨论】:
你的问题是当你点击它时它很好,但是当你的列表视图向上或向下移动时它只是失去了颜色 不,这不是我的问题。我的问题和我说的完全一样。我选择了该项目,但未保留突出显示。它会闪烁“按下”状态的颜色,但不会更改/保持“激活”状态的颜色。 看看:github.com/ashish-dhiman/ExpandableWithListSelector 【参考方案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 步。 在 onChildClick() 回调中调用 expandableListView.setItemChecked(index,true)。
index是从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;
【讨论】:
这很有帮助。为此,由于某种原因,我无法让 android:listSelector="@drawable/selector_list_item" 正常工作。我的解决方案是在列表上执行 android:listSelector="@android:color/transparent" 然后在列表中项目的实际布局中, android:background="@drawable/selector_list_item" 嗨,getFlatListPosition(1,3)
总是返回 1
而不是子元素的平面位置。我想根据偏好数据设置 singleChoice ExpandableListView 的各种元素
感谢此解决方案适用于可扩展列表视图中的子视图,谢谢!我们如何在可展开的列表视图中更改所选组的背景颜色。
起初这对我不起作用,因为我在子项布局内的特定元素上设置了 onClickListeners。似乎他们覆盖了子点击监听器。
如何使用它来突出显示多个项目【参考方案2】:
花费 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;
【讨论】:
【参考方案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;
);
【讨论】:
哇...好胖 =) 我找到了更轻量级的解决方案。看上面。 是您的适配器在活动类中(嵌套)。你如何在lv.setOnChildClickListener(new ExpandableListView.OnChildClickListener()
中访问selectedStatus[][]
这适用于自定义视图,如果我们需要更改某些精确视图,我们可以使用模型中的标志变量并这样做。【参考方案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_
android:layout_
android:orientation="horizontal"
android:background="@drawable/selector" >
<TextView
android:id="@+id/TVChild"
android:layout_
android:layout_
android:textColor="#000"
android:textSize="12dp"/>
</LinearLayout>
在 xml 文件的 ExpandableListView 元素(不是子项或组)中的属性android:drawSelectorOnTop="true"
如下所示:
<ExpandableListView
android:id="@+id/expandableViewDetailsBriefing"
android:layout_
android:layout_
android:background="#fff"
android:drawSelectorOnTop="true"
android:dividerHeight="1px"
android:childDivider="@color/Gris"
android:indicatorRight="690dp"
android:textFilterEnabled="true" >
</ExpandableListView>
【讨论】:
我忘了指出 xml 文件中 ExpandableListView 元素中的属性 android:drawSelectorOnTop="true" 像这样下一个解决方案可帮助您为组和子创建不同的列表选择器。
首先,您需要禁用 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;
);
...
...
就是这样。我希望这个解决方案能帮您节省时间。
【讨论】:
【参考方案6】:您可以保存当前视图并在点击侦听器中更改视图的背景颜色:
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;
);
【讨论】:
【参考方案7】:如果您只需要更改子项颜色,而不是在 onchildclick
方法中将背景颜色设置为 View 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。
【讨论】:
【参考方案8】:当我面临与作者相同的问题时,这个简单的解决方案帮助了我
我有一个布局,其中的片段中有一个可扩展列表 左边和右边的细节片段。这一切都很好。现在我 想指出左边的哪个项目有它的详细信息 显示在右侧,我遇到了问题。
要指示选择了可扩展列表中的哪个项目,请转到 ExpandableListView 属性(在布局中)并为 listSelector 选择颜色。
【讨论】:
【参考方案9】: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;
);
【讨论】:
【参考方案10】: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;
);
【讨论】:
请查看此网址以进一步了解答案问题。 ***.com/help/how-to-answer【参考方案11】:只要使用下面的
<ExpandableListView
android:id="@+id/expandable_list"
android:layout_
android:layout_
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>
【讨论】:
不起作用,因为它关闭了指示器而不是组的 listSelector 帮助我了解了在哪里声明listselector
。赞成:)以上是关于突出显示可展开列表中的选定项目的主要内容,如果未能解决你的问题,请参考以下文章