时间:2022-12-03 12:10:57 | 栏目:Android代码 | 点击:次
欢迎界面想做出广告页自动轮播的效果,图片切换的方式用淡入淡出的方式。这个在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,所以轮询的次数也不会太多。