使用TransitionDrawable实现多张图片淡入淡出的效果

欢迎界面想做出广告页自动轮播的效果,图片切换的方式用淡入淡出的方式。这个在h5页面很容易就实现了,但是在android界面中,很容易就想到了动画animation动画来实现,但是发现使用动画的话,这种方式看起来不会自然,因为在调用statAnimation的时候因为图片已经显示了,这样再硬生生的播放一次动画其实会导致细微的闪烁效果。后来发现android中自带了TransitionDrawable类可以很轻松地实现这个效果,但是会有局限性。。。
先上效果图:
这里写图片描述

一、两张图片的切换效果,轻松实现

//讲需要切换的两张图片直接给TransitionDrawable对象
TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{getResources().getDrawable(R.drawable.advertiseone),getResources().getDrawable(R.drawable.advertisetwo)});
//一样用
imgAdvertise.setImageDrawable(transitionDrawable);
//切换图片的时间间隔
transitionDrawable.startTransition(3000);

二、切换多张图片
实现思路,通过开启一个线程(死循环),每隔一段时间发送消息到UI主线程中替换主线程中的transitionDrawable对象中的图片就可以了,需要用到handler。这里实现在广告倒计时中无限循环图片切换的次数

package com.coofond.carservice;

import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import com.coofond.carservice.mine.ui.LoginAct;

/**
 * Created by IBM on 2016/10/7.
 */

public class WelcomeAct extends AppCompatActivity {
    private TextView tvTimecount;
    private ImageView imgAdvertise;
    private int adTime = 6000;//倒计时秒数
    private int timeInterval = 1000;//倒计时间隔
    private CountDownTimer mTimer;//计时器
    private int change = 0;//记录下标
    private int[] ids = new int[]{R.drawable.advertiseone, R.drawable.advertisetwo, R.drawable.advertisethree};
    private Drawable[] drawables;//图片集合
    private Thread mThread;//线程
    private boolean mThreadFlag = true;//线程结束标志符

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.act_welcome);
        initView();
        initData();
        initEvent();
    }

    //定义hander
    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            int duration = msg.arg1;
            TransitionDrawable transitionDrawable = new TransitionDrawable(new Drawable[]{drawables[change % ids.length],
                    drawables[(change + 1) % ids.length]});
            change++;//改变标识位置
            imgAdvertise.setImageDrawable(transitionDrawable);
            transitionDrawable.startTransition(duration);
            return false;
        }
    });

    //开启线程发送消息,让transition一直在改变
    private class MyRunnable implements Runnable {
        @Override
        public void run() {
            //这个while(true)是做死循环
            while (mThreadFlag) {
                int duration = 1000;//改变的间隔
                Message message = mHandler.obtainMessage();
                message.arg1 = duration;
                mHandler.sendMessage(message);
                try {
                    Thread.sleep(duration);
                    //隔duration秒发送一次
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void initView() {
        tvTimecount = (TextView) findViewById(R.id.tv_advert);
        imgAdvertise = (ImageView) findViewById(R.id.iv_advetise);
        //填充图片
        drawables=new Drawable[ids.length];
        for (int i = 0; i < ids.length; i++) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                drawables[i] = getDrawable(ids[i]);
            } else {
                drawables[i] = getResources().getDrawable(ids[i]);
            }
        }
    }
    private void initData() {
        // 初始化计时器,第一个参数是共要倒计时的秒数,第二个参数是倒计时的间隔
        mTimer = new CountDownTimer(adTime, timeInterval) {
            // 倒计时开始时要做的事情,参数m是直到完成的时间
            @Override
            public void onTick(long millisUntilFinished) {
                tvTimecount.setText("" + millisUntilFinished / 1000 + "s跳过广告");
            }
            // 结束计时后要做的工作
            @Override
            public void onFinish() {
                jumpActivity();
            }
        };
        //开启计时器
        mTimer.start();
        //开启线程,改变transition,切换图片
        mThread= new Thread(new MyRunnable());
        mThread.start();
    }

    private void initEvent() {
        tvTimecount.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTimer.cancel();
                jumpActivity();
            }
        });
    }

    // 跳转页面
    private void jumpActivity() {
        //如果还没结束当前的页面,就结束
        if (!isFinishing()) {
            finish();
        }
        Intent it = new Intent(WelcomeAct.this, LoginAct.class);
        startActivity(it);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //mThread.stop(); 不推荐使用
        mThreadFlag=false;//结束线程

    }
}

记录个小tips:如何比较优雅地结束一个线程,只要在while条件中设置自己标识符,在需要结束的地方把标识符改为false就可以了。基础补上。。。

总结:transitionDrawable是切换两张图片淡入淡出效果的一个类。如果要切换多张图片,那么就相当于不断替换它的胶卷就可以了。因为交卷在UI主线程就准备好了,所以需要用到handler进行通信,然后开启线程轮询。因为实现的是广告欢迎页,倒计时一般只有3-5s,所以轮询的次数也不会太多。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值