代码有注释应该都能看的懂
上代码:
import java.util.ArrayList;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Scroller;
public class ImageViewGroup extends ViewGroup {
private InageViewGardenSwitch gardenSwitch = null;//用于返回当前界面的编号(对外编号)
private Context mContext;
private Scroller mScroller = null;//滑动动画
private int cens = 0;//当前显示界面的编号(初始值为0 0是中间 比如有五张图片那么0代表第三张图片,排序是-2,-1,0,1,2)
/*总共view的数量
总共图片数量为当前图片加2,因为这图片循环是伪无限循环, 需要添两张图片作为过渡,
这两张图片添加规则为:比如有5张图片
1,2,3,4,5 进来的图片的编号
5,1,2,3,4,5,1 添加两张图片之后的队列
-3,-2,-1,0,1,2,3 重新编号
*/
private int max = 0;
//最左边的view编号 (添加两张图片后的最左边位置)
private int leftJump = 0;
//同上方向是右边
private int rightJump = 0;
//如果当前显示为最左边的图片则跳转的目标图片编号
private int targetRight = 0;
private int targetLeft = 0;//同上
private boolean isTouch = false;//判断手指是否在控件上(是则不执行自动跳转)
private static final int TOUCH_STATE_REST = 0;
private static final int TOUCH_STATE_SCROLLING = 1;
private int mTouchState = TOUCH_STATE_REST;
private boolean isThread = true;//自动跳转线程开关
//--------------------------
public static int SNAP_VELOCITY = 600 ;
private int mTouchSlop = 0 ;
private float mLastionMotionX = 0 ;
private VelocityTracker mVelocityTracker = null ;
private int sizeWidth = 0;//控件的宽度
private int sizeHeight= 0;//控件的高度
public ImageViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
this.mContext = context;
mScroller = new Scroller(context);
}
/*
* 滑动到下一张图片
*/
public void startMove(){
if(cens == rightJump){
cens = leftJump + 1;
}
cens++ ;
mScroller.startScroll((cens-1)*getWidth(), 0,getWidth(), 0,2000);
invalidate();
theCurrentlyDisplayed();
}
/*
* 开启线程定时滑动到下一张图片
*/
public void timingMove(){
Handler handler = new Handler(){
/* (non-Javadoc)
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if(!isTouch){//判断当时是不是在执行手势
if(mScroller != null){//判断当前是不是正在执行动画
startMove();
}
}
}
};
new Thread(new timing(handler)).start();
}
//线程定时
class timing implements Runnable{
private Handler handler;
public timing(Handler handler) {
// TODO Auto-generated constructor stub
this.handler = handler;
}
@Override
public void run() {
while (isThread) {
try {
Thread.sleep(4000);
handler.sendMessage(new Message());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/*
* 初始化
*/
@Override
public void computeScroll() {
// TODO Auto-generated method stub
if (mScroller.computeScrollOffset()) {
scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
postInvalidate();
}else{
}
}
/*
* 设置图片并在首尾添加过渡图片
*/
public void setListImageView(ArrayList<Bitmap> list,InageViewGardenSwitch gardenSwitch){
this.gardenSwitch = gardenSwitch;
if(list != null && list.size() != 0){
ImageView top = new ImageView(mContext);
top.setImageBitmap(list.get(list.size()-1));
addView(top);
for (int i = 0; i < list.size(); i++) {
ImageView img = new ImageView(mContext);
img.setImageBitmap(list.get(i));
addView(img);
}
ImageView buttom = new ImageView(mContext);
buttom.setImageBitmap(list.get(0));
addView(buttom);
}
}
/*
* 手势监听
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if(mVelocityTracker == null){
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
super.onTouchEvent(event);
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isTouch = true;//设置手势正在监听中
if(mScroller != null){//判断当前是否在执行动画
mScroller.abortAnimation();//停止动画
}
if(cens == leftJump){//判断当前显示是否是最左边的图片
scrollBy(targetRight, 0);//跳转到最右侧-1的图片
cens = rightJump - 1;
}
if(cens == rightJump){//同上
scrollBy(targetLeft, 0);
cens = leftJump + 1;
}
mLastionMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
isTouch = true;
int dataX = (int)(mLastionMotionX - x);
scrollBy(dataX, 0);
mLastionMotionX = x;
break;
case MotionEvent.ACTION_UP:
isTouch = false;
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000);
int velocityX = (int) velocityTracker.getXVelocity();
System.out.println(velocityX+"aa");
if(velocityX > SNAP_VELOCITY){
snapToScreen(cens - 1);
}else if(velocityX < -SNAP_VELOCITY){
snapToScreen(cens + 1);
}else{
snapToDestination();
}
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
mTouchState = TOUCH_STATE_REST ;
case MotionEvent.ACTION_CANCEL:
mTouchState = TOUCH_STATE_REST ;
break;
default:
break;
}
return true;
}
public boolean commOnTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
final int action = ev.getAction();
if ((action == MotionEvent.ACTION_MOVE) && (mTouchState != TOUCH_STATE_REST)) {
return true;
}
final float x = ev.getX();
final float y = ev.getY();
switch (action) {
case MotionEvent.ACTION_MOVE:
final int xDiff = (int) Math.abs(mLastionMotionX - x);
if (xDiff > mTouchSlop) {
mTouchState = TOUCH_STATE_SCROLLING;
}
break;
case MotionEvent.ACTION_DOWN:
mLastionMotionX = x;
mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST : TOUCH_STATE_SCROLLING;
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mTouchState = TOUCH_STATE_REST;
break;
}
return mTouchState != TOUCH_STATE_REST;
}
private void snapToDestination(){
int destScreen = (getScrollX() + getWidth() / 2 ) / getWidth() ;
snapToScreen(destScreen);
}
private void snapToScreen(int whichScreen){
cens = whichScreen;
int dx = (cens)*getWidth() - getScrollX();
int time = Math.abs(dx) * 2;
mScroller.startScroll(getScrollX(), 0, dx, 0,time);
invalidate();
System.out.println(cens);
theCurrentlyDisplayed();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(sizeWidth, sizeHeight);
}
@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
// TODO Auto-generated method stub
int count = getChildCount();
int ce = 0;
System.out.println(count);
if(count <= 2)
return;
int childL = 0;
int childR = sizeWidth;
int childLs = 0;
int childRs = sizeWidth;
ce = count/2;
View cen = getChildAt(ce);
cen.layout(childL, 0, childR, sizeHeight);
for (int i = ce+1; i < count; i++) {
View view = getChildAt(i);
childL+=sizeWidth;
childR+=sizeWidth;
view.layout(childL, 0, childR, sizeHeight);
}
for (int i = ce-1; i >= 0; i--) {
View view = getChildAt(i);
childLs-=sizeWidth;
childRs-=sizeWidth;
view.layout(childLs, 0, childRs, sizeHeight);
}
max = count;
leftJump = -count/2;
if(count%2 == 0){
rightJump = count / 2 - 1;
}else{
rightJump = count / 2;
}
targetRight = (max - 2)*sizeWidth;
targetLeft = -(max - 2)*sizeWidth;
if(isTiming){
timingMove();
}
isTiming = false;
}
private boolean isTiming = true;
@Override
protected void onDetachedFromWindow() {
// TODO Auto-generated method stub
super.onDetachedFromWindow();
isThread = false;
}
public void theCurrentlyDisplayed(){
System.out.println(cens +"dangqiande "+leftJump);
if(cens == leftJump)
gardenSwitch.onSwitch((max-2)-1);
else
if(cens == rightJump)
gardenSwitch.onSwitch(0);
else
gardenSwitch.onSwitch(cens - (leftJump+1));
}
//手势监听获取
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
getParent().requestDisallowInterceptTouchEvent(true);
super.dispatchTouchEvent(ev);
commOnTouchEvent(ev);
return true;
}
}
//接口类 用于返回当前显示的是第几张图片。
public interface InageViewGardenSwitch {
public void onSwitch(int i);
}
使用方法:
xml:
<main.diyview.ImageViewGroup
android:id="@+id/homePageImageGroup"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
</main.diyview.ImageViewGroup>
activity:
public class main extends Activity implements InageViewGardenSwitch{
private ImageViewGroup imageViewGroup;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.home_page);
imageViewGroup = (ImageViewGroup)findViewById(R.id.homePageImageGroup);
ArrayList<Bitmap> imagelist = new ArrayList<Bitmap>();
Bitmap bitmap1 = BitmapFactory.decodeResource(this.getResources(), R.drawable.banner1); Bitmap bitmap2 = BitmapFactory.decodeResource(this.getResources(), R.drawable.banner2); Bitmap bitmap3 = BitmapFactory.decodeResource(this.getResources(), R.drawable.banner3); imagelist.add(bitmap1); imagelist.add(bitmap2); imagelist.add(bitmap3); imageViewGroup.setListImageView(imagelist, this);
}
@Override
public void onSwitch(int i) {
//返回当前显示第几张图片 可以用于小圆点切换
}
}
代码可能有一些错误 或者可以优化的地方请指出
<p>版权声明:本文为博主原创文章,未经博主允许不得转载。</p>