我在三星手机上遇到一个简单的ListView问题。
我以编程方式创建一个新的ListView。这些项目是简单的TextView。我在我的列表视图中放了一个监听器:
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
}
});
TextView
(即listView的项目)使用ColorStateList
作为textColor(按下 - &gt;绿色;选中 - &gt;蓝色;默认 - &gt;红色)。
在模拟器上,一切都很好:默认情况下项目是红色的,当我按下它变为绿色时,当我释放时它变为蓝色。如果我选择另一个项目:先前选择的项目将返回红色,新选择的项目将变为蓝色。
在我的三星设备上:默认情况下,项目为红色,当我按下一个变为绿色时,当我释放时它再次变为红色(即未选中)。
这似乎是三星ListView实现中的一个错误(它是一个自定义实现,因此很难在没有源代码的情况下进行跟踪)。
编辑:不是错误,而是因触摸模式略有不同的行为(请参阅接受回答中的链接)
您对如何解决此错误/ 行为有什么想法吗?
附加约束:我不能使用 xml选择器,因为我收到的颜色只能在运行时使用。
我的设备是三星GT-B5330,API 15.(但我希望它出现在大多数三星设备上)
这是完整的(可编译的)代码
import android.R;
import android.app.Activity;
import android.content.res.ColorStateList;
import android.database.DataSetObserver;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class TestActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RelativeLayout rootLayout = new RelativeLayout(this);
setContentView(rootLayout);
//create listView
ListView listView = new ListView(this);
listView.setAdapter(new MyListAdapter());
listView.setDivider(null);
listView.setDividerHeight(0);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
listView.setItemsCanFocus(false);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
view.setSelected(true);
}
});
listView.setBackgroundColor(Color.WHITE);
//positionning listView
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(100,200);
lp.setMargins(50,50,10,10);
rootLayout.addView(listView, lp);
}
private class MyListAdapter implements ListAdapter{
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ColorStateList colorStateList = new ColorStateList(
new int[][]{
new int[]{R.attr.state_pressed},
new int[]{R.attr.state_selected},
new int[]{-R.attr.state_selected},
},
new int[]{
Color.GREEN,
Color.BLUE,
Color.RED});
TextView textView = new TextView(parent.getContext());
textView.setText("Item " + position);
textView.setTextColor(colorStateList);
return textView;
}
@Override
public boolean areAllItemsEnabled() {
return true;
}
@Override
public boolean isEnabled(int position) {
return true;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return 10;
}
@Override
public Object getItem(int position) {
return "data "+position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public int getViewTypeCount() {
return getCount();
}
@Override
public boolean isEmpty() {
return getCount()>0;
}
}
}
答案 0 :(得分:1)
我手边没有三星设备(Galaxy Nexus不算数,它有简单的Android,你的例子也很好用)所以我无法测试我的假设但似乎ListView下降选择的状态项目发布后。您可以使用HierarchyViewer进行检查(如果手机未植根,请使用Romain Guy的ViewServer。)
由于TouchMode依赖于具有触摸屏的选择是危险的(参见http://android-developers.blogspot.ru/2008/12/touch-mode.html)。用两个词来说:当用户与触摸屏交互时,你没有选择(或焦点,顺便说一句)的概念。仿真器通常具有D-pad,因此它的行为可能略有不同。
所以我的建议是使用state_checked
代替state_selected
。 Android有CheckedTextView可能有所帮助。只需调用ListView的setItemChecked
即可。此解决方案还具有很好的属性,可以在配置更改之间保持检查项目位置,并在按下其他项目时自动取消选中先前检查的项目(如果使用CHOICE_MODE_SINGLE
)。
如果这是不可接受的,你需要坚持state_selected
,那么你可以将TextView包装成LinearLayout,它应该防止选择消失。但是不要忘记,当ListView退出屏幕时,ListView会对其他列表项重复使用相同的视图,因此您需要跟踪适配器中的选择状态以正确设置它。
答案 1 :(得分:0)
我可以确认,我在三星设备(Nexus,S3,Note2)上遇到过类似的错误。 Listview项目具有默认的背景颜色,因此在我的情况下为黑色。但是它会随机变成红色。如果我将listviewitem backgroundcolor显式设置为黑色,我没有遇到该错误。老实说,我不知道如何解决你的情况,但定义所有州的颜色可能对你有帮助。