Android自定义控件, 实现图片无限滚动

效果图:



实现原理:通过监听OnTouch, 记录手指的滑动距离,然后将图片绘制到界面上。绘制过程中分成三个部分, 左边、中间、右边。 当滑动距离等于0时,则只绘制中间部分,当滑动距离大于0时,说明是右滑,则根据滑动距离,将右边的也绘制出来。 小于0,则反之。


部分绘图逻辑代码:(ps:当一个屏幕存在多张图片且滑动很快时,会出现图片间隔不是固定的bug, 暂时用第二个 if 修复闭嘴)

        if (mOffsetX > 0) {
            // 显示将上一个元素
            b = getBitmap(mCurrentItemIndex - 1);
            src.right = b.getWidth();
            src.bottom = b.getHeight();
            dest.top = mItemIntervalY;
            dest.bottom = dest.top + mItemHeight;
            dest.left = (int) (mOffsetX - mItemWidth);
            dest.right = dest.left + mItemWidth;
            canvas.drawBitmap(b, src, dest, mPaint);
            // 防止滑动过快 左边出现黑边
            if (dest.left > 0) {
                b = getBitmap(mCurrentItemIndex - 2);
                src.right = b.getWidth();
                src.bottom = b.getHeight();
                dest.top = mItemIntervalY;
                dest.bottom = dest.top + mItemHeight;
                dest.right = dest.left - mItemIntervalX;
                dest.left = dest.right - mItemWidth;
                canvas.drawBitmap(b, src, dest, mPaint);
            }
        }

 

具体代码:

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.*;

import java.util.List;

/**
 * Created by Yx on 14-5-18.
 */
public class LoopSwitcherView extends View implements View.OnTouchListener {

    /**
     * 手指滑动需要达到的最小速度。
     */
    private static final int SNAP_VELOCITY = 200;

    /**
     * 自动播放延迟时间
     */
    private static final long AUTO_PLAY_TIME = 3000;

    private static final float MIN_OFFSET_X = 100;

    /**
     * 当前显示的元素的下标。
     */
    private int mCurrentItemIndex = 0;

    /**
     * 当前屏幕可见的元素个数
     */
    private int mVisibleItemCount;

    /**
     * 每个元素的宽度
     */
    private int mItemWidth;

    /**
     * 每个元素的宽度
     */
    private int mItemHeight;

    /**
     * 元素之间的横坐标间隔
     */
    private int mItemIntervalX = 0;

    /**
     * 元素之间的纵坐标间隔
     */
    private int mItemIntervalY = 0;

    /**
     * 保存所有要显示的图片
     */
    private List<Bitmap> mBitmaps;

    /**
     * 记录手指按下时的横坐标。
     */
    private float mDownX;

    /**
     * 记录手指按下时的纵坐标
     */
    private float mDownY;

    /**
     * 记录手机抬起时的横坐标。
     */
    private float mUpX;

    /**
     * 记录图片偏移量
     */
    private float mOffsetX = 0;

    /**
     * 手指允许偏移距离的平方
     */
    private float mTouchSlopSquare;

    /**
     * 记录手指是否在单击允许范围内
     */
    private boolean mAlwaysInTapRegion;

    private OnImageItemClickListener mOnImageItemClickListener;

    /**
     * 用于计算手指滑动的速度。
     */
    private VelocityTracker mVelocityTracker;

    /**
     * 负责滚动
     */
    private ScrollTask mScrollTask;

    private boolean mIsAutoPlay;

    private Paint mPaint;

    public LoopSwitcherView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
        setOnTouchListener(this);

        final ViewConfiguration configuration = ViewConfiguration.get(context);
        int touchSlop = configuration.getScaledTouchSlop();
        mTouchSlopSquare = touchSlop * touchSlop;
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LoopSwitcherView);
        mIsAutoPlay = ta.getBoolean(R.styleable.LoopSwitcherView_auto_play, true);
        mVisibleItemCount = ta.getInt(R.styleable.LoopSwitcherView_visible_item_count, 0);
        mItemWidth = ta.getD
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值