«

Android 图片轮番 继承ViewGroup实现 可以直接使用

时间:2024-3-2 19:23     作者:韩俊     分类: Android



代码有注释应该都能看的懂
上代码:

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>

标签: android

热门推荐