在Android画布上实现字符串的简单淡出动画

3
我有一个扩展自View的自定义视图,其中有很多以不同角度绘制的文本,并且我希望在第一次启动后,特定字符串的alpha值降低到某个水平。欢迎任何建议或片段代码:)
对于这个任务,postInvalidateDelayed(...)似乎无法工作。

你的目标安卓版本是什么?Honeycomb 及以上版本有一个动画框架,可用于实现此功能。 - MJD
使用SDK android:minSdkVersion="10",目标版本为2.3.3。我知道那个框架,但我还差一步:P。 - M-Wajeeh
现在postInvalidateDelayed(...)正在工作。在正确测量要淡化的文本边界时出现了错误。 - M-Wajeeh
3个回答

1
一种可能的方法是创建两个视图,它们重叠在一个FrameLayout中。一个视图包含所有静态字符串,另一个视图包含您想要动画化的字符串。然后,只需向动画视图添加alpha动画即可。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <package.MyNonAnimatedView
        android:id="@+id/nonAnimatedView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <package.MyAnimatedView
        android:id="@+id/animatedView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</FrameLayout>

对于动画,您需要将其附加到动画视图上:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="100" />

在您的活动的onCreate(Bundle)方法中,您可以调用AnimationUtils.loadAnimation(Context, int)来从xml资源加载动画并将其附加到动画视图上(前提是您给它一个id)。

不错 :) 但是这两个视图是相关的,我必须使用接口等方法将它们分开,只为了使用这种方法进行简单的动画。 - M-Wajeeh
嗯...如果这两个视图在创建字符串方面足够相似,你可以在上面的xml代码中实例化同一个视图两次。通过活动在两个视图之间进行交互(如果必要)非常容易。最简单的方法是完全将视图代码与动画代码分开,但像上面描述的那样对一个视图进行动画处理将会对整个视图进行动画处理,而不仅仅是其中的一部分。 - happydude

1
你可以在你的Activity中添加一个Handler,它可以按照指定的时间间隔发送消息。当你的Activity从Handler接收到回调时,可以通知视图更新你想要改变的部分。
一个例子:
public class myActivity extends Activity implements Handler.Callback {

    int mDelay = 100; // Update interval (milliseconds).
    Handler mHandler = new Handler(this);
    private Runnable mEvent = new Runnable() {
        @Override
        public void run() {
            mHandler.postDelayed(mEvent, mDelay);
            Message message = mHandler.obtainMessage();
            // Add arguments to message, if required.
            mHandler.sendMessage(message);
        }
    };

    @Override
    public boolean handleMessage(Message message) {
        // Your view update code.
    }

    private void start() {
        mHandler.postDelayed(mEvent, mDelay);
    }

    private void stop() {
        mHandler.removeCallbacks(mEvent);
    }
}

调用 start() 启动处理程序,stop() 停止它。确定何时停止处理程序可能在 handleMessage(Message) 代码中。


这种方法也可以使用,但是我不知何故成功地运用了 postInvalidateDelayed(...) 方法。在垂直文本边界的正确测量方面存在错误。 - M-Wajeeh
我建议您将解决方案发布并接受它作为答案。 - happydude

0

在正确测量垂直文本边界以进行淡化时出现了错误。这是我的onDraw方法:

Paint myPaint = new Paint();
myPaint.setColor(Color.parseColor("#" + colorAlpha + "3AA6D0"));// initially colorAlpha is ff
Rect r = new Rect();
char[] a = "Hello World".toCharArray();
datePaint.getTextBounds(a, 0, a.length, r);// get the bound of the text, I was not calculating this correctly
canvas.drawText("Hello World", 0, 0, myPaint);// draw the text

int colorValue = Integer.parseInt(colorAlpha, 16);
    colorValue -= 20;// decrease alpha value for next call to onDraw method by postInvalidateDelayed
if (colorValue > 40) {
        colorAlpha = Integer.toHexString(colorValue);


 // this will create the effect of fade out animation
 // because each call to onDraw method is at the difference of 50 millisecond delay 
 // and in each call we are decreasing alpha value by 20.
        postInvalidateDelayed(50, r.left, r.top, r.right, r.bottom);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接