如何动态地将按下颜色更改为选择器的其他颜色?

4
这是我的列表选择器(item_selector.xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@color/orange" />
    <item android:state_focused="true" android:drawable="@color/orange" />
    <item android:state_pressed="true" android:drawable="@color/orange" />
    <item android:drawable="@color/transparent" />
</selector>

这是我的列表行(row_item.xml):
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/alarm_item_drawer_selector"
    >

    <ImageView 
        android:id="@+id/item_icon"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_centerHorizontal="true"
        android:paddingTop="5dp"
        android:paddingBottom="2dp"
        android:src="@drawable/ic_launcher"/>

    <TextView      
        android:id="@+id/item_title"
        style="@style/DrawerItemTextStyle"
        android:textColor="@color/text_drawer_item_selector"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/item_icon" />

</RelativeLayout>

我希望能够动态更改android:state_pressed="true" android:drawable="@color/orange"的颜色。我的目标是使每一行的按下颜色不同。这是否可能实现?


1
你可能需要使用setOnItemClickListener来处理项目的点击事件,在该代码中你可以在选中时更改项目的颜色。 - Saqib
我更喜欢在getView内部改变颜色。 我猜它看起来像这样:
  1. 获取View的选择器
  2. 更改按下状态的颜色
  3. 将其应用回去
- user1711993
4个回答

9
为每个项目分配一个新的StateListDrawable。
    StateListDrawable stateListDrawable= new StateListDrawable();
    stateListDrawable.addState(new int[] {android.R.attr.state_pressed}, new ColorDrawable(getContext().getResources().getColor(R.color.anycolor)));
    stateListDrawable.addState(new int[] {android.R.attr.state_focused}, new ColorDrawable(getContext().getResources().getColor(R.color.anycolor)));
    stateListDrawable.addState(new int[] {android.R.attr.state_selected}, new ColorDrawable(getContext().getResources().getColor(R.color.anycolor)));
    stateListDrawable.addState(new int[] {}, new ColorDrawable(getContext().getResources().getColor(R.color.anycolor)));

    view.setBackgroundDrawable(stateListDrawable);

1
我在我的项目中所做的是创建了一个静态方法,该方法可以将任何视图更改为我制作的六个不同颜色选择器之一的背景。 关键在于不要尝试更改listview选择器,而是要更改listview布局的父布局的背景。
以下是例子: listview.xml(listview的实际内容)
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/parent"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textColor="@android:color/white"
    android:id="@+id/text"
    android:text="Text"
    android:padding="20dp"/>

</LinearLayout>

我适配器中的 getView() 方法:
@Override
public View getView(int i, View view, ViewGroup viewGroup) {

    Holder holder = new Holder();
    if (view == null) {
        LayoutInflater inflater = LayoutInflater.from(context);
        view = inflater.inflate(R.layout.listview, viewGroup, false);
    } else {

        holder = (Holder) view.getTag();
    }

    holder.parent = (LinearLayout) view.findViewById(R.id.parent);
    setRandomListViewSelector(holder.parent);
    holder.text = (TextView) view.findViewById(R.id.text);
    holder.text.setText(strs.get(i));

    return view;
}

改变背景的静态方法:

public static void setRandomListViewSelector(View parentView) {

        int i = new Random().nextInt(2);

        switch (i) {
            case 0:
                parentView.setBackgroundResource(R.drawable.list_selector_blue);
                break;

            case 1:
                parentView.setBackgroundResource(R.drawable.list_selector_red);
                break;
       }

}

list_selector_blue.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
    <shape>
        <solid android:color="@android:color/holo_blue_dark"/>
    </shape>
</item>
</selector>

在我的例子中,我只是使用Random类来随机生成0到1之间的数字。如果你想要更多的控制,你可以创建一个全局变量并将其增加1,这样你就可以更好地控制设置什么背景颜色了。

0
如果您想动态更改它,您将不得不通过代码来实现。为此,您将需要使用onTouchListener,因为您想知道何时在视图上触摸和释放。
    final TextView textView =findViewById(R.id.item_title);
    textView.setOnTouchListener(new View.OnTouchListener()
    {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent)
        {
            switch (motionEvent.getAction()){
                case MotionEvent.ACTION_DOWN:
                    textView.setTextColor(Color.RED);
                    break;
                case MotionEvent.ACTION_UP:case MotionEvent.ACTION_CANCEL:
                    textView.setTextColor(Color.BLACK);
                    break;
            }
            return false;
        }
    });

当你按下它时,上述代码将更改文本视图的文本颜色。将Color.RED更改为您想要的颜色。


谢谢Pedro!但我有一个问题,这种方式是否可行?
  1. 获取视图选择器 2. 更改按下状态的颜色 3. 将其应用回去。
- user1711993
我曾尝试在点击监听器中动态更改颜色,但这不是正确的解决方案:( 我是Android开发的新手,我的目标是学会正确的方法。 - user1711993
你无法在点击监听器上完成它,因为它不能告诉你当你释放按钮时发生了什么。 - Pedro Oliveira
关于第一个问题。那不是正确的方法,但请查看此链接:https://dev59.com/QWXWa4cB1Zd3GeqPNoIb - Pedro Oliveira
Pedro,你最后提供的链接很好。我会等待其他答案一段时间,如果我没有得到更好的解决方案,我会将你的帖子标记为解决方案。 - user1711993
@user1711993 阅读 StateListDrawable 文档,不要使用任何 setOnTouchListener,这不是它应该工作的方式。 - pskink

0

选择器标签的类型为StateListDrawable。索引从零开始。有一个Kotlin示例(在Android 8.1上测试过)

val listDrawable = relativeLayout.background as StateListDrawable
val stateDrawable = listDrawable.getStateDrawable(2) as GradientDrawable // android:state_pressed="true" android:drawable="@color/orange"
stateDrawable.setColor(0xff00ff00)
// or stateDrawable.setColor(Color.parseColor("#00ff00")
// or stateDrawable.setColor(Color.GREEN)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接