通过从左到右填充来更改按钮背景

con*_*dor 2 java android kotlin

我想在按下时更改按钮的背景,方法是从左到右填充颜色,就像水平进度条一样。

这是检测按住不放的代码:

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
        }
Run Code Online (Sandbox Code Playgroud)

这是我用于按钮的背景:

<?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>
Run Code Online (Sandbox Code Playgroud)

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

Che*_*amp 10

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>
Run Code Online (Sandbox Code Playgroud)

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 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.

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;
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)