这个功能在网上找了好久,没有满意的,自己实现了一个,只是基础部分,后续有待优化,上代码,转载请注明
package com.example.bobo.myapplication;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.widget.ImageView;
import android.widget.Scroller;
import java.util.ArrayList;
/**
* Created by missingbobo on 2015/1/26.
*/
public class BannerView extends ViewGroup {
Scroller scroller;
private float mLastMotionX;
private int scrollTime = 14 * 1000;
private int currentScreenIndex = 0;
private boolean moving = false;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
}
};
public BannerView(Context context) {
super(context);
init(context);
}
public BannerView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public void init(Context context) {
this.scroller = new Scroller(context, new DecelerateInterpolator(4));//OvershootInterpolator(1.1f)
}
public void setViews(ArrayList views, Context context) {
if (views == null || views.size() == 0) {
return;
}
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
//生成头部header
ImageView iv = new ImageView(context);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setLayoutParams(params);
BannerEntity headerEntity = views.get(views.size() - 1);
iv.setImageBitmap(headerEntity.getBitmap());
addView(iv);
if (views.size() > 1) {
for (BannerEntity entity : views) {
iv = new ImageView(context);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageBitmap(entity.getBitmap());
iv.setLayoutParams(params);
addView(iv);
}
BannerEntity firstEntity = views.get(0);
iv = new ImageView(context);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageBitmap(firstEntity.getBitmap());
iv.setLayoutParams(params);
addView(iv);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int count = getChildCount();
for (int i = 0; i < count; i++) {
View view = getChildAt(i);
view.measure(widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean b, int i, int i2, int i3, int i4) {
int count = getChildCount();
int width = -getMeasuredWidth();
for (int num = 0; num < count; num++) {
View view = getChildAt(num);
view.layout(width, 0, width + getMeasuredWidth(), view.getMeasuredHeight());
width += getMeasuredWidth();
}
}
private float getRightEdge() {
int count = getChildCount();
return (count-2) * getMeasuredWidth();
}
private boolean isEnd() {
return getScrollX() >= getRightEdge();
}
private boolean isHead() {
return getScrollX() <= -getMeasuredWidth();
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (getChildCount() == 0 || !scroller.isFinished()) {
return false;
}
final int action = ev.getAction();
final float x = ev.getX();
getParent().requestDisallowInterceptTouchEvent(true);
switch (action) {
case MotionEvent.ACTION_DOWN:
mLastMotionX = x;
if (!scroller.isFinished()) {
scroller.abortAnimation();
return true;
}
moving = false;
return true;
case MotionEvent.ACTION_MOVE:
final int deltaX = (int) (mLastMotionX - x);
boolean xMoved = Math.abs(deltaX) > 4;
if (!moving && !xMoved)
break;
mLastMotionX = x;
scrollBy(deltaX, 0);
moving = true;
return true;
case MotionEvent.ACTION_UP:
forwordOrback();
break;
case MotionEvent.ACTION_CANCEL:
forwordOrback();
}
return false;
}
public void forwordOrback() {
scrollToScreen(getWhichScreen());
Log.e("banner which screen",getWhichScreen()+"");
}
@Override
public void computeScroll() {
if (scroller.computeScrollOffset()) {
scrollTo(scroller.getCurrX(), scroller.getCurrY());
// 刷新View 否则效果可能有误差
postInvalidate();
}
if (scroller.getCurrX() % getMeasuredWidth() == 0) {
if (isEnd()) {
scrollToHead();
} else if (isHead()) {
scrollToEnd();
}
}
}
public void scrollToHead() {
scrollTo(0, 0);
}
public void scrollToEnd() {
scrollTo(getLastPosition(), 0);
}
public int getLastPosition() {
int count = getChildCount();
return (count - 3) * getMeasuredWidth();
}
public int getWhichScreen() {
if(getScrollX()<0){
return -1;
}
return (getScrollX() + (getMeasuredWidth() / 2)) / getMeasuredWidth();
}
private void scrollToScreen(int whichScreen) {
if (whichScreen >= getChildCount()) {
whichScreen = getChildCount() - 1;
}
int delta = 0;
delta = whichScreen * getWidth() - getScrollX();
scroller.startScroll(getScrollX(), 0, delta, 0, 500);
invalidate();
currentScreenIndex = whichScreen;
}
}