安卓案例:利用帧动画动态显示时间

安卓可以利用线程(Thread)和消息处理器(Handler)实现帧动画,下面我们通过一个简单案例【动态显示时间】来学习如何实现帧动画。

一、运行效果

在这里插入图片描述

二、涉及知识点

  • 线性布局(LinearLayout)
  • 标签(TextView)
  • 按钮(Button)
  • 线程(Thread)
  • 消息处理器(Handler)

三、安卓消息处理机制

(一)消息机制的引入

  1. 在Android中,只有在主线程中才能更新UI界面
  2. 在Android中,长时间的工作(联网)都需要在分线程中执行

(二)如何实现线程之间的通信

  • 消息机制:Handler + Thread
  • 异步任务:AsyncTask == Handler + Thread

(三)Message的使用:线程之间数据的载体

1、创建消息

Message.obtain();

2、使用消息

int what //标识符
int args1、args2 //用于保存int数据
Object obj //用于保存对象数据
Handler target //用于处理消息的handler
long when //消息应该被处理的时间
Message next //用于形成消息队列
static Message pool //消息池

(四)Handler的使用:发送、处理、移除消息

1、创建消息处理器

new Handler();

2、使用消息处理器

(1)发送消息

  • 发送及时消息 sendMessage(Message message)
  • 发送延迟消息 sendMessageDelayed(Message message, long dalayTime)
  • 发送空消息 sendEmptyMessage(int what)
  • 发送延迟的空消息 sendEmpMessage(int what, long dalatTime)

(2)处理消息

void handleMessage(Message msg) // 回调方法

(3)移除消息

removeMessage(int what) // 根据标识移除
removeCallbacksAndMessage(null) //移除所有未处理的消息

(五)MessageQueue:消息队列

  • 用来存放通过Handler的发送的消息
  • 一个按Message的when排序的优先级队列

(六)Looper(钩子)循环器

  • 负责循环取出MessageQueue里面得当前需要处理的Message
  • 交给对应的Handler
  • 处理完成将Message对象缓存到消息池中进行复用

(七)消息机制的原理

在这里插入图片描述

(八)Handler的用途

  • 线程间的通讯
  • 延迟工作
  • 定时循环工作

四、实现步骤

1、创建安卓应用【DynamicTime】

在这里插入图片描述
在这里插入图片描述

2、准备背景图片,拷贝到drawable目录

在这里插入图片描述

3、主布局资源文件activity_main.xml

在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tvTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2020-09-29 11:11:11"
        android:textColor="@color/colorPrimary"
        android:textSize="40sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center">

        <Button
            android:id="@+id/btnStart"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="doStart"
            android:text="@string/start"
            android:textSize="25sp"/>

        <Button
            android:id="@+id/btnStop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="doStop"
            android:text="@string/stop"
            android:textSize="25sp"/>

    </LinearLayout>
</LinearLayout>

4、字符串资源文件strings.xml

在这里插入图片描述

<resources>
    <string name="app_name">动态显示时间</string>
    <string name="start">开始</string>
    <string name="stop">停止</string>
</resources>

5、主界面类MainActivity

在这里插入图片描述

(1)声明变量

在这里插入图片描述

(2)通过资源标识符获取控件实例

在这里插入图片描述

(3)实例化简单日期格式对象

在这里插入图片描述

(4)创建消息处理器,接收子线程发送的消息,更新主界面元素

在这里插入图片描述

(5)创建【开始】按钮单击事件处理方法

在这里插入图片描述

(6)创建【停止】按钮单击事件处理方法

在这里插入图片描述

6、启动应用,查看效果

在这里插入图片描述

五、扩展练习

任务1、帧动画:游戏特效

在这里插入图片描述

游戏特效实现思路

  • 逐帧动画,其实就要定时切换图片,定时操作可以利用子线程来完成,切换图片就需要事先将所有图片的资源标识保存到一个数组里(这也是一个难点,尤其当图片数量比较大时),通过改变图片资源标识数组的当前索引达到切换图片的目的。
  • 但是,从安卓4.0版本以后,出于安全考虑,子线程不能直接更新主界面元素。怎么办呢?
  • 这就需要一种能沟通主线程和子线程的机制,而消息处理器Handler正是这样一种机制,实现不同线程间的通信。在子线程里,定时更新图片当前索引,然后通过handler的sendEmptyMessage方法将更新后的图片当前索引发送到主线程,最后,在主线程里,通过handler的handleMessage方法获取子线程发送过来的图片当前索引,利用这个索引获取当前图片的资源标识,作为参数传给图像控件的setImageRource方法,就达到更新图片的目的。
    在这里插入图片描述

任务2、帧动画:欣赏美女

在这里插入图片描述

任务3、帧动画:功夫熊猫

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/howard2005/article/details/108864515
今日推荐