单击Button时更改ListView项的背景颜色

时间:2014-06-04 08:25:20

标签: android android-listview android-listfragment

如果之前已经问过这个问题,请道歉。

我有一个ListFragment,每个列表项中都包含一个Button。单击按钮应更改该特定列表项的背景颜色。据我所知,ListFragment中的ListView会自行刷新,这意味着如果用户滚动它,可能是之前未点击的列表项的背景颜色会发生变化。

我遇到的许多解决方案都涉及存储在自定义适配器中实现的重写的getView(int position,View convertView,ViewGroup parent)方法中单击的列表项的位置(在我的情况下扩展了SimpleAdapter) 。

然而,我的问题因每个列表项中都存在一个Button而更加复杂,这意味着除非我在自定义适配器中附加OnClickListener(此部分已完成),否则Button将无法点击。现在,尝试存储Button的列表项的位置失败,因为保存的位置始终是刷新的位置而不是列表项的绝对位置。我也尝试为每个按钮设置标签,但即使那些按页面滚动也会被回收,考虑到ListView的设计,这是(不幸的)预期的行为。

据我所知,如果列表项没有需要点击的子项,则此问题很容易解决。但是,如果每个列表项中都有子项需要响应与包含每个列表项的父视图分开的点击,该怎么办?我也尝试使用选择器来操作列表项的背景,但这也没有帮助。

这是我的自定义适配器的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> 

我花了很多时间来解决这个问题,但我无法找到解决方案。任何指导,指导或解决方案都将受到最高的赞赏。

1 个答案:

答案 0 :(得分:1)

在自定义适配器的getView()方法中,只有当convertView为空时,才会使视图膨胀并附加onclicklistener。 convertView是回收的视图。如果convertView不为null,则需要更改该视图中的值。您的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;
    }

实际上,如果它们发生变化,您还应该根据position更改与该项目相关联的任何值。例如,如果每个button显示列表中的位置,则还应添加以下行

button.setText("Button " + position);