我想知道这些州的不同之处。我没有找到任何网页澄清这一点。
答案 0 :(得分:170)
Checked和Activated之间的区别实际上非常有趣。即使是Google文档也是抱歉的(下面重点介绍):
...例如,在具有单个或多个选择的列表视图中 启用后,将激活当前选择集中的视图。 (嗯 是的,我们对这里的术语深感抱歉。)激活了 state被传播到它所设置视图的子节点。
所以区别在于:
ListView(在Honeycomb之后)调用setChecked()或setActivated(),具体取决于Android版本,如下所示(取自Android源代码):
if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {
if (child instanceof Checkable) {
((Checkable) child).setChecked(mCheckStates.get(position));
} else if (getContext().getApplicationInfo().targetSdkVersion
>= android.os.Build.VERSION_CODES.HONEYCOMB) {
child.setActivated(mCheckStates.get(position));
}
}
注意mCheckStates变量。它会跟踪列表中的哪些位置被检查/激活。例如,可以通过getCheckedItemPositions()访问它们。另请注意,对ListView.setItemChecked()的调用会调用上面的内容。换句话说,它同样可以称为setItemActivated()。
在Honeycomb之前,我们必须实现变通方法以反映列表项中的state_checked。这是因为ListView仅在布局中最顶层的View上调用setChecked()(并且布局不实现可检查)......并且它不会在没有帮助的情况下传播。这些变通方法具有以下形式:扩展根布局以实现Checkable。在其构造函数中,递归地查找实现Checkable的所有子项。当调用setChecked()etc ...时,将调用传递给那些视图。如果这些视图使用不同的drawable for state_checked实现状态列表drawable(例如CheckBox),则检查状态将反映在UI中。
要在Honeycomb之后为列表项做一个很好的背景,你需要做的就是有一个状态列表,可以绘制一个状态state_activated的drawable(当然使用setItemChecked()):
<item android:state_pressed="true"
android:drawable="@drawable/list_item_bg_pressed"/>
<item android:state_activated="true"
android:drawable="@drawable/list_item_bg_activated"/>
<item android:drawable="@drawable/list_item_bg_normal"/>
要在HoneyComb之前为列表项做一个很好的背景,你可以为state_checked执行类似的操作,你还需要扩展最顶层的视图来实现Checkable接口。然后,你需要通过实现onCreateDrawableState()并在状态发生变化时调用refreshDrawableState()来告诉Android你正在实现的状态是真还是假。
<item android:state_pressed="true"
android:drawable="@drawable/list_item_bg_pressed"/>
<item android:state_checked="true"
android:drawable="@drawable/list_item_bg_checked"/>
<item android:drawable="@drawable/list_item_bg_normal"/>
...在RelativeLayout中实现Checkable和state_checked的代码可以是:
public class RelativeLayoutCheckable extends RelativeLayout implements Checkable {
public RelativeLayoutCheckable(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RelativeLayoutCheckable(Context context) {
super(context);
}
private boolean mChecked = false;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
@Override
public boolean isChecked() {
return mChecked;
}
@Override
public void setChecked(boolean checked) {
mChecked = checked;
refreshDrawableState();
}
private static final int[] mCheckedStateSet = {
android.R.attr.state_checked,
};
@Override
protected int[] onCreateDrawableState(int extraSpace) {
final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
if (isChecked()) {
mergeDrawableStates(drawableState, mCheckedStateSet);
}
return drawableState;
}
@Override
public void toggle() {
setChecked(!mChecked);
}
}
感谢以下内容:
http://sriramramani.wordpress.com/2012/11/17/custom-states/
Stackoverflow:How to add a custom button state
Stackoverflow:Custom Checkable View which responds to Selector
http://www.charlesharley.com/2012/programming/custom-drawable-states-in-android/
http://developer.android.com/guide/topics/resources/drawable-resource.html#StateList
http://blog.marvinlabs.com/2010/10/29/custom-listview-ability-check-items/
答案 1 :(得分:18)
根据doc:
android:state_selected 布尔。 “true
”如果在导航时对象是当前用户选择时应使用此项目
使用方向控制(例如在列表中导航时)
用d-pad); “false
”如果对象在此时应使用此项
未选中的。焦点时使用选定的状态
(android:state_focused)是不够的(比如列表视图有的话)
使用d-pad选择焦点和其中的项目。
android:state_checked 布尔。 “true
”如果在检查对象时应使用此项; “false
”如果应该使用的话
对象未经检查。
android:state_activated 布尔。 “true
”如果在将对象激活为持久选择时应使用此项(例如
至于“突出显示”持久性中先前选择的列表项
导航视图); “false
”如果在对象不是时应该使用它
活性。在 API级别11 。
我认为文档很清楚,那么问题是什么?
答案 2 :(得分:0)
以下是此问题的其他解决方案: https://github.com/jiahaoliuliu/CustomizedListRow/blob/master/src/com/jiahaoliuliu/android/customizedlistview/MainActivity.java
我已经覆盖了方法setOnItemClickListener并检查代码中的不同情况。但最终马文的解决方案要好得多。
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position,
long id) {
CheckedTextView checkedTextView =
(CheckedTextView)view.findViewById(R.id.checkedTextView);
// Save the actual selected row data
boolean checked = checkedTextView.isChecked();
int choiceMode = listView.getChoiceMode();
switch (choiceMode) {
// Not choosing anything
case (ListView.CHOICE_MODE_NONE):
// Clear all selected data
clearSelection();
//printCheckedElements();
break;
// Single choice
case (ListView.CHOICE_MODE_SINGLE):
// Clear all the selected data
// Revert the actual row data
clearSelection();
toggle(checked, checkedTextView, position);
//printCheckedElements();
break;
// Multiple choice
case (ListView.CHOICE_MODE_MULTIPLE):
case (ListView.CHOICE_MODE_MULTIPLE_MODAL):
// Revert the actual selected row data
toggle(checked, checkedTextView, position);
//printCheckedElements();
break;
}
}
});