当按钮被按下一次时,我该如何更改文本颜色(Android)

3

我想做的基本上就是这样: 当我点击按钮时,我希望它的文字颜色出现不同的颜色。 我尝试的方法是:

<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:color="@color/red" />
    <item
        android:state_pressed="false"
        android:color="#000" />
</selector>

然后我将此选择器用作按钮android:textColor上的可绘制对象

但这并不能解决它,因为它只在我按下按钮时更改其颜色。 我想要像这样:

默认:黑色 点击时:蓝色 再次点击:黑色

有什么想法吗?:S

这是我的按钮形状(如果有影响):

<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:insetBottom="-1dp"
    android:insetLeft="-1dp"
    android:insetRight="-1dp">
    <selector>
        <item android:state_pressed="false">
            <shape android:shape="rectangle" >
                <corners
                    android:radius="0dp"
                    />
                <solid
                    android:color="@color/background_grey"
                    />
                <padding
                    android:left="0dp"
                    android:top="0dp"
                    android:right="0dp"
                    android:bottom="0dp"
                    />
                <size
                    android:width="100dp"
                    android:height="30dp"
                    />
                <stroke
                    android:width="1dp"
                    android:color="#ffb4b4b4"
                    />
            </shape>
        </item>

        <item android:state_pressed="true">
            <shape android:shape="rectangle" >
                <corners
                    android:radius="0dp"
                    />
                <solid
                    android:color="@color/pq_blue"
                    />
                <padding
                    android:left="0dp"
                    android:top="0dp"
                    android:right="0dp"
                    android:bottom="0dp"
                    />
                <size
                    android:width="100dp"
                    android:height="30dp"
                    />
                <stroke
                    android:width="1dp"
                    android:color="#ffb4b4b4"
                    />
            </shape>
        </item>
    </selector>
</inset>

谢谢您提前的帮助。

编辑

所以我尝试以编程方式实现它,并尝试以下内容,只是为了查看是否更改颜色,但是它似乎不起作用(我的onClick事件似乎无效):

 @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.listview_item, container, false);



    final Button likeButton = (Button)rootView.findViewById(R.id.btLike);
    likeButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            String test = "tester";
            if(BUTTON_STATE==BUTTON_STATE_ONCE){

                likeButton.setTextColor(getResources().getColor(R.color.pq_blue));
                BUTTON_STATE = BUTTON_STATE_TWICE;
            }else{
                likeButton.setTextColor(getResources().getColor(R.color.red));
                BUTTON_STATE = BUTTON_STATE_ONCE;
            }

        }
    });
    return rootView;
}

注意:我在我的ActionBarActivity(带有选项卡)的Fragment中使用onCreateView完成所有这些操作,如果我在onCreate中这样做,我会在findViewById处得到空指针异常(因为它会在我的MainActivity中搜索ID,对吗?)

所以,有什么建议吗?


2
如果您想要这样的行为,您必须通过编程来实现。选择器无法获取第二次或第三次点击的状态。 - Opiatefuchs
你不想通过编程来完成吗? - Skizo-ozᴉʞS ツ
可能是Android:更改点击时的字体颜色的重复问题。 - Ameer
好的,谢谢。所以我真的需要通过编程来完成它。有没有一种常见/简单的方法来做到这一点?或者只需在onClickListner中处理它,改变颜色并设置一些状态/标志,以便它知道它改变了颜色。然后如果(状态)就将颜色改回正常? - zooky
顺便问一下,android:state_focused 是什么时候被触发的?state_focused 和 state_pressed 有什么区别? - zooky
显示剩余4条评论
6个回答

2
您的 textselector.xml 文件 -
<selector
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:color="@color/red" /> <!--selected text colour-->
    <item
        android:state_focused="true"
        android:color="@color/red" />
    <item            
        android:color="@color/blue" /> <!--unselected text colour-->
</selector>

您在layout.xml文件中的按钮 -

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Exit"
    android:textColor="@drawable/textselector" <!-- SET textselector HERE -->
    android:background="@drawable/button_color"/>

如果单击另一个视图,按钮将失去焦点状态,因此文本颜色将恢复为黑色,即使不点击第三次也是如此... - Opiatefuchs

1
您可以使用以下代码进行编程实现:

myButton.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View arg0) {
        // TODO Auto-generated method stub
        ColorStateList myList=myButton.getTextColors();
        int myColor=myList.getDefaultColor();
        switch(myColor)
        {
            case Color.BLACK:
            myButton.setTextColor(Color.BLUE);
            break;

            case Color.BLUE:
            myButton.setTextColor(Color.BLACK);
            break;

       }
   }
});

但是,使用getDefaultColor()不是这样吗?因为在选择器中将其设置为默认值,所以您始终会得到黑色的颜色?因此,开关状态将无法获取正确的状态... - Opiatefuchs
1
我刚刚测试了一下,对我来说它是可以工作的。当然,我的样式表中没有那个 XML 样式,并且请注意 getTextColors(); 获取当前颜色而不是 getDefaultColor();。 - Morteza
好的,但是在API中它被定义为:“获取不同状态(正常,选定,聚焦)的文本颜色...”。这对我来说意味着所有使用的颜色都将包含在ColorStateList中,包括默认值,是吗? - Opiatefuchs
getDefaultColor();返回此ColorStateList中的默认颜色,而不是唯一的原始颜色,因此当以编程方式更改按钮的颜色而不指定状态(按下、聚焦等)时,它将变为默认颜色。 - Morteza
啊,你是指在 XML 布局中定义的按钮默认颜色,而不是选择器颜色? - Opiatefuchs

1
如果您想要实现以下行为:
  • 第一次点击:按钮文字变为黑色
  • 第二次点击:按钮文字变为蓝色
  • 第三次点击:按钮文字再次变为黑色
我认为这不可能通过选择器来实现,也不能通过状态 focused 来实现。因为如果点击其他视图,按钮就不再处于焦点状态,并且将失去文本颜色,回到默认状态。您必须以编程方式实现:
首先,在您的 xml 中将默认文本颜色设置为您想要的颜色:黑色。这样,当未按下时,文本颜色就是该颜色。然后创建一个全局变量来保存状态。
 private int BUTTON_STATE = 0;
 private final int BUTTON_STATE_ONCE = 0;
 private final int BUTTON_STATE_TWICE = 1;



     button.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View view) {

          if(BUTTON_STATE==BUTTON_STATE_ONCE){

            button.setTextColor(Color.BLUE);
            BUTTON_STATE = BUTTON_STATE_TWICE;
          }else if(BUTTON_STATE==BUTTON_STATE_TWICE){

            button.setTextColor(Color.BLACK);
            BUTTON_STATE = BUTTON_STATE_ONCE;
          }

        }

    });

那只是一个可能的解决方案,有很多种方法。

编辑

对于你的代码:

像我在上面的示例中所做的那样创建全局变量,并在if/else语句中使用它们:

    likeButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {

           if(BUTTON_STATE==BUTTON_STATE_ONCE){

        likeButton.setTextColor(getResources().getColor(R.color.pqBlue));
        BUTTON_STATE = BUTTON_STATE_TWICE;
      }else if(BUTTON_STATE==BUTTON_STATE_TWICE){

        likeButton.setTextColor(getResources().getColor(R.color.pqBlack));
        BUTTON_STATE = BUTTON_STATE_ONCE;
      }

    }
});

不,你必须将这些变量设为全局变量,而不是在类内部。 - Opiatefuchs
我也尝试过,但是出现了这个错误:无法从静态内容引用非静态字段BUTTON_STATE。我在以下几行代码中遇到了这个问题:if(BUTTON_STATE==BUTTON_STATE_ONCE)、BUTTON_STATE = BUTTON_STATE_TWICE;以及BUTTON_STATE = BUTTON_STATE_ONCE; 假设我只想改变一次颜色,那么只需要使用setTextColor(...)就可以了,对吗?但是这也不起作用,是因为“final”吗?-> final button likeButton... - zooky
你可以将这些变量声明为静态的,例如:private static int BUTTON_STATE = 0; - Opiatefuchs
好的,我已经做了那个...还是不行。似乎它甚至没有跳转到我的onClick函数 :O 需要找出问题所在...如果你想的话,可以看一下。我会更新我的第一个帖子。 - zooky
你是我的英雄。你的解决方案刚刚救了我的命。@Opiatefuchs 非常感谢你,如果可能的话,我会给你10个赞..哈哈 - ken
显示剩余8条评论

0

尝试添加text_effect.xml drawable

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_pressed="true"
           android:color="@color/white" /> <!-- pressed -->    
     <item android:color="@color/black" /> <!-- default -->
 </selector>

将此行添加到按钮控件中。
android:textColor="@drawable/text_effect"

它会工作的。享受吧:)


0

如果您不是必须需要一个简单的按钮,您可以使用一个专门用于二进制状态处理的ToggleButton... 使用ToggleButton后,您的选择器将如下所示:

<?xml version="1.0" encoding="utf-8"?>
   <selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_checked="true" android:color="@color/red" />
   <!-- Default State -->
   <item android:color="#000" />
</selector>

0

看起来你想实现像切换按钮一样的东西。 可以使用切换按钮代替按钮。 不过如果你只想使用按钮,那么你需要在Java代码和XML代码中进行一些更改。

创建一个名为 def_btn.xml 的文件,它应该长这样...

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle" >
            <corners
                android:radius="0dp"
                />
            <solid
                android:color="@color/background_grey"
                />
            <padding
                android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp"
                />
            <size
                android:width="100dp"
                android:height="30dp"
                />
            <stroke
                android:width="1dp"
                android:color="#ffb4b4b4"
                />
        </shape>

创建另一个名为press_btn.xml的文件,它应该长这样...
    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
           android:shape="rectangle" >
            <corners
                android:radius="0dp"
                />
            <solid
                android:color="@color/pq_blue"
                />
            <padding
                android:left="0dp"
                android:top="0dp"
                android:right="0dp"
                android:bottom="0dp"
                />
            <size
                android:width="100dp"
                android:height="30dp"
                />
            <stroke
                android:width="1dp"
                android:color="#ffb4b4b4"
                />
        </shape>

在您的活动中声明一个私有布尔变量(假设为isPressed),默认情况下isPressed为false。对于默认按钮背景,将使用def_btn.xml。
现在在按钮的onClick事件中编写以下内容。
    btn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            isPressed = !isPressed;

            if(isPressed){
                btn.setBackgroundResource(R.drawable.def_btn);
            }else{
                btn.setBackgroundResource(R.drawable.press_btn);
            }
        }
    });

就是这样。


我不想在我的文本下面有切换按钮。而且,切换按钮总是在文本下方显示一个“条”,不是吗? - zooky

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