imageswitch的自动切换的一个工具类

2024-01-12 03:18

本文主要是介绍imageswitch的自动切换的一个工具类,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

主要代码

public class ImageSwitcher extends ViewGroup {

    
    private String TAG = ImageSwitcher.class.getSimpleName();
    private static final int SNAP_VELOCITY = 300;

    private Scroller scroller;
    
    private VelocityTracker mVelocityTracker;
    
    private int mTouchSlop;

    private float mMotionX;

    private int mImageWidth;
    
    private int imageCount;

    private int mIndex;

    private int mImageHeight;
    
    private int[] imageItems;
    
    private boolean forceToRelayout;
    
    private int mTouchState = TOUCH_STATE_REST;
    
    private static final int TOUCH_STATE_REST = 0;
    private static final int TOUCH_STATE_SCROLLING = 1;
    
    private static final int AUTO_MSG = 0;
    
    private static final int START_MSG =2;
    
    private static final int HANDLE_MSG = 1;
    
    private static final long PHOTO_CHANGE_TIME = 4000;
    
    
    private  Handler mHandler = new Handler(){ //处理图片自动或者手动滚动操作
        
        public void handleMessage(Message msg) {
            switch (msg.what) {
            case AUTO_MSG:
                scrollToNext();
                mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);
                break;
            case START_MSG:
                mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);
                break;
            case HANDLE_MSG:
                mHandler.removeMessages(AUTO_MSG);
                mHandler.sendEmptyMessageDelayed(AUTO_MSG, PHOTO_CHANGE_TIME);
            default:
                break;
            }
        }
    };

    /**
     * 表示滚动到下一张图片这个动作
     */
    private static final int SCROLL_NEXT = 0;
    /**
     * 表示滚动到上一张图片这个动作
     */
    private static final int SCROLL_PREVIOUS = 1;
    
    private static final int SCROLL_BACK = 2;
    
    
    public ImageSwitcher(Context context, AttributeSet attrs) {
        super(context, attrs);
        scroller = new Scroller(context);
        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }
    
    /**
     * 当View被添加到Window容器的时候才开始执行:生命周期依次先后 onMeasure > onLayout > onDraw >onAttachedToWindow
     */
    @Override
    protected void onAttachedToWindow(){
        super.onAttachedToWindow();
        mHandler.sendEmptyMessage(START_MSG); //发送消息让图片自动开始滚动
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if(changed || forceToRelayout){
            imageCount = getChildCount();
            mImageWidth = getMeasuredWidth();
            mImageHeight = getMeasuredHeight();
            int marginLeft = 0;
            scroller.abortAnimation(); //设置scroller为滚动状态
            this.scrollTo(0, 0); //每次重新布局时候,重置滚动初始位置
            int[] items = { getIndexForItem(1), getIndexForItem(2),
                    getIndexForItem(3), getIndexForItem(4),
                    getIndexForItem(5) };
            imageItems = items;
            for (int i = 0; i < items.length; i++) {
                ImageView childView = (ImageView)getChildAt(items[i]);
                childView.layout(marginLeft, 0, marginLeft
                        + mImageWidth , mImageHeight);
                marginLeft = marginLeft + mImageWidth;
            }
            refreshImageView();
            forceToRelayout = false;
        }
    }
    
    private void refreshImageView(){
        for (int i = 0; i < imageItems.length; i++) {
            ImageView childView = (ImageView)getChildAt(imageItems[i]);
            childView.invalidate();
        }
    }
    

    private int getIndexForItem(int item) {
        int index = -1;
        index = mIndex + item - 3;
        while (index < 0) {
            index = index + imageCount;
        }
        while (index > imageCount - 1) {
            index = index - imageCount;
        }
        return index;
    }
    
    @Override
    public boolean  onInterceptTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        if ((action == MotionEvent.ACTION_MOVE)
                && (mTouchState != TOUCH_STATE_REST)) {
            return true;        
        }
        float xLoc = ev.getX();
        switch(action){
        case MotionEvent.ACTION_DOWN:
            mMotionX = xLoc;
            mTouchState = TOUCH_STATE_REST;
            Log.e(TAG, "onInterceptTouchEvent ACTION_DOWN");  
            break;
        case MotionEvent.ACTION_MOVE:
            Log.e(TAG, "onInterceptTouchEvent ACTION_MOVE");  
             int xDif = (int)Math.abs(mMotionX - xLoc);
             if(xDif > mTouchSlop){  //当我们的水平距离滚动达到我们滚动的最小距离,开始拦截ViewGroup的事件给子控件分发
                 mTouchState = TOUCH_STATE_SCROLLING;
             }
            break;
        case MotionEvent.ACTION_UP:
            Log.e(TAG, "onInterceptTouchEvent ACTION_UP");  
            mTouchState = TOUCH_STATE_REST;
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.e(TAG, "onInterceptTouchEvent ACTION_CANCEL");
            mTouchState = TOUCH_STATE_REST;
            break;
        default:
            Log.e(TAG, "onInterceptTouchEvent DEFAULT");
            mTouchState = TOUCH_STATE_REST;
            break;
        }
        return mTouchState != TOUCH_STATE_REST;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(scroller.isFinished()){ //scroller还没有开始或者已经完成,以下代码在手指滑动的时候才开始执行
            if (mVelocityTracker == null) {
                mVelocityTracker = VelocityTracker.obtain();
            }
            mVelocityTracker.addMovement(event);
            int action = event.getAction();
            float x = event.getX();
            switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 记录按下时的横坐标
                mMotionX = x;
            case MotionEvent.ACTION_MOVE:
                int disX = (int)(mMotionX - x);
                mMotionX = x;
                scrollBy(disX, 0);
                break;
            case MotionEvent.ACTION_UP:
                mVelocityTracker.computeCurrentVelocity(1000);
                int velocityX = (int) mVelocityTracker.getXVelocity();
                if (judeScrollToNext(velocityX)) {
                    // 下一张图
                    scrollToNext();
                } else if (judeScrollToPrevious(velocityX)) {
                    //上一张图
                    scrollToPrevious();
                } else {
                    // 当前图片
                    scrollBack();
                }
                if (mVelocityTracker != null) {
                    mVelocityTracker.recycle();
                    mVelocityTracker = null;
                }
                mHandler.sendEmptyMessageDelayed(HANDLE_MSG, PHOTO_CHANGE_TIME);
                return true;
            }
        }
        return false;
    }
    

    private void scrollBack() {
        if (scroller.isFinished()) {
            beginScroll(getScrollX(), 0, -getScrollX(), 0,SCROLL_BACK);
        }
    }

    private void scrollToPrevious() {
        if(scroller.isFinished()){
            setImageSwitchIndex(SCROLL_PREVIOUS);
            int disX = -mImageWidth - getScrollX();
            beginScroll(getScrollX(), 0, disX, 0,SCROLL_PREVIOUS);
        }
    }

    private void scrollToNext() {
        if (scroller.isFinished()) {
            setImageSwitchIndex(SCROLL_NEXT);
            int disX = mImageWidth - getScrollX();
            beginScroll(getScrollX(), 0, disX, 0,SCROLL_NEXT);
        }
    }
    
    /**
     * 图片开始滑动
     */
    private void beginScroll(int startX, int startY, int dx, int dy,
            final int action) {
        int duration = (int) (700f / mImageWidth * Math.abs(dx));
        scroller.startScroll(startX, startY, dx, dy, duration);
        invalidate();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (action == SCROLL_NEXT || action == SCROLL_PREVIOUS) {
                    forceToRelayout = true;
                    requestLayout();
                }
            }
        }, duration);
    }

    private void setImageSwitchIndex(int action) {
        if(action == SCROLL_NEXT){
            if(mIndex < imageCount){
                mIndex++;
            }else{
                mIndex = 0;
            }
        }else if(action == SCROLL_PREVIOUS){
            if(mIndex > 0){
                mIndex--;
            }else{
                mIndex = imageCount -1;
            }
        }
        
    }

    /**
     * 判断时候滑向前一个
     * @param velocityX
     * @return
     */
    private boolean judeScrollToPrevious(int velocityX) {
        return velocityX > SNAP_VELOCITY || getScrollX() < -mImageWidth / 2;
    }

    /**
     * 判断时候滑向后一个
     * @param velocityX
     * @return
     */
    private boolean judeScrollToNext(int velocityX) {
        return velocityX < -SNAP_VELOCITY|| getScrollX() > mImageWidth / 2;
    }
    
    @Override
    public void computeScroll() {    
        if (scroller.computeScrollOffset()) {
            scrollTo(scroller.getCurrX(), scroller.getCurrY());
            //刷新View 否则效果可能有误差
            postInvalidate();
        }
    }
    
}



