android自定义广告轮播图(一个类300行)
2018-06-26 本文已影响28人
niiiiiK
Banner.gif
package com.forens.action.ui.widget;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import com.forens.action.R;
import com.forens.action.utils.LogUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/****
* <pre>
* Project_Name: ActionHttp2
* Copyright:
* Version: 1.0.0
* Created: dake on 2018/6/14 17:13.
* E-mail: 1129305620@qq.com
* Desc: 自定义首页轮播广告layout
* </pre>
****/
public class BannerLayout extends ViewGroup {
private float X_DOWN = 0, X_PREVIOUS;
private int DIRECTION = 0;
private int interval = 3000;
private int count = 0, currentPosition = 0, placeHolderId;
private List<ImageView> mImageViewList;
private ValueAnimator moveAnim, backAnim;
private BannerListener mListener;
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
moveAnim.cancel();
moveAnim.start();
postDelayed(this, interval);
}
};
public BannerLayout(Context context) {
this(context, null);
}
public BannerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BannerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initImage();
initAnim();
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BannerLayout);
placeHolderId = a.getResourceId(R.styleable.BannerLayout_placeholder, 0);
}
}
private void initImage() {
mImageViewList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
ImageView imageView = new ImageView(getContext());
imageView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
addView(imageView);
mImageViewList.add(imageView);
}
}
private void initAnim() {
moveAnim = ValueAnimator.ofFloat(0f, 1f);
moveAnim.setDuration(1000).setInterpolator(new DecelerateInterpolator());
moveAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float all = getWidth() - Math.abs(mImageViewList.get(1).getX());
if (DIRECTION == 1) {
setAllX(all * (float) animation.getAnimatedValue());
} else {
setAllX(-all * (float) animation.getAnimatedValue());
}
}
});
moveAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (DIRECTION == 1) {//向右
mImageViewList.get(2).setX(-getWidth());
Collections.swap(mImageViewList, 1, 2);
Collections.swap(mImageViewList, 0, 1);
if (mListener != null) {
mImageViewList.get(0).setImageBitmap(null);
currentPosition = currentPosition == 0 ? (count - 1) : (currentPosition - 1);
mListener.onLoadImg(currentPosition == 0 ? (count - 1) : currentPosition - 1, mImageViewList.get(0));
}
} else {
mImageViewList.get(0).setX(getWidth());
Collections.swap(mImageViewList, 1, 0);
Collections.swap(mImageViewList, 2, 1);
if (mListener != null) {
mImageViewList.get(2).setImageBitmap(null);
currentPosition = currentPosition == (count - 1) ? 0 : (currentPosition + 1);
mListener.onLoadImg(currentPosition == (count - 1) ? 0 : currentPosition + 1, mImageViewList.get(2));
}
}
if (mListener != null) {
mListener.onChange(currentPosition);
}
}
});
backAnim = ValueAnimator.ofFloat(0f, 1f);
backAnim.setDuration(1000).setInterpolator(new DecelerateInterpolator());
backAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float all = Math.abs(mImageViewList.get(1).getX());
if (mImageViewList.get(1).getX() > 0) {
setAllX(-all * (float) animation.getAnimatedValue());
} else {
setAllX(all * (float) animation.getAnimatedValue());
}
}
});
}
private void setAllX(float xOf) {
mImageViewList.get(1).setX(mImageViewList.get(1).getX() + xOf);
mImageViewList.get(0).setX(mImageViewList.get(1).getX() - getWidth());
mImageViewList.get(2).setX(mImageViewList.get(1).getX() + getWidth());
}
public void setScaleType(ImageView.ScaleType scaleType) {
for (ImageView imageView : mImageViewList) {
imageView.setScaleType(scaleType);
}
}
public void setCount(int count) {
this.count = count;
if (count <= 0) {
mImageViewList.get(1).setImageResource(placeHolderId);
} else {
if (mListener != null) {
mListener.onLoadImg(0, mImageViewList.get(1));
if (count > 1) {
mListener.onLoadImg(1, mImageViewList.get(2));
mListener.onLoadImg(count - 1, mImageViewList.get(0));
postDelayed(mRunnable, interval);
}
}
}
}
public void setListener(BannerListener listener) {
mListener = listener;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int count = getChildCount();
if (count < 3)
return;
for (int i = 0; i < count; i++) {
View child = getChildAt(i);
if (child instanceof ImageView) {
int w = getWidth();
switch (i) {
case 0:
child.layout(-w, t, 0, b);
break;
case 1:
child.layout(l, t, r, b);
break;
case 2:
child.layout(w, t, w * 2, b);
break;
}
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
// int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//高度wrap_content时设置为16:9
if (heightMode == MeasureSpec.AT_MOST) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(widthSize, widthSize * 9 / 16);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (count == 0 || count == 1) {
return false;
}
getParent().requestDisallowInterceptTouchEvent(true);
moveAnim.cancel();
backAnim.cancel();
removeCallbacks(mRunnable);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
X_DOWN = event.getX();
X_PREVIOUS = event.getX();
break;
case MotionEvent.ACTION_MOVE:
setAllX(event.getX() - X_PREVIOUS);
X_PREVIOUS = event.getX();
break;
case MotionEvent.ACTION_UP:
DIRECTION = event.getX() - X_DOWN > 0 ? 1 : 0;
if ((event.getEventTime() - event.getDownTime()) < 200) {
// LogUtil.d("快速滑动,切换");
if (Math.abs((event.getX() - X_DOWN)) > 200) {
moveAnim.start();
} else {
backAnim.start();
}
} else {
if (Math.abs((event.getX() - X_DOWN)) >= (getWidth() / 2)) {
// LogUtil.d("慢速滑动超过一半,切换");
moveAnim.start();
} else {
// LogUtil.d("慢速滑动没有超过一半,回弹");
backAnim.start();
}
}
postDelayed(mRunnable, interval);
break;
}
return true;
}
@Override
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
LogUtil.d("onWindowFocusChanged:"+hasWindowFocus);
}
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
LogUtil.d("onWindowVisibilityChanged:"+visibility);
if(visibility==VISIBLE){
}else {
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
removeCallbacks(mRunnable);
}
public interface BannerListener {
void onChange(int position);
void onLoadImg(int position, ImageView imageView);
}
}
attrs.xml
<declare-styleable name="BannerLayout">
<attr name="placeholder" format="reference"/>
</declare-styleable>
使用
mBannerLayout.setListener(new BannerLayout.BannerListener() {
@Override
public void onChange(int position) {
LogUtil.d("onChange:"+position);
}
@Override
public void onLoadImg(int position, ImageView imageView) {
LogUtil.d("onLoadImg:"+position);
Glide.with(getActivity()).load(mStringList.get(position)).into(imageView);
}
});
mBannerLayout.setCount(mStringList.size());