通过从左到右填充来更改按钮背景 [英] Change button background by filling it left to right

查看:85
本文介绍了通过从左到右填充来更改按钮背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在按下按钮的同时改变其背景,就像水平进度条一样从左到右填充颜色.

I want to change the background of a button while being pressed by filling it a color from left to right just like a horizontal progress bar.

这是检测按下状态的代码:

This is the code for detecting press-hold:

lateinit var buttonView: View
val cdt = object : CountDownTimer(1000, 100) {
            override fun onTick(millisUntilFinished: Long) {

            }

            override fun onFinish() {
                //do something after being press by 1 sec.
            }
        }

        val onTouchListener = View.OnTouchListener { v, event ->
            buttonView = v
            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    (v.background as AnimationDrawable).start()
                    cdt.start()
                }
                MotionEvent.ACTION_UP -> {
                    (v.background as AnimationDrawable).stop()
                    cdt.cancel()
                }

            }
            false
        }

这是我用于按钮的背景:

This is the background I used for the button:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    ...items with drawables which colors are in different position. Frame by frame....
</animation-list>

这有效,但并不顺利.有办法有效地做到这一点吗?像这样? https://codepen.io/kay8/pen/azKbjN
(可以用Java回答)

This works but it ain't smooth. Is there a way to do this efficiently? Just like this? https://codepen.io/kay8/pen/azKbjN
(It's okay to answer in Java)

推荐答案

对于可绘制对象,我将使用 LayerDrawable .这将在视觉上像进度条一样工作.

For the drawable, I would go with a ClipDrawable as the top layer in a LayerDrawable. This will visually work like a progress bar.

在以下可绘制对象中,剪辑可绘制对象覆盖了仅一个红色矩形的底层.

In the following drawable, the clip drawable overlays a bottom layer that is just a red rectangle.

button_background.xml

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/holo_red_light" />
        </shape>
    </item>
    <item android:id="@+id/clip_drawable">
        <clip
            android:clipOrientation="horizontal"
            android:gravity="start">
            <shape
                android:shape="rectangle">
                <solid android:color="@android:color/black" />
            </shape>
        </clip>
    </item>
</layer-list>

随着剪贴画的级别从0(未显示)增加到10,000(覆盖红色矩形的100%),剪贴画的黑色将超过红色矩形.

The black of the clip drawable will eclipse the red rectangle as the level of the clip drawable increases from 0 (not shown) to 10,000 (100% covering the red rectangle.)

TimeAnimator 可用于为可绘制剪辑的水平设置动画

TimeAnimator can be used to animate the level of the clip drawable.

此类为侦听器提供了一种简单的回调机制,该机制与系统中的所有其他动画制作器保持同步.

This class provides a simple callback mechanism to listeners that is synchronized with all other animators in the system.

这里是一个快速演示.如果要设置动画的持续时间,可以更改onTimeUpdate()以对总时间和经过时间敏感.

Here is a quick demo. You can change onTimeUpdate() to be sensitive to total and elapsed time if you want to set the duration of the animation.

MainActivity.java

public class MainActivity extends AppCompatActivity implements TimeAnimator.TimeListener {
    private TimeAnimator mAnimator;
    private int mCurrentLevel = 0;
    private ClipDrawable mClipDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Get a handle on the ClipDrawable that we will animate.
        LayerDrawable layerDrawable = (LayerDrawable) findViewById(R.id.button).getBackground();
        mClipDrawable = (ClipDrawable) layerDrawable.findDrawableByLayerId(R.id.clip_drawable);

        // Set up TimeAnimator to fire off on button click.
        mAnimator = new TimeAnimator();
        mAnimator.setTimeListener(this);
    }

    @Override
    public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
        mClipDrawable.setLevel(mCurrentLevel);
        if (mCurrentLevel >= MAX_LEVEL) {
            mAnimator.cancel();
        } else {
            mCurrentLevel = Math.min(MAX_LEVEL, mCurrentLevel + LEVEL_INCREMENT);
        }
    }

    public void animateButton(View view) {
        if (!mAnimator.isRunning()) {
            mCurrentLevel = 0;
            mAnimator.start();
        }
    }

    private static final int LEVEL_INCREMENT = 400;
    private static final int MAX_LEVEL = 10000;
}

activity_main.xml

<android.support.constraint.ConstraintLayout 
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="32dp"
        android:background="@drawable/button_background"
        android:text="Button"
        android:onClick="animateButton"
        android:textColor="@android:color/white"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

这篇关于通过从左到右填充来更改按钮背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