多个视图的 state_pressed 背景,onClick

发布于 2024-11-07 09:35:24 字数 3189 浏览 6 评论 0原文

如何在单击任意一个视图时同时在多个View上实现android:background更改效果?

注意内容有所不同

我得到了一个分为两部分的“徽章”布局。它们的作用就像一个按钮,但两个部分具有不同的 StateListDrawable (选择器),为 state_pressed 等定义背景。第一部分是带有图像的标题(“lefter”) 。第二个是充满各种子内容的内容区域。 这一切都归结为两个部分的内容都有不同的尺寸。

我希望两个徽章部分分别拉伸,并在按下其中任何一个时共享共同的背景效果。

<LinearLayout
    style="@style/Badge">

    <!-- LEFTER -->
    <LinearLayout
            style="@style/BadgeLefter"
            android:background="@drawable/badge_lefter_bg_blue">
            <ImageView
                    style="@style/BadgeLefterImage"
                    android:src="@drawable/office_building"/>
    </LinearLayout>

    <!-- CONTENT -->
    <LinearLayout
            android:id="@+id/badge_blue_content"
            style="@style/BadgeContent"
            android:background="@drawable/badge_content_bg_blue">
    </LinearLayout> 
</LinearLayout>

StateListDrawable 背景选择器示例(如上面的 @drawable/badge_content_bg_blue):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_pressed="false"
    android:drawable="@drawable/badge_bg_blue_normal"/>
<item android:state_focused="false" android:state_pressed="true"
    android:drawable="@drawable/badge_bg_blue_pressed"/>
<item android:state_focused="true"
    android:drawable="@drawable/badge_bg_blue_focused"/>
<item android:state_focused="true" android:state_pressed="true"
    android:drawable="@drawable/badge_bg_blue_pressed"/>
</selector>

其中 badge_bg_blue_normal 等是 9-patch png。

我是安卓新手。我在这里找不到类似的问题。自定义我自己的 Button 没有帮助,因为按钮只有一个 android:background selector。我发现没有 9 片支持多个可拉伸区域。我意识到我可以构建一个自定义组件。这是个好主意吗?

我在应用程序中广泛使用我的徽章。一个优雅的解决方案将不胜感激! :)

* 解决方案编辑:*

使用 TouchListener 构建自定义组件后,我已准备就绪:^_^

public class Badge extends LinearLayout {
    //...
    public Badge(Context c, AttributeSet attrs) {
        super(c, attrs);
        //... 
        // inflating layouts and setting selector backgrounds here
        //... 
        setClickable(true);
        setOnTouchListener(new OnTouchListener() {

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

                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    lefter.setPressed(true);
                    contents.setPressed(true);
                }
                else if (event.getAction() == MotionEvent.ACTION_UP || !isInside(v, event)) {
                    lefter.setPressed(false);
                    contents.setPressed(false);
                }
                return false;
            }

            private boolean isInside(View v, MotionEvent event) {
                //...
            }
        });
   }
   //...
}

How to achieve an android:background change effect on multiple Views at the same time, on clicking any of them?

Note that contents vary

I got a "badge" layout in two parts. They act like one button, but the two parts have different StateListDrawable (selectors) defining backgrounds for state_pressed etc. The first part is a header ("lefter") with an image. The second is a content area getting filled with various sub-contents. It all comes down to that the contents of the both parts both come in various sizes.

I want the two badge parts to stretch separately AND share a common background effect when any of them is pressed.

<LinearLayout
    style="@style/Badge">

    <!-- LEFTER -->
    <LinearLayout
            style="@style/BadgeLefter"
            android:background="@drawable/badge_lefter_bg_blue">
            <ImageView
                    style="@style/BadgeLefterImage"
                    android:src="@drawable/office_building"/>
    </LinearLayout>

    <!-- CONTENT -->
    <LinearLayout
            android:id="@+id/badge_blue_content"
            style="@style/BadgeContent"
            android:background="@drawable/badge_content_bg_blue">
    </LinearLayout> 
</LinearLayout>

Example of StateListDrawable background selector (like @drawable/badge_content_bg_blue above):

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="false" android:state_pressed="false"
    android:drawable="@drawable/badge_bg_blue_normal"/>
<item android:state_focused="false" android:state_pressed="true"
    android:drawable="@drawable/badge_bg_blue_pressed"/>
<item android:state_focused="true"
    android:drawable="@drawable/badge_bg_blue_focused"/>
<item android:state_focused="true" android:state_pressed="true"
    android:drawable="@drawable/badge_bg_blue_pressed"/>
</selector>

where badge_bg_blue_normal etc are 9-patch png's.

I'm new to android. I failed to find a similar question here. It does not help to custom my own Button because buttons only have one android:background selector. I found no 9-patch supporting multiple stretchable areas. I realize I could build a custom component. Is that a good idea here?

I use my badges widely around the app. An elegant solution would be greatly appreciated!
:)

* SOLUTION EDIT: *

After building a custom component with a TouchListener I'm all set: ^_^

public class Badge extends LinearLayout {
    //...
    public Badge(Context c, AttributeSet attrs) {
        super(c, attrs);
        //... 
        // inflating layouts and setting selector backgrounds here
        //... 
        setClickable(true);
        setOnTouchListener(new OnTouchListener() {

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

                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    lefter.setPressed(true);
                    contents.setPressed(true);
                }
                else if (event.getAction() == MotionEvent.ACTION_UP || !isInside(v, event)) {
                    lefter.setPressed(false);
                    contents.setPressed(false);
                }
                return false;
            }

            private boolean isInside(View v, MotionEvent event) {
                //...
            }
        });
   }
   //...
}

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

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

发布评论

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

评论(1

那片花海 2024-11-14 09:35:25

如果我正确理解你的问题,你有两个按钮,按下其中一个按钮后,它们都应该表现得像被按下一样?

按下其中一个按钮后,您是否尝试调用另一个按钮上的 View.setPressed(bool) 函数,等等?如果我有像上面这样的设计,我就会从这里开始。如果这不起作用,另一种方法可能是在按下其中一个按钮时简单地切换所有按钮上的背景可绘制,并且不使用内置的 state_pressed 功能。

对于在多个区域可拉伸的 9-patch,您可以使用 android SDK 中包含的 9-patch-tool 来实现。我用一个我自己制作的按钮来做到这一点,该按钮有一个静态中心区域(垂直)和两个上下可拉伸区域。

If I understand your question correctly, you have two buttons, and upon pressing one of them, both of them should behave like they are being pressed?

Upon pressing one of the buttons, did you try to call the View.setPressed(bool) function on the other one, and so on? That's where I would start if I had design like yours above. If that doesn't work, another approach could be to simply switch the background drawable on all buttons when pressing one of them, and simply not use the built-in state_pressed functionality.

Regarding 9-patches that are stretchable in multiple areas, you can achieve this using the 9-patch-tool included in the android SDK. I did it with a button I made myself which had a static center area (vertically) and two stretchable areas above and below.

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