简体   繁体   English

单击按钮更改ListView项的背景颜色

[英]Changing background color of ListView item upon clicking a Button

Apologies if this question has been asked previously. 抱歉如果以前曾问过这个问题。

I have a ListFragment that contains a Button in each list item. 我有一个ListFragment,每个列表项中都包含一个Button。 Clicking on the Button should change the background color of that particular list item. 单击按钮应更改该特定列表项的背景颜色。 I understand that the ListView inside the ListFragment refreshes itself implying that if a user scrolls it is likely that a list item that was not previously clicked will have its background color changed. 我知道ListFragment中的ListView会刷新自身,这意味着如果用户滚动,以前未单击的列表项很可能会更改其背景颜色。

Many of the solutions I have come across involve storing the position of the list item that was clicked in an overridden getView(int position, View convertView, ViewGroup parent) method implemented in a custom adapter (that extends SimpleAdapter in my case). 我遇到的许多解决方案都包含将单击的列表项的位置存储在自定义适配器(在我的情况下扩展了SimpleAdapter)中实现的重写的getView(int position,View convertView,ViewGroup parent)方法中。

However my problem is compounded by the presence of a Button inside every list item implying that the Button will not be clickable unless I attach an OnClickListener inside a custom adapter (this part is done). 但是,每个列表项中都存在一个Button,这使我的问题更加复杂,这意味着除非我将OnClickListener附加到自定义适配器中(此部分已完成),否则Button将不可单击。 Now, trying to store the position of the Button's list item fails because the saved position is always a refreshed position and not the absolute position of the list item. 现在,尝试存储Button列表项的位置失败,因为保存的位置始终是刷新的位置,而不是列表项的绝对位置。 I also tried setting tags for each button but even those get recycled as the page scrolls, which is (unfortunately) expected behaviour considering the design of ListView. 我还尝试为每个按钮设置标签,但是即使标签在滚动时也会被回收,考虑到ListView的设计,这是(不幸的)预期行为。

I understand that this problem is easily solvable if the a list item does not have children that need to be clicked. 我知道,如果列表项中没有需要单击的子项,则可以轻松解决此问题。 But what if there are children within every list item that need to respond to clicks separate from the parent view that contains each list item ? 但是,如果每个列表项中都有需要响应点击的子项,而不是包含每个列表项的父视图,该怎么办? I have also tried using selectors to manipulate a list item's background but that hasn't helped either. 我也尝试过使用选择器来操纵列表项的背景,但这也无济于事。

Here is my Custom Adapter's getView method: 这是我的自定义适配器的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;
}

And the XML layout file: 和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> 

I have spent many hours on this problem and I am unable to arrive at a solution. 我已经花了很多时间解决这个问题,但我无法找到解决方案。 Any direction, guidance or a solution would be most appreciated. 任何方向,指导或解决方案将不胜感激。

In your Custom Adapter's getView() method, you are inflating the view and attaching the onclicklistener only if the convertView is null. 在自定义适配器的getView()方法中,仅当convertView为null时,才扩大视图并附加onclicklistener。 convertView IS the recycled view. convertView是回收的视图。 If convertView is not null, then you need to change the values in that view. 如果convertView不为null,则需要更改该视图中的值。 Your getView() method should be like this instead 您的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;
    }

Indeed you should also be changing any values associated with that item according to that position , if they change. 实际上,如果更改了与该项目相关联的任何值,那么您也应该根据该position更改。 For example, if each button displays the position in the list, you should also add the following line 例如,如果每个button在列表中显示位置,则还应添加以下行

button.setText("Button " + position);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM