项目中需要使用头像可以循环轮播的效果,哈哈,啥也不说,先上效果图,
不要看例子花里胡哨的,其实只是中间那四个头像啊!单独抽出来是右边这样的图片效果,这里是搞了个按钮开启自动更新的任务。
要想使用自动轮播头像闪动,首先需要圆形的头像,这个圆形的头像图片使用的是一个叫CircleImageView的开源控件
写的已经非常清晰了,他就是一个CircleImageView.java文件,复制过来这个java文件和一个arrrs.xml文件就可以使用了,目的是将我们提供的各种形状的图片替换成圆形的头像。
具体实现,先看下布局文件,很简单,就是四个上面使用的控件,四个CircleImageView,就这样,木有了:(请忽略这四个图片的名字,太乱了,不想改了o(╥﹏╥)o)
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ly_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/light">
<com.example.fake_hago_2.view.CircleImageView
android:id="@+id/top_2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toLeftOf="@+id/top_img"
android:layout_marginRight="7dp"
android:layout_centerInParent="true"
android:src="@drawable/pic2"
app:civ_border_width="2dp"
app:civ_border_color="@color/light" />
<com.example.fake_hago_2.view.CircleImageView
android:id="@+id/top_img"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:src="@drawable/hugh"
android:layout_marginRight="7dp"
app:civ_border_width="2dp"
app:civ_border_color="@color/light" />
<com.example.fake_hago_2.view.CircleImageView
android:id="@+id/top_3"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_toRightOf="@+id/top_img"
android:layout_marginRight="7dp"
android:layout_centerInParent="true"
android:src="@drawable/pic3"
app:civ_border_width="2dp"
app:civ_border_color="@color/light" />
<com.example.fake_hago_2.view.CircleImageView
android:id="@+id/top_4"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_toRightOf="@+id/top_3"
android:src="@drawable/pic4"
app:civ_border_width="2dp"
app:civ_border_color="@color/light" />
</RelativeLayout>
</merge>
接下来要自定义布局啦,我们继承RelativeLayout,然后重写初始化函数,在bindView()里面find到我们的每一个ImageView的Id,因为需要单独控制每个ImageView图片播放动画的时机,这样才有四个图片挨个播放的效果,具体的实现就是从MainActivity中启动我们这个自定义View的函数startFlashAvaterTask(),里面定义一个TimerTask,这个Task每隔两秒,发送四个之间间隔100毫秒的消息,交个Handler处理,handler根据接收到消息的先后顺序去开始四个ImageView各自的动画,大致逻辑就是这样子,具体看代码吧,注释写的比较清楚了:
public class FlashAvaterView extends RelativeLayout{
private ImageView top_2;
private ImageView top_3;
private ImageView top_4;
private ImageView mTopImg;
private Timer mTimer;
private long mIntervalTime = 0;
private volatile boolean isRun = true;
private static class AnimHandler extends Handler {}
//不同时间间隔接受到的消息,播放对应的View的动画
private AnimHandler mHandler = new AnimHandler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
scaleAnimator(top_2);
} else if (msg.what == 1) {
scaleAnimator(mTopImg);
} else if (msg.what == 2) {
scaleAnimator(top_3);
} else if (msg.what == 3) {
scaleAnimator(top_4);
}
super.handleMessage(msg);
}
};
public FlashAvaterView(Context context) {
this(context, null);
}
public FlashAvaterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlashAvaterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
bindViews(context);
}
private void bindViews(Context context) {
LayoutInflater.from(context).inflate(R.layout.flash_avater_view, this, true);
if (mTimer == null) {
mTimer = new Timer();
}
top_2 = (CircleImageView) findViewById(R.id.top_2);
mTopImg = (CircleImageView) findViewById(R.id.top_img);
top_3 = (CircleImageView) findViewById(R.id.top_3);
top_4 = (CircleImageView) findViewById(R.id.top_4);
}
//启动轮播任务的时间点
public void startFlashAvaterTask(long time) {
if (mTimer == null) {
mTimer = new Timer();
} else {
if (isRun) {
mTimer.scheduleAtFixedRate(new MyTask(), 1, 2000);
isRun = false;
}
}
}
//由于需要四个头像之间播放也有先后顺序,因此设置一个时间间隔,间隔mIntervalTime发送消息给handler
private class MyTask extends TimerTask {
@Override
public void run() {
for (int i = 0 ; i < 4; i++) {
mIntervalTime += 100;
mHandler.sendEmptyMessageDelayed(i, mIntervalTime);
}
}
}
//缩小、放大的动画
private void scaleAnimator(final ImageView img){
final float scale = 0f;
AnimatorSet scaleSet = new AnimatorSet();
ValueAnimator valueAnimatorSmall = ValueAnimator.ofFloat(1.0f, scale);
valueAnimatorSmall.setDuration(200);
ValueAnimator valueAnimatorLarge = ValueAnimator.ofFloat(scale, 1.0f);
valueAnimatorLarge.setDuration(200);
valueAnimatorSmall.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img.setScaleX(scale);
img.setScaleY(scale);
}
});
valueAnimatorLarge.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float scale = (Float) animation.getAnimatedValue();
img.setScaleX(scale);
img.setScaleY(scale);
}
});
scaleSet.play(valueAnimatorSmall).before(valueAnimatorLarge);
scaleSet.start();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}
}
具体怎个用法就很简单了,在XML布局文件中引入这个FlashAvaterView,然后findViewById(),和使用普通控件一样了:
xml中引入:
<com.example.fake_hago_2.view.FlashAvaterView
android:id="@+id/flash_avater"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
java中find它:
FlashAvaterView flashAvaterView = (FlashAvaterView) helper.getView(R.id.flash_avater);
flashAvaterView.startFlashAvaterTask(3000);