android控件實(shí)現(xiàn)多張圖片漸變切換
本來(lái)項(xiàng)目是用的viewpager實(shí)現(xiàn)的輪播滾動(dòng),但是客戶覺(jué)得輪播的效果太大眾化了,于是就要我們改成漸變切換的效果。聽(tīng)到這需求,我最先想到是給viewpager設(shè)置切換動(dòng)畫(huà),但是無(wú)論怎么設(shè)置動(dòng)畫(huà),都要手動(dòng)切換的時(shí)候才有效果。于是我就自定義了一個(gè)控件,利用淡入淡出動(dòng)畫(huà)實(shí)現(xiàn)了這效果,還是先上效果圖,沒(méi)效果圖說(shuō)再多也沒(méi)用。

public class Gradient extends RelativeLayout {
private List<ImageView> imageViews;
private List<Animation> outAnim;//淡出動(dòng)畫(huà)
private List<Animation> inAnim;//淡入動(dòng)畫(huà)
private Context mContext;
private Handler handler = new Handler(Looper.getMainLooper());
private int couot;
private int currentIndex;//當(dāng)前的頁(yè)面
private LinearLayout linearLayout;
private onClickListner listner;
private long time=3000;//動(dòng)畫(huà)間隔時(shí)間
public Gradient(Context context) {
this(context, null);
}
public Gradient(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
/**
* 畫(huà)點(diǎn)
*/
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++) {
// 設(shè)置圓點(diǎn)
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);
}
}
/**
* 根據(jù)手機(jī)的分辨率從 dip 的單位 轉(zhuǎn)成為 px(像素)
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 設(shè)置圖片
* @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();
}
/**
* 開(kāi)啟動(dòng)畫(huà)
*/
private void start() {
final int size = imageViews.size();
handler.post(new Runnable() {
@Override
public void run() {
final int i = couot % size;
//解決點(diǎn)擊事件的沖突
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 {
//當(dāng)前的淡出,下一張淡入
ImageView imageView = imageViews.get(size - 1 - i);
imageView.startAnimation(outAnim.get(size - 1 - i));
}
} else {
if (i == size - 1) {
//當(dāng)顯示到最后一張的時(shí)候,要跳到第一張
ImageView imageView = imageViews.get(0);
imageView.startAnimation(outAnim.get(0));
ImageView imageView2 = imageViews.get(size - 1);
imageView2.startAnimation(inAnim.get(size - 1));
} else {
//當(dāng)前的淡出,下一張淡入
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);
}
});
}
/**
* 創(chuàng)建動(dòng)畫(huà)
*/
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);
}
}
/**
* 設(shè)置點(diǎn)擊事件
*/
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);
}
/**
* 設(shè)置動(dòng)畫(huà)播放和handler延遲時(shí)間
* @param time
*/
public void setTime(long time) {
this.time = time;
}
public void setListner(onClickListner listner) {
this.listner = listner;
}
/** 創(chuàng)建一個(gè)淡出縮小的動(dòng)畫(huà) */
public Animation createZoomOutAwayAnim() {
AnimationSet ret;
Animation anim;
ret = new AnimationSet(false);
// 創(chuàng)建一個(gè)淡出的動(dòng)畫(huà)
anim = new AlphaAnimation(1f, 0f);
anim.setDuration(time);
anim.setInterpolator(new DecelerateInterpolator());
ret.addAnimation(anim);
// 創(chuàng)建一個(gè)縮小的動(dòng)畫(huà)
/*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;
}
/** 創(chuàng)建一個(gè)淡入縮小的動(dòng)畫(huà) */
public Animation createZoomOutNearAnim() {
AnimationSet ret;
Animation anim;
ret = new AnimationSet(false);
// 創(chuàng)建一個(gè)淡入的動(dòng)畫(huà)
anim = new AlphaAnimation(0f, 1f);
anim.setDuration(time);
anim.setInterpolator(new LinearInterpolator());
ret.addAnimation(anim);
// 創(chuàng)建一個(gè)縮小的動(dòng)畫(huà)
/*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;
}
}
這個(gè)控件的使用非常簡(jiǎn)單只要在布局文件中使用我們自定義的控件,然后調(diào)用setTime設(shè)置動(dòng)畫(huà)切換的時(shí)間,setListener設(shè)置圖片的點(diǎn)擊事件,setImagevies設(shè)置圖片就可以實(shí)現(xiàn)效果.考慮到內(nèi)存泄漏的問(wèn)題,只要在ondestry方法里面調(diào)用stop方法即可,點(diǎn)擊下載Demo
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android開(kāi)發(fā)之使用ViewPager實(shí)現(xiàn)圖片左右滑動(dòng)切換效果
- Android編程單擊圖片實(shí)現(xiàn)切換效果的方法
- Android自定義ImageView實(shí)現(xiàn)點(diǎn)擊兩張圖片切換效果
- Android實(shí)現(xiàn)圖片輪播切換實(shí)例代碼
- Android基于ImageSwitcher實(shí)現(xiàn)圖片切換功能
- Android實(shí)現(xiàn)滑動(dòng)屏幕切換圖片
- Android游戲開(kāi)發(fā):實(shí)現(xiàn)手勢(shì)操作切換圖片的實(shí)例
- Android使用ViewFlipper實(shí)現(xiàn)圖片切換功能
- Android開(kāi)發(fā)實(shí)現(xiàn)高仿優(yōu)酷的客戶端圖片左右滑動(dòng)切換功能實(shí)例【附源碼下載】
- Android開(kāi)發(fā)實(shí)現(xiàn)的圖片點(diǎn)擊切換功能示例
相關(guān)文章
Android布局中margin與padding的區(qū)別及說(shuō)明
這篇文章主要介紹了Android布局中margin與padding的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
Android Build Variants 為項(xiàng)目設(shè)置變種版本的方法
下面小編就為大家分享一篇Android Build Variants 為項(xiàng)目設(shè)置變種版本的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Android答題APP的設(shè)計(jì)與實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Android答題APP的設(shè)計(jì)與實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Android使用android-wheel實(shí)現(xiàn)省市縣三級(jí)聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了Android使用android-wheel實(shí)現(xiàn)省市縣三級(jí)聯(lián)動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
Android編程實(shí)現(xiàn)兩個(gè)Activity之間共享數(shù)據(jù)及互相訪問(wèn)的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)兩個(gè)Activity之間共享數(shù)據(jù)及互相訪問(wèn)的方法,簡(jiǎn)單分析了Android中Activity數(shù)據(jù)共享與訪問(wèn)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Android ChipGroup收起折疊效果實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了Android ChipGroup收起折疊效果實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
自定義TextView跑馬燈效果可控制啟動(dòng)/停止/速度/焦點(diǎn)
Android自帶的跑馬燈效果不太好控制,不能控制速度,不能即時(shí)停止和啟動(dòng),而且還受焦點(diǎn)的影響不已,由于項(xiàng)目需求需所以自己寫(xiě)了一個(gè)自定義的TextView,感興趣的朋友可以了解下2013-01-01
Android sqlite cursor的遍歷實(shí)例詳解
在本篇內(nèi)容里小編給大家整理的是一篇關(guān)于Android sqlite cursor的遍歷的相關(guān)實(shí)例及知識(shí)點(diǎn),需要的朋友們可以學(xué)習(xí)下。2021-06-06

