改变的 GradientDrawable 在不同的地方被不必要地重复使用

Posted

技术标签:

【中文标题】改变的 GradientDrawable 在不同的地方被不必要地重复使用【英文标题】:Altered GradientDrawable gets unwantedly reused in different places 【发布时间】:2015-12-16 00:25:02 【问题描述】:

我有一个 ShapeDrawable drawable/my_shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
   android:shape="rectangle">
    <solid
       android:color="#FFFF00" />
    <padding android:left="1dp"
        android:top="1dp"
        android:right="1dp"
        android:bottom="1dp" />
</shape>

我在我的应用程序的几个地方将其用作一些TextViews 的背景。就像 layout/my_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout...>
    <TextView
        android:id="@+id/tag"
        android:background="@drawable/my_drawable"
        android:layout_
        android:layout_
        android:text="Some text"
    />
<!-- other tags -->
</RelativeLayout>

或在用作列表项的布局中layout/my_list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout...>
    <TextView
        android:id="@+id/subject"
        android:background="@drawable/my_drawable"
        android:layout_
        android:layout_
    />
<!-- other tags -->
</RelativeLayout>

现在,当我在列表的ArrayAdapter 内以编程方式更改形状的颜色时,TextView我的应用程序中完全不同的位置 的片段内的背景会得到与我列表中的最后一项颜色相同!从那时起,颜色改变的形状被用于布局中包含 my_fragment.xml 的所有其他活动。

holder.subject = (TextView) v.findViewById(R.id.subject);

GradientDrawable bgShape = (GradientDrawable)holder.subject.getBackground();
bgShape.setColor( position % 2 == 0 ? Color.BLACK : Color.WHITE );

这怎么可能?如何避免这种“重用”行为?

这是我的数组适配器的代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) 
    View v = convertView;
    ViewHolder holder; // to reference the child views for later actions

    if (v == null) 
        LayoutInflater vi = 
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.my_list_item, null);
        // cache view fields into the holder
        holder = new ViewHolder();
        holder.subject = (TextView) v.findViewById(R.id.subject);
        // associate the holder with the view for later lookup
        v.setTag(holder);
    
    else 
        // view already exists, get the holder instance from the view
        holder = (ViewHolder) v.getTag();
    

    GradientDrawable bgShape = (GradientDrawable)holder.subject.getBackground();
    bgShape.setColor( position % 2 == 0 ? Color.BLACK : Color.WHITE );
    holder.subject.setText(getItem(position));


// somewhere else in your class definition
static class ViewHolder 
    TextView subject;

【问题讨论】:

我的印象是,mutate 可以解决我的问题***.com/questions/7979440/… 【参考方案1】:

我必须使用bgShape.mutate().setColor(..)

另见

Android: Cloning a drawable in order to make a StateListDrawable with filters http://developer.android.com/reference/android/graphics/drawable/Drawable.html#mutate%28%29

【讨论】:

以上是关于改变的 GradientDrawable 在不同的地方被不必要地重复使用的主要内容,如果未能解决你的问题,请参考以下文章

在代码中设置形状资源 / GradientDrawable 的填充

JAVA代码设置selector不同状态下的背景颜色

GradientDrawable.setCornerRadii 的剪辑不起作用

GradientDrawable 获取单一颜色

GradientDrawable 获取单一颜色

GradientDrawable 获取单一颜色