android 按钮 setPressed 在 onClick 后

发布于 2024-11-07 09:36:34 字数 440 浏览 4 评论 0原文

昨天我注意到可以通过兼容性包将片段集成到较旧的 API 级别中,但这对于这个问题来说并不是真正重要的。 :)

我有一个带有 OnClickListener 的按钮

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        doSomething();
        button.setPressed(true);
    }
});

由于实际单击,它显示为按下状态,释放单击后,按钮状态未按下并保持这种状态。

有没有一种简单的方法可以在释放按钮后保持按下状态? 我首先想到的是某种计时器,但这似乎不合理。

yesterday I noticed the possibility to integrate Fragments in older API Levels through the Compatibility package, but thats not really essential for the question. :)

I have a Button with an OnClickListener

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        doSomething();
        button.setPressed(true);
    }
});

Because of the actual clicking, it is shown as pressed and after releasing the click, the button state is not pressed and stays that way.

Is there a simple way that keeps the button state pressed after releasing?
First thing I can think of would be some sort of timer, but that seems unreasonable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

无人问我粥可暖 2024-11-14 09:36:35

这是我使用的解决方案,目前它也适用于 android 7.0。

YourActivity.java

public void onStandbyStart(String message) {
    startStandbyBtn.setActivated(true);
}

public void onBackOnline(String message) {
    startStandbyBtn.setActivated(false);
}

YourActivityLayout

<Button
        ...
        style="@style/generic_btn_style"
        ... />

values/styles.xml

    <style name="generic_btn_style" parent="@android:style/Widget.Button">
        <item name="android:gravity">center_vertical|center_horizontal</item>
        <item name="android:background">@drawable/generic_btn</item>
        <item name="android:textColor">@color/selector_white_black</item>
        <item name="android:focusable">true</item>
        <item name="android:clickable">true</item>
</style>

drawable/generic_btn.xml
该选择器选择按钮背景。我使用按下作为激活。

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/generic_btn_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" />
    <item android:drawable="@drawable/generic_btn_pressed" android:state_activated="true" />
    <item android:drawable="@drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" />
    <item android:drawable="@drawable/generic_btn_enabled" android:state_enabled="true" />
</selector>

颜色/selector_black_white
这里我设置了文字颜色。就我而言,我需要在按下时选择黑色文本颜色。

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

This is the solution I used, It also works on android 7.0 at the moment.

YourActivity.java

public void onStandbyStart(String message) {
    startStandbyBtn.setActivated(true);
}

public void onBackOnline(String message) {
    startStandbyBtn.setActivated(false);
}

YourActivityLayout

<Button
        ...
        style="@style/generic_btn_style"
        ... />

values/styles.xml

    <style name="generic_btn_style" parent="@android:style/Widget.Button">
        <item name="android:gravity">center_vertical|center_horizontal</item>
        <item name="android:background">@drawable/generic_btn</item>
        <item name="android:textColor">@color/selector_white_black</item>
        <item name="android:focusable">true</item>
        <item name="android:clickable">true</item>
</style>

drawable/generic_btn.xml
This selector chooses the button background. I use the pressed as the activated.

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/generic_btn_disabled" android:state_enabled="false" />
    <item android:drawable="@drawable/generic_btn_pressed" android:state_enabled="true" android:state_pressed="true" />
    <item android:drawable="@drawable/generic_btn_pressed" android:state_activated="true" />
    <item android:drawable="@drawable/generic_btn_focused" android:state_enabled="true" android:state_focused="true" />
    <item android:drawable="@drawable/generic_btn_enabled" android:state_enabled="true" />
</selector>

color/selector_black_white
Here I set the text color. In my case, I need to pick the textcolor black when pressed.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#fff" android:state_pressed="true" /> <!-- pressed -->
    <item android:color="#fff" android:state_activated="true" /> <!-- pressed -->
    <item android:color="#000" /> <!-- default -->
</selector>
如梦亦如幻 2024-11-14 09:36:34

请注意,这是因为 Android 在 onClickEvent 之前和之后都更改了 setPressed,因此您自己更改它没有效果。解决这个问题的另一种方法是使用onTouchEvent

button.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        // show interest in events resulting from ACTION_DOWN
        if (event.getAction() == MotionEvent.ACTION_DOWN) return true;

        // don't handle event unless its ACTION_UP so "doSomething()" only runs once.
        if (event.getAction() != MotionEvent.ACTION_UP) return false;

        doSomething();
        button.setPressed(true);                    
        return true;
   }
});

Just to note this is because Android is changing the setPressed both before and after your onClickEvent, so changing it yourself has no effect. Another way to get around this is to use the onTouchEvent.

button.setOnTouchListener(new OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        // show interest in events resulting from ACTION_DOWN
        if (event.getAction() == MotionEvent.ACTION_DOWN) return true;

        // don't handle event unless its ACTION_UP so "doSomething()" only runs once.
        if (event.getAction() != MotionEvent.ACTION_UP) return false;

        doSomething();
        button.setPressed(true);                    
        return true;
   }
});
栩栩如生 2024-11-14 09:36:34

使用 ToggleButton 而不是 Button

<ToggleButton
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:background="@drawable/topping_selector"
    android:checked="false"
    android:textOff="Topping2"
    android:textOn="Topping2" />

topping_selector.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_checked="true" 
        android:drawable="@drawable/btn_topping_on" />

    <item android:state_checked="false" 
        android:drawable="@drawable/btn_topping_off" />

</selector>

Use ToggleButton instead of Button.

<ToggleButton
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:background="@drawable/topping_selector"
    android:checked="false"
    android:textOff="Topping2"
    android:textOn="Topping2" />

topping_selector.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:state_checked="true" 
        android:drawable="@drawable/btn_topping_on" />

    <item android:state_checked="false" 
        android:drawable="@drawable/btn_topping_off" />

</selector>
走野 2024-11-14 09:36:34

您可以将按钮状态保存在drawable文件夹下的xml文件中,然后用作按钮的背景。
例如:

 android:background="@drawable/buttonstate"

buttonstate.xml

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

You can keep the button states in xml file under drawable folder, then used as background for button.
For example:

 android:background="@drawable/buttonstate"

buttonstate.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@drawable/back_focused" />
    <item android:drawable="@drawable/back" /> <!-- default -->
</selector>
像你 2024-11-14 09:36:34

更好的解决方案:

在 xml 文件中:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_activated="true">
        <bitmap android:src="@drawable/image_selected"/>
    </item>
    <item>
        <bitmap android:src="@drawable/image_not_selected"/>
    </item>
</selector>

在 java 中:

@Override
public void onClick(View v) {
   v.setActivated(!v.isActivated());
}

Better solution:

In xml file:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_activated="true">
        <bitmap android:src="@drawable/image_selected"/>
    </item>
    <item>
        <bitmap android:src="@drawable/image_not_selected"/>
    </item>
</selector>

And in java:

@Override
public void onClick(View v) {
   v.setActivated(!v.isActivated());
}
夕嗳→ 2024-11-14 09:36:34

您可以使用 android.os.Handler 类。丑陋,但也有效:

final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        doSomething();
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                button.setPressed(true);
            }
        });
    }
});

You can use android.os.Handler class. Ugly, but works also:

final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        doSomething();
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                button.setPressed(true);
            }
        });
    }
});
诠释孤独 2024-11-14 09:36:34

另一种解决方案是扩展 Button 并重写 setPressed(boolean Pressed) 方法,以便您可以使用标志处理来自 onClickEvent 的平台调用,例如根据您的需要更改布尔按下参数。

public class MyButton extends Button {
   boolean isSelected = false;  //this is your flag
   @Override
   public void setPressed(boolean pressed) {
       if(isSelected) {
           //here you change the parameter so it stays pressed
           super.setPressed(true);
           return;
       }
       super.setPressed(pressed);
   }

   public void setIsSelected(boolean selected) {
       this.isSelected = selected;
   }

   public MyButton(Context context) {
       super(context);
   }
}

Another solution is to extend Button and override setPressed(boolean pressed) method so you can handle platform calls from the onClickEvent using a flag, for example changing the boolean pressed parameter depending on your needs.

public class MyButton extends Button {
   boolean isSelected = false;  //this is your flag
   @Override
   public void setPressed(boolean pressed) {
       if(isSelected) {
           //here you change the parameter so it stays pressed
           super.setPressed(true);
           return;
       }
       super.setPressed(pressed);
   }

   public void setIsSelected(boolean selected) {
       this.isSelected = selected;
   }

   public MyButton(Context context) {
       super(context);
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文