Yev Kanivets
Yev Kanivets

Reputation: 1800

Advanced view animation in Android

I'm developing an app for Android with beautiful, but hard-to-implement design with tons of custom animations. Now I need to implement animation for button, it must be dynamic glance animation that affects both button border and its text, and must move from left to right. Here is an example of such animation in iOS app.

from left

to right

So I hope you catched the main idea. I tried to use Property Animation, but it's not what I really need. Also I found many custom libraries and tried a lot of examples from SDK, but there are nothing similar.

So if you know how it can be do, answer me.

Upvotes: 1

Views: 1171

Answers (3)

pdegand59
pdegand59

Reputation: 13029

I finished my custom implementation of this.

The result so far :

enter image description here

This is obtained by transferring an animated gradient Shader on the static TextView You can get the source code on the following Gist : ShinnyTextView

The current version does not support XML customization, but you can adapt the values in the code.

If you are using this, you might want to have a more precise control on when to pause/restart the animation to avoid the ani

Upvotes: 2

pskink
pskink

Reputation: 24720

try this wrapper class:

class FL extends FrameLayout implements ValueAnimator.AnimatorUpdateListener {
    private static final int W = 200;
    private final LinearGradient gradient;
    private final Paint paint;
    private float x;

    public FL(View child) {
        super(child.getContext());
        addView(child);
        int[] colors = {0, 0xaaffffff, 0};
        gradient = new LinearGradient(0, 0, W, 0, colors, null, Shader.TileMode.CLAMP);
        paint = new Paint();
        paint.setShader(gradient);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
        x = -W;
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.saveLayer(null, null, 0);
        super.dispatchDraw(canvas);
        canvas.translate(x, 0);
        float h = getHeight();
        canvas.rotate(20, W / 2, h / 2);
        canvas.drawRect(0, -h, W, 2 * h, paint);
        canvas.restore();
    }

    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        x = (int) animation.getAnimatedValue();
        invalidate();
    }

    public void startMagic() {
        ValueAnimator a = ValueAnimator.ofInt(-W, getWidth());
        a.addUpdateListener(this);
        a.setDuration(1000).setInterpolator(new AccelerateDecelerateInterpolator());
        a.start();
    }
}

round_frame.xml is:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners android:radius="20dp" />
    <stroke android:color="#a00" android:width="4dp" />
</shape>

and test it with the following in onCreate:

    Button b = new Button(this);
    final FL fl = new FL(b);
    b.setTextSize(28);
    b.setTextColor(0xffaa0000);
    b.setText("click me to see the magic");
    b.setBackgroundResource(R.drawable.round_frame);
    View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fl.startMagic();
        }
    };
    b.setOnClickListener(listener);
    addContentView(fl, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));

NOTE: if you want it to use it in the Button only, you don't have a FL wrapper: you can extend Button class and override drawing methods as i did in FL wrapper class

Upvotes: 3

Greg Ennis
Greg Ennis

Reputation: 15379

I get the pre-rendered animation with a sequence of PNG files and then use the AnimationDrawable to display it.

Upvotes: 4

Related Questions