如果之前有人问过这个问题,我们深表歉意。
我有一个 ListFragment,每个列表项中都包含一个 Button。单击按钮应更改该特定列表项的背景颜色。我知道 ListFragment 中的 ListView 会自行刷新,这意味着如果用户滚动,则之前未单击的列表项的背景颜色可能会发生变化。
我遇到的许多解决方案都涉及存储在自定义适配器(在我的例子中扩展了 SimpleAdapter)中实现的重写 getView(int position, View convertView, ViewGroup parent) 方法中单击的列表项的位置.
但是,我的问题因每个列表项中都存在一个按钮而变得更加复杂,这意味着除非我在自定义适配器中附加一个 OnClickListener(这部分已完成),否则该按钮将不可单击。现在,尝试存储 Button 列表项的位置失败,因为保存的位置始终是刷新位置而不是列表项的绝对位置。我还尝试为每个按钮设置标签,但即使是那些按钮也会在页面滚动时被回收,考虑到 ListView 的设计,这是(不幸的)预期行为。
据我了解,如果列表项没有需要单击的子项,则此问题很容易解决。但是,如果每个列表项中都有需要响应与包含每个列表项的父 View 分开的点击的子项怎么办?我也尝试过使用选择器来操纵列表项的背景,但这也没有帮助。
这是我的自定义适配器的 getView 方法:
@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
final int pos = position;
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.fragment_layout, null);
Button button = (Button) view.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.d("CLICKED POSITION",Integer.valueOf(pos).toString());
View parent = (View) v.getParent();
parent.setBackgroundColor(Color.GREEN);
}
});
}
return view;
}
和 XML 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="300dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="1"
android:descendantFocusability="blocksDescendants"
android:layout_margin="5dp"
>
<ListView android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/label"
android:layout_gravity="start"
/>
<TextView
android:id="@+id/text_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="end"
/>
<Button
android:id="@+id/button"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/button"
android:layout_margin="2dp"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:clickable="true"
/>
</LinearLayout>
我在这个问题上花了很多时间,但我无法找到解决方案。任何方向、指导或解决方案将不胜感激。
最佳答案
在自定义适配器的 getView()
方法中,只有当 convertView
为 null 时,您才会膨胀 View 并附加 onclicklistener。 convertView
是回收 View 。如果 convertView
不为空,则您需要更改该 View 中的值。你的 getView()
方法应该是这样的
@Override
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
final int pos = position;
//No recycled view, so create a new one
if(view == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.fragment_layout, null);
}
//By this line, we either have a view that is created in the if block above or passed via convertView
Button button = (Button) view.findViewById(R.id.button);
//attach listener to the view, recycled or not
button.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
Log.d("CLICKED POSITION",Integer.valueOf(pos).toString());
//parent not required as we are have the view directly
//View parent = (View) v.getParent();
v.setBackgroundColor(Color.GREEN);
}
});
return view;
}
事实上,如果它们发生变化,您还应该根据该位置
更改与该项目关联的任何值。例如,如果每个按钮
显示列表中的位置,您还应该添加以下行
button.setText("按钮"+ position);
关于android - 单击按钮更改 ListView 项目的背景颜色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24032445/