布局


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
     <com.zhanglei.imageswitcher.ImageSwitcher
        android:id="@+id/image_switch_view"
        android:layout_width="match_parent"
        android:layout_height="200dp" >
        <ImageView
            android:id="@+id/image1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:clickable="true"
            android:src="@drawable/item01"/>
        <ImageView
            android:id="@+id/image2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:clickable="true"
            android:src="@drawable/item02"/>
        <ImageView
            android:id="@+id/image3"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:clickable="true"
            android:src="@drawable/item03"/>
        <ImageView
            android:id="@+id/image4"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:clickable="true"
            android:src="@drawable/item04"/>
         <ImageView
            android:id="@+id/image5"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="fitXY"
            android:clickable="true"
            android:src="@drawable/item05"/>
    </com.zhanglei.imageswitcher.ImageSwitcher>


</RelativeLayout>
效果就不展示了,因为我不会录像,嘎嘎

拿来就可以用哦


这篇关于imageswitch的自动切换的一个工具类的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/596634

相关文章

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

java图像识别工具类(ImageRecognitionUtils)使用实例详解

《java图像识别工具类(ImageRecognitionUtils)使用实例详解》:本文主要介绍如何在Java中使用OpenCV进行图像识别,包括图像加载、预处理、分类、人脸检测和特征提取等步骤... 目录前言1. 图像识别的背景与作用2. 设计目标3. 项目依赖4. 设计与实现 ImageRecogni

IDEA如何切换数据库版本mysql5或mysql8

《IDEA如何切换数据库版本mysql5或mysql8》本文介绍了如何将IntelliJIDEA从MySQL5切换到MySQL8的详细步骤,包括下载MySQL8、安装、配置、停止旧服务、启动新服务以及... 目录问题描述解决方案第一步第二步第三步第四步第五步总结问题描述最近想开发一个新应用,想使用mysq

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

基于C#实现PDF文件合并工具

《基于C#实现PDF文件合并工具》这篇文章主要为大家详细介绍了如何基于C#实现一个简单的PDF文件合并工具,文中的示例代码简洁易懂,有需要的小伙伴可以跟随小编一起学习一下... 界面主要用于发票PDF文件的合并。经常出差要报销的很有用。代码using System;using System.Col

redis-cli命令行工具的使用小结

《redis-cli命令行工具的使用小结》redis-cli是Redis的命令行客户端,支持多种参数用于连接、操作和管理Redis数据库,本文给大家介绍redis-cli命令行工具的使用小结,感兴趣的... 目录基本连接参数基本连接方式连接远程服务器带密码连接操作与格式参数-r参数重复执行命令-i参数指定命

SpringBoot项目启动后自动加载系统配置的多种实现方式

《SpringBoot项目启动后自动加载系统配置的多种实现方式》:本文主要介绍SpringBoot项目启动后自动加载系统配置的多种实现方式,并通过代码示例讲解的非常详细,对大家的学习或工作有一定的... 目录1. 使用 CommandLineRunner实现方式:2. 使用 ApplicationRunne

Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单

《Springboot的ThreadPoolTaskScheduler线程池轻松搞定15分钟不操作自动取消订单》:本文主要介绍Springboot的ThreadPoolTaskScheduler线... 目录ThreadPoolTaskScheduler线程池实现15分钟不操作自动取消订单概要1,创建订单后

Python pyinstaller实现图形化打包工具

《Pythonpyinstaller实现图形化打包工具》:本文主要介绍一个使用PythonPYQT5制作的关于pyinstaller打包工具,代替传统的cmd黑窗口模式打包页面,实现更快捷方便的... 目录1.简介2.运行效果3.相关源码1.简介一个使用python PYQT5制作的关于pyinstall

python实现自动登录12306自动抢票功能

《python实现自动登录12306自动抢票功能》随着互联网技术的发展,越来越多的人选择通过网络平台购票,特别是在中国,12306作为官方火车票预订平台,承担了巨大的访问量,对于热门线路或者节假日出行... 目录一、遇到的问题?二、改进三、进阶–展望总结一、遇到的问题?1.url-正确的表头:就是首先ur