android控件实现多张图片渐变切换
作者:totcw 发布时间:2022-06-18 20:11:57
标签:android,图片渐变,图片切换
本来项目是用的viewpager实现的轮播滚动,但是客户觉得轮播的效果太大众化了,于是就要我们改成渐变切换的效果。听到这需求,我最先想到是给viewpager设置切换动画,但是无论怎么设置动画,都要手动切换的时候才有效果。于是我就自定义了一个控件,利用淡入淡出动画实现了这效果,还是先上效果图,没效果图说再多也没用。
public class Gradient extends RelativeLayout {
private List<ImageView> imageViews;
private List<Animation> outAnim;//淡出动画
private List<Animation> inAnim;//淡入动画
private Context mContext;
private Handler handler = new Handler(Looper.getMainLooper());
private int couot;
private int currentIndex;//当前的页面
private LinearLayout linearLayout;
private onClickListner listner;
private long time=3000;//动画间隔时间
public Gradient(Context context) {
this(context, null);
}
public Gradient(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
/**
* 画点
*/
public void cratePoint() {
if (null != imageViews && imageViews.size() > 0) {
int size = imageViews.size();
linearLayout = new LinearLayout(mContext);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setGravity(Gravity.CENTER);
// 添加图片
for (int i = 0; i < size; i++) {
// 设置圆点
View viewPoint = new View(mContext);
viewPoint.setBackgroundResource(R.drawable.point_background);
int weight = dip2px(mContext, 5);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(weight, weight);
lp.leftMargin = weight;
viewPoint.setLayoutParams(lp);
viewPoint.setEnabled(false);
linearLayout.addView(viewPoint);
}
View childAt = linearLayout.getChildAt(0);
if (null != childAt) {
childAt.setEnabled(true);
}
//添加到图片的下边
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(-1,-2);
rlp.bottomMargin = dip2px(mContext, 5);
rlp.addRule(ALIGN_PARENT_BOTTOM);
this.addView(linearLayout, rlp);
}
}
/**
* 根据手机的分辨率从 dip 的单位 转成为 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 设置图片
* @param imageViews
*/
public void setImageViews(List<ImageView> imageViews) {
this.imageViews = imageViews;
for (int i = 0; i < imageViews.size(); i++) {
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(-1,-1);
addView(imageViews.get(i),layoutParams);
}
setonClick();
cratePoint();
createAnim();
start();
}
/**
* 开启动画
*/
private void start() {
final int size = imageViews.size();
handler.post(new Runnable() {
@Override
public void run() {
final int i = couot % size;
//解决点击事件的冲突
for (int j = 0; j < size; j++) {
if (j == i) {
imageViews.get(i).setClickable(true);
} else {
imageViews.get(i).setClickable(false);
}
}
if (couot < size) {
if (i == size - 1) {
ImageView imageView = imageViews.get(0);
imageView.startAnimation(outAnim.get(0));
ImageView imageView2 = imageViews.get(size - 1);
imageView2.startAnimation(inAnim.get(size - 1));
} else {
//当前的淡出,下一张淡入
ImageView imageView = imageViews.get(size - 1 - i);
imageView.startAnimation(outAnim.get(size - 1 - i));
}
} else {
if (i == size - 1) {
//当显示到最后一张的时候,要跳到第一张
ImageView imageView = imageViews.get(0);
imageView.startAnimation(outAnim.get(0));
ImageView imageView2 = imageViews.get(size - 1);
imageView2.startAnimation(inAnim.get(size - 1));
} else {
//当前的淡出,下一张淡入
ImageView imageView = imageViews.get(size - 1 - i);
imageView.startAnimation(outAnim.get(size - 1 - i));
ImageView imageView2 = imageViews.get(size - 2 - i);
imageView2.startAnimation(inAnim.get(size - 2 - i));
}
}
currentIndex = i;
linearLayout.getChildAt(currentIndex % size).setEnabled(false);
currentIndex++;
linearLayout.getChildAt(currentIndex % size).setEnabled(true);
couot++;
handler.postDelayed(this, time);
}
});
}
/**
* 创建动画
*/
private void createAnim() {
outAnim = new ArrayList<>();
inAnim = new ArrayList<>();
for (int i = 0; i < imageViews.size(); i++) {
Animation zoomOutAwayAnim = createZoomOutAwayAnim();
zoomOutAwayAnim.setFillAfter(true);
outAnim.add(zoomOutAwayAnim);
Animation zoomOutNearAnim = createZoomOutNearAnim();
zoomOutNearAnim.setFillAfter(true);
inAnim.add(zoomOutNearAnim);
}
}
/**
* 设置点击事件
*/
public void setonClick() {
for (int i = 0; i < imageViews.size(); i++) {
imageViews.get(i).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (listner != null) {
listner.setonClick((currentIndex) % imageViews.size());
}
}
});
}
}
public interface onClickListner{
void setonClick(int position);
}
/**
* 设置动画播放和handler延迟时间
* @param time
*/
public void setTime(long time) {
this.time = time;
}
public void setListner(onClickListner listner) {
this.listner = listner;
}
/** 创建一个淡出缩小的动画 */
public Animation createZoomOutAwayAnim() {
AnimationSet ret;
Animation anim;
ret = new AnimationSet(false);
// 创建一个淡出的动画
anim = new AlphaAnimation(1f, 0f);
anim.setDuration(time);
anim.setInterpolator(new DecelerateInterpolator());
ret.addAnimation(anim);
// 创建一个缩小的动画
/*anim = new ScaleAnimation(1, 0, 1, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(MEDIUM);
anim.setInterpolator(new DecelerateInterpolator());
ret.addAnimation(anim);*/
return ret;
}
/** 创建一个淡入缩小的动画 */
public Animation createZoomOutNearAnim() {
AnimationSet ret;
Animation anim;
ret = new AnimationSet(false);
// 创建一个淡入的动画
anim = new AlphaAnimation(0f, 1f);
anim.setDuration(time);
anim.setInterpolator(new LinearInterpolator());
ret.addAnimation(anim);
// 创建一个缩小的动画
/*anim = new ScaleAnimation(3, 1, 3, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(MEDIUM);
anim.setInterpolator(new DecelerateInterpolator());
ret.addAnimation(anim);*/
return ret;
}
}
这个控件的使用非常简单只要在布局文件中使用我们自定义的控件,然后调用setTime设置动画切换的时间,setListener设置图片的点击事件,setImagevies设置图片就可以实现效果.考虑到内存泄漏的问题,只要在ondestry方法里面调用stop方法即可,点击下载Demo
来源:https://blog.csdn.net/totcw/article/details/52161975


猜你喜欢
- 本文实例讲述了Java实现的质因数分解操作。分享给大家供大家参考,具体如下:这里演示java通过递归实现质因数分解,代码如下:import
- 作为Android应用开发者,不得不面对一个尴尬的局面,就是自己辛辛苦苦开发的应用可以被别人很轻易的就反编译出来。Google似乎也发现了这
- 需求说明实现方式嗯 这个可以视作一个经典的消费者和生产者的问题,详细见代码注释代码内容 消费者,负责取走生产者产生的信息/** * @aut
- 在装2个不同版本JDK时遇到了这个问题,在网上钩了一吧!查到一个讲解比较好的资料。一:要解决的问题我们在尝鲜 JDK1.5 的时候,相信不少
- 本文实例为大家分享了Android实现圆形云标签效果展示的具体代码,供大家参考,具体内容如下下面是实现的效果图:这个适合用于选择 用户的一些
- 题目:将一个数组逆序输出。代码:import java.util.*;public class lianxi31 {public stati
- 缘起:利用 ContentProvider 来初始化你的 Library, 这个相信大家已经不太陌生了,下面简要说下。1. 利用 Conte
- 前言:函数式编程是一种编程范式,其中程序是通过应用和组合函数来构造的。它是一种声明式编程范式,其中函数定义是表达式树,每个表达式树返回一个值
- 在AndroidMenifest.xml中,常常会有下面的语句: <uses-sdk android:minSdkVersion=&q
- 这篇文章主要介绍了通过实例了解spring使用构造器注入的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,
- 本文实例讲述了C#移除所有事件绑定的方法。分享给大家供大家参考。具体分析如下:private delegate int DEL_TEST_E
- 安装容易出现的问题以及解决方法:1、更新sdk时可能无法连接服务器,可在C:\WINDOWS\system32\drivers\etc下的h
- main方法调用spring的service将业务层类配置到Spring中:<bean id="customerServic
- try &
- 本文实例为大家分享了unity shader实现玻璃折射的具体代码,供大家参考,具体内容如下Shader "Unlit/rende
- 写作原因:跨进程通信的实现和理解是Android进阶中重要的一环。下面博主分享IPC一些相关知识、操作及自己在学习IPC过程中的一些理解。这
- 在最近写的一个天气APP中用到了圆形头像这样的一个样式,中间是圆形的头像(被圆形切割的图片),周围是一个带颜色的圆环。如下图所示,今天就来说
- 大叔我北漂十多年,一直没有摇到北京的车牌,每周都需要通过一个 APP 办理“进京证”,当我办理 19 年最后一次进京证的时候,APP 给出了
- 正文:相关术语翻译说明:Mark,标记;Sweep,清除;Compact,整理; 也有人翻译为压缩,译者认为GC时不存在压缩这回事。Copy
- 在项目开发中,我们经常需要进行动态添加组件,其中可添加的部分有两项:布局和组件 其中,添加的布局主要有RelativeLayout