我有一个ListView
,其项目可以处于以下三种状态之一:已选中,多选或无。
当选择该项时,表示用户刚刚点击它(选中它),并且该行的背景应更改为所选的drawable。
如果是多选,则表示用户长按某个项目,并将该列表置于多选模式。该初始项设置为多选,并且任何后续单击的项将被置于多选模式,直到多选结束(退格,取消选择所有多选项等)。多选行的背景应设置为多选的drawable。
否则它处于“无”状态且背景是透明的。
我遇到的问题是,当某个项目处于选定模式时,我会在View.setSelected(true)
的所选位置的视图上调用getView()
。我在我的应用程序中有两个地方使用此模式。在一个地方它完美地运作,但在另一个地方,似乎某些(不是我)在从View.setSelected(false)
返回后在我选择的行上调用getView()
。
以下是我初始化ListView的方法(通货膨胀后):
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
lv.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, final View clickedItem, int position, long id) {
if(adapter.isMultiSelect()) {
((ListView)parent).setItemChecked(position, !adapter.isPositionInMultiSelect(position));
}
else {
adapter.setNewSelectedPosition(position);
//do something
}
}
});
lv.setMultiChoiceModeListener(new MyMultiChoiceModeListener(adapter));
adapter.setNewSelectedPosition()
来电notifyDataSetChanged()
。这是我的getView()
:
public View getView(final int position, View convertView, final ViewGroup parent) {
if(convertView == null) {
convertView = new MyListRow(context);
}
boolean isSelected = isPositionInMultiSelect(position) || position == getSelectedPosition();
SelectionType selectionType = SelectionType.NONE;
if(isMultiSelect() && selectedPosition == position) {
if(isPositionInMultiSelect(position)) {
selectionType = SelectionType.MULTI_SELECT;
}
else {
selectionType = SelectionType.NONE;
}
selectedPosition = NO_SELECTION_POSITION;
}
else if(isSelected) {
if(isMultiSelect()) {
selectionType = SelectionType.MULTI_SELECT;
}
else {
selectionType = SelectionType.SELECTED_ITEM;
}
}
((MyListRow) convertView).updateViews(isSelected, selectionType);
return convertView;
}
这是MyListRow
:
public MyListRow(Context context) {
super(context);
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.my_row, this, true);
setPadding(20, 20, 20, 20);
setViewBackground(R.drawable.list_row_selector);
setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS);
}
public void updateViews(boolean isSelected, SelectionType selectionType) {
if(isSelected) {
if(selectionType == SelectionType.MULTI_SELECT) {
setSelected(false);
}
else {
setSelected(true);
}
}
else {
setSelected(false);
}
//do stuff
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void setViewBackground(int res) {
Drawable d = getContext().getResources().getDrawable(res);
Rect drawablePadding = new Rect();
d.getPadding(drawablePadding);
int top = getPaddingTop() + drawablePadding.top;
int left = getPaddingLeft() + drawablePadding.left;
int right = getPaddingRight() + drawablePadding.right;
int bottom = getPaddingBottom() + drawablePadding.bottom;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
setBackgroundDrawable(d);
}
else {
setBackground(d);
}
setPadding(left, top, right, bottom);
}
最后,这是list_row_selector.xml
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/list_selector_pressed"
android:state_pressed="true" />
<item
android:drawable="@drawable/list_selector_pressed"
android:state_selected="true" />
<item
android:drawable="@drawable/list_selector_activated"
android:state_activated="true" />
<item
android:drawable="@android:color/transparent" />
答案 0 :(得分:3)
无论出于何种原因,post
setSelected(true)使其有效:
public void updateViews(boolean isSelected, SelectionType selectionType) {
if(isSelected) {
if(selectionType == SelectionType.MULTI_SELECT) {
setSelected(false);
}
else {
post(new Runnable() {
@Override
public void run() {
setSelected(true);
}
});
}
}
else {
setSelected(false);
}
//do stuff
}