Android 3D球形水平圆形旋转,旋转动态更换图片

        看效果图

1、事件监听类

OnItemClickListener:3D旋转视图项点击监听器接口

public interface OnItemClickListener {
    /**
     * 当旋转视图中的项被点击时调用
     *
     * @param view     被点击的视图对象
     * @param position 被点击项在旋转视图中的位置索引(从0开始)
     */
    void onItemClick(View view, int position);
}

OnItemSelectedListener:3D旋转视图项选中监听器接口

public interface OnItemSelectedListener {
    /**
     * 当旋转视图中的选中项发生变化时调用
     *
     * @param item 新选中项在旋转视图中的位置索引(从0开始)
     * @param view 新选中的视图对象
     */
    void selected(int item, View view);
}

OnLoopViewTouchListener:3D旋转视图触摸事件监听器接口

public interface OnLoopViewTouchListener {
    /**
     * 当旋转视图接收到触摸事件时调用
     *
     * @param event 触摸事件对象,包含触摸的类型、位置等信息
     */
    void onTouch(MotionEvent event);
}

2、3D水平旋转轮播控件

我这里是参考 https://github.com/yixiaolunhui/LoopRotarySwitch ,然后进行一个小改动。

LoopRotarySwitchViewHandler.java 轮播图自动滚动处理器

/**
 * 轮播图自动滚动处理器
 * 用于控制轮播图的自动滚动功能
 * 特点:
 * 1. 支持自定义滚动时间间隔
 * 2. 支持开启/关闭自动滚动
 * 3. 支持自定义滚动方向
 */
public abstract class LoopRotarySwitchViewHandler extends Handler {

    private boolean loop = false;           // 是否开启自动滚动
    public long loopTime = 3000;           // 滚动时间间隔(毫秒)
    public static final int msgid = 1000;  // 消息ID

    private Message msg = createMsg();     // 创建消息对象

    /**
     * 构造方法
     * @param time 滚动时间间隔(毫秒)
     */
    public LoopRotarySwitchViewHandler(int time) {
        this.loopTime = time;
    }

    /**
     * 处理消息
     * 当收到消息时,如果开启了自动滚动,则执行滚动并发送下一条消息
     */
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what = msgid) {
            case msgid:
                if (loop) {
                    doScroll();    // 执行滚动
                    sendMsg();     // 发送下一条消息
                }
                break;
        }
        super.handleMessage(msg);
    }

    /**
     * 设置是否开启自动滚动
     * @param loop true开启自动滚动,false关闭自动滚动
     */
    public void setLoop(boolean loop) {
        this.loop = loop;
        if (loop) {
            sendMsg();    // 开启自动滚动,发送消息
        } else {
            try {
                removeMessages(msgid);    // 关闭自动滚动,移除消息
            } catch (Exception e) {
            }
        }
    }

    /**
     * 发送消息
     * 移除之前的消息,创建新消息并延迟发送
     */
    private void sendMsg() {
        try {
            removeMessages(msgid);    // 移除之前的消息
        } catch (Exception e) {
        }
        msg = createMsg();    // 创建新消息
        this.sendMessageDelayed(msg, loopTime);    // 延迟发送消息
    }

    /**
     * 创建消息对象
     * @return 消息对象
     */
    public Message createMsg() {
        Message msg = new Message();
        msg.what = msgid;
        return msg;
    }

    /**
     * 设置滚动时间间隔
     * @param loopTime 时间间隔(毫秒)
     */
    public void setLoopTime(long loopTime) {
        this.loopTime = loopTime;
    }

    /**
     * 获取滚动时间间隔
     * @return 时间间隔(毫秒)
     */
    public long getLoopTime() {
        return loopTime;
    }

    /**
     * 获取是否开启自动滚动
     * @return true开启,false关闭
     */
    public boolean isLoop() {
        return loop;
    }

    /**
     * 执行滚动
     * 由子类实现具体的滚动逻辑
     */
    public abstract void doScroll();
}

LoopRotarySwitchView.java 水平旋转轮播控件

/**
 * 水平旋转轮播控件
 * 实现了一个可以水平旋转的轮播图效果,支持自动轮播和手动滑动
 * 特点:
 * 1. 支持水平方向旋转
 * 2. 支持自动轮播和手动滑动
 * 3. 支持自定义轮播方向
 * 4. 支持自定义轮播时间间隔
 * 5. 支持点击事件和选择事件
 */
public class LoopRotarySwitchView extends RelativeLayout {
    private final String TAG = "LoopRotarySwitchView";
    private final static int LoopR = 200; // 默认半径

    private final static int vertical = 0;   // 竖直方向
    private final static int horizontal = 1; // 水平方向

    private int mOrientation = horizontal;   // 当前方向,默认水平

    private Context mContext;                // 上下文

    private ValueAnimator restAnimator = null; // 回位动画
    private ValueAnimator rAnimation = null;   // 半径动画
    private ValueAnimator zAnimation = null;   // Z轴旋转动画
    private ValueAnimator xAnimation = null;   // X轴旋转动画

    private int loopRotationX = 0, loopRotationZ = 0; // X轴和Z轴的旋转角度

    private GestureDetector mGestureDetector = null; // 手势检测器

    private int selectItem = 0;    // 当前选中的item
    private int size = 4;          // item总数

    private float r = LoopR;       // 当前半径
    private float multiple = 2f;   // 倍数
    private float distance = multiple * r; // 观察距离,影响大小差异

    private float angle = 0;       // 当前旋转角度
    private float last_angle = 0;  // 上一次的角度

    private boolean autoRotation = false;    // 是否自动旋转
    private boolean touching = false;        // 是否正在触摸
    private boolean isAnimating = false;     // 是否正在动画中

    private AutoScrollDirection autoRotatinDirection = AutoScrollDirection.left; // 自动滚动方向

    private List<View> views = new ArrayList<View>(); // 子视图列表

    private OnItemSelectedListener onItemSelectedListener = null;    // 选择监听器
    private OnLoopViewTouchListener onLoopViewTouchListener = null;  // 触摸监听器
    private OnItemClickListener onItemClickListener = null;          // 点击监听器

    private boolean isCanClickListener = true; // 是否可以点击
    private float x;                          // 触摸的X坐标
    private float limitX = 30;                // 滑动阈值

    float spacingFactor = 1.2f; // 设置图片之间间距系数,可以调整这个值来改变间距

    private static boolean isFirstOpen = false; // 是否第一次打开这个页面


    /**
     * 自动滚动方向枚举
     */
    public enum AutoScrollDirection {
        left, right
    }

    /**
     * 构造方法
     */
    public LoopRotarySwitchView(Context context) {
        this(context, null);
    }

    /**
     * 构造方法
     */
    public LoopRotarySwitchView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    /**
     * 构造方法
     * 初始化控件的基本属性和动画
     */
    public LoopRotarySwitchView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        // 获取自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.LoopRotarySwitchView);
        mOrientation = typedArray.getInt(R.styleable.LoopRotarySwitchView_orientation, horizontal);
        autoRotation = typedArray.getBoolean(R.styleable.LoopRotarySwitchView_autoRotation, false);
        r = typedArray.getDimension(R.styleable.LoopRotarySwitchView_r, LoopR);
        int direction = typedArray.getInt(R.styleable.LoopRotarySwitchView_direction, 0);
        typedArray.recycle();

        // 初始化手势检测器
        mGestureDetector = new GestureDetector(context, getGeomeryController());

        // 设置旋转方向
        if (mOrientation == horizontal) {
            loopRotationZ = 0;
        } else {
            loopRotationZ = 90;
        }

        // 设置自动滚动方向
        if (direction == 0) {
            autoRotatinDirection = AutoScrollDirection.left;
        } else {
            autoRotatinDirection = AutoScrollDirection.right;
        }

        // 启动自动滚动
        loopHandler.setLoop(autoRotation);
    }

    /**
     * handler处理
     */
    @SuppressLint("HandlerLeak")
    LoopRotarySwitchViewHandler loopHandler = new LoopRotarySwitchViewHandler(3000) {
        @Override
        public void doScroll() {
            try {
                if (size != 0) {//判断自动滑动从那边开始
                    int perAngle = 0;
                    switch (autoRotatinDirection) {
                        case left:
                            perAngle = 360 / size;
                            break;
                        case right:
                            perAngle = -360 / size;
                            break;
                    }
                    if (angle == 360) {
                        angle = 0f;
                    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值