安卓常用自定义View

圆形ImageView

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.widget.ImageView;

/**
 * 圆形ImageView,用于显示用户头像
 */
public class RoundImageView extends ImageView {
    private static final String STATE_INSTANCE = "state_instance";
    private static final String RADIUS = "radius";
    private int sideColor = 0xFFFFFFFF;
    /**
     * 绘图的Paint
     */
    private Paint mBitmapPaint;
    /**
     * 圆角的半径
     */
    private int mRadius;
    /**
     * 3x3 矩阵,主要用于缩小放大
     */
    private Matrix mMatrix;
    /**
     * 渲染图像,使用图像为绘制图形着色
     */
    private BitmapShader mBitmapShader;
    /**
     * view的宽度
     */
    private int mWidth;

    public RoundImageView(Context context) {
        this(context, null);
    }

    public RoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mMatrix = new Matrix();
        mBitmapPaint = new Paint();
        mBitmapPaint.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = getMeasuredWidth();
        int height = getMeasuredHeight();
        mWidth = Math.min(width, height);
        mRadius = mWidth / 2;
    }

    /**
     * 初始化BitmapShader
     */
    private void setUpShader() {
        Drawable drawable = getDrawable();
        Bitmap bmp = drawableToBitamp(drawable);
        if (drawable == null || bmp == null) {
            return;
        }

        // 将bmp作为着色器,就是在指定区域内绘制bmp
        mBitmapShader = new BitmapShader(bmp, TileMode.CLAMP, TileMode.CLAMP);
        float scale = 1.0f;
        // 拿到bitmap宽或高的小值
        int bSize = Math.min(bmp.getWidth(), bmp.getHeight());
        scale = mWidth * 1.0f / bSize;

        // shader的变换矩阵,我们这里主要用于放大或者缩小
        mMatrix.setScale(scale, scale);
        // 设置变换矩阵
        mBitmapShader.setLocalMatrix(mMatrix);
        // 设置shader
        mBitmapPaint.setShader(mBitmapShader);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (getDrawable() == null) {
            return;
        }
        setUpShader();

        canvas.drawColor(sideColor, PorterDuff.Mode.SRC_OVER);
        canvas.drawCircle(mRadius, mRadius, mRadius, mBitmapPaint);
    }

    /**
     * drawable转bitmap
     *
     * @param drawable
     * @return
     */
    protected Bitmap drawableToBitamp(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            BitmapDrawable bd = (BitmapDrawable) drawable;
            return bd.getBitmap();
        }
        int w = drawable.getIntrinsicWidth();
        int h = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_4444);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, w, h);
        drawable.draw(canvas);
        return bitmap;
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(STATE_INSTANCE, super.onSaveInstanceState());
        bundle.putInt(RADIUS, mRadius);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            super.onRestoreInstanceState(((Bundle) state)
                    .getParcelable(STATE_INSTANCE));
            this.mRadius = bundle.getInt(RADIUS);
        } else {
            super.onRestoreInstanceState(state);
        }
    }

    public void setBackGroundColor(int color) {
        this.sideColor = color;
        invalidate();
    }

    public int getBackGroundColor(){
        return sideColor;
    }
}

可缩放的ImageView

import android.content.Context;
import android.content.DialogInterface.OnDismissListener;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Build.VERSION;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.ImageView;

/**
 * 可缩放的ImageView,用于图片浏览
 */
public class ScaleImageView extends ImageView {
    private Context mContext;
    private float MAX_SCALE = 8f;

    private Matrix mMatrix;
    private final float[] mMatrixValues = new float[9];

    // display width height.
    private int mWidth;
    private int mHeight;

    private int mIntrinsicWidth;
    private int mIntrinsicHeight;

    private float mScale;
    private float mMinScale = 0.1f;

    private float mPrevDistance;
    private boolean isScaling;

    private int mPrevMoveX;
    private int mPrevMoveY;

    private int mLastX;
    private int mLastY;

    private GestureDetector mDetector;

    private float mSlop;
    private OnDismissListener mListener;
    private float mDefaultScale = 0f;

    public ScaleImageView(Context context, AttributeSet attr) {
        super(context, attr);
        this.mContext = context;
        initialize();
    }

    public ScaleImageView(Context context) {
        super(context);
        this.mContext = context;
        initialize();
    }

    @Override
    public void setImageBitmap(Bitmap bm) {
        super.setImageBitmap(bm);
        this.initialize();
    }

    @Override
    public void setImageResource(int resId) {
        super.setImageResource(resId);
        this.initialize();
    }

    private void initialize() {
        this.setScaleType(ScaleType.MATRIX);
        this.mMatrix = new Matrix();
        Drawable d = getDrawable();
        if (d != null) {
            mIntrinsicWidth = d.getIntrinsicWidth();
            mIntrinsicHeight = d.getIntrinsicHeight();
        }
        // 双击的情况。首先放大到图片的最大比例8,再双击则显示原图大小
        mDetector = new GestureDetector(mContext, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onDoubleTap(MotionEvent e) {
                maxZoomTo((int) e.getX(), (int) e.getY());
                cutting();
                return super.onDoubleTap(e);
            }
        });
        mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    public void updateScale() {
        mWidth = getWidth();
        mHeight = getHeight();
        mMatrix.reset();

        mScale = (float) mWidth / (float) mIntrinsicWidth;
        if (mScale * mIntrinsicHeight > mHeight) {
            mScale = (float) mHeight / (float) mIntrinsicHeight;
        }
        zoomTo(mScale, mWidth / 2, mHeight / 2);
        cutting();
    }

    @Override
    protected boolean setFrame(int l, int t, int r, int b) {
        mWidth = r - l;
        mHeight = b - t;

        mMatrix.reset();
        int r_norm = r - l;
        mScale = (float) r_norm / (float) mIntrinsicWidth;
        if (mScale * mIntrinsicHeight > mHeight) {
            mScale = (float) mHeight / (float) mIntrinsicHeight;
        }
        zoomTo(mScale, mWidth / 2, mHeight / 2);
        cutting();
        return super.setFrame(l, t, r, b);
    }

    protected float getValue(Matrix matrix, int whichValue) {
        matrix.getValues(mMatrixValues);
        return mMatrixValues[whichValue];
    }

    protected float getScale() {
        return getValue(mMatrix, Matrix.MSCALE_X);
    }

    public float getTranslateX() {
        return getValue(mMatrix, Matrix.MTRANS_X);
    }

    protected float getTranslateY() {
        return getValue(mMatrix, Matrix.MTRANS_Y);
    }

    protected void maxZoomTo(int x, int y) {
        float scale = 0;
        if (MAX_SCALE != getScale() && (Math.abs(getScale() - MAX_SCALE)) > 0.1f) {
            scale = MAX_SCALE / getScale();
        } else {
            scale = mMinScale / getScale();
        }
        zoomTo(scale, x, y);
    }

    public void reset() {
        mMatrix.reset();
        mScale = mMinScale;
        setImageMatrix(mMatrix);
    }

    public void zoomTo(float scale, int x, int y) {
        if (getScale() * scale < mMinScale) {
            return;
        }
        if (scale >= 1 && getScale() * scale > MAX_SCALE) {
            return;
        }
        mMatrix.postScale(scale, scale);
        // move to center
        mMatrix.postTranslate(-(mWidth * scale - mWidth) / 2, -(mHeight * scale - mHeight) / 2);

        // move x and y distance
        mMatrix.postTranslate(-(x - (mWidth / 2)) * scale, 0);
        mMatrix.postTranslate(0, -(y - (mHeight / 2)) * scale);
        setImageMatrix(mMatrix);
    }

    public void cutting() {
        int width = (int) (mIntrinsicWidth * getScale());
        int height = (int) (mIntrinsicHeight * getScale());
        if (getTranslateX() < -(width - mWidth)) {
            mMatrix.postTranslate(-(getTranslateX() + width - mWidth), 0);
        }
        if (getTranslateX() > 0) {
            mMatrix.postTranslate(-getTranslateX(), 0);
        }
        if (getTranslateY() < -(height - mHeight)) {
            mMatrix.postTranslate(0, -(getTranslateY() + height - mHeight));
        }
        if (getTranslateY() > 0) {
            mMatrix.postTranslate(0, -getTranslateY());
        }
        if (width < mWidth) {
            mMatrix.postTranslate((mWidth - width) / 2, 0);
        }
        if (height < mHeight) {
            mMatrix.postTranslate(0, (mHeight - height) / 2);
        }
        setImageMatrix(mMatrix);
    }

    private float distance(float x0, float x1, float y0, float y1) {
        float x = x0 - x1;
        float y = y0 - y1;
        return (float) Math.sqrt(x * x + y * y);
    }

    private float dispDistance() {
        return (float) Math.sqrt(mWidth * mWidth + mHeight * mHeight);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (isGingerbread() || event.getAction() != MotionEvent.ACTION_MOVE) {
            return super.dispatchTouchEvent(event);
        }
        if (mDefaultScale == 0f) {
            mDefaultScale = mScale;
        }
        if (getScale() - 1.0f >= 0.01f && !checkEdge(event)) {// 放大且没有移动到边缘,此时事件交给子控件处理
            getParent().requestDisallowInterceptTouchEvent(true);
        } else {
            getParent().requestDisallowInterceptTouchEvent(false);// 交给ViewPager处理
        }
        return super.dispatchTouchEvent(event);
    }

    @SuppressWarnings("deprecation")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mDetector.onTouchEvent(event)) {
            return true;
        }
        int touchCount = event.getPointerCount();
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_1_DOWN:
            case MotionEvent.ACTION_POINTER_2_DOWN:
                if (touchCount >= 2) {
                    float distance = distance(event.getX(0), event.getX(1), event.getY(0),
                            event.getY(1));
                    mPrevDistance = distance;
                    isScaling = true;
                } else {
                    mPrevMoveX = (int) event.getX();
                    mPrevMoveY = (int) event.getY();
                    mLastX = mPrevMoveX;
                    mLastY = mPrevMoveY;
                }
            case MotionEvent.ACTION_MOVE:
                if (touchCount >= 2 && isScaling) {
                    float dist = distance(event.getX(0), event.getX(1), event.getY(0),
                            event.getY(1));
                    // if ( Math.abs(dist - mPrevDistance) < mSlop ) {
                    // Log.d("", "######## move dis " + dist + "   " + mSlop);
                    // return false;
                    // }
                    float scale = (dist - mPrevDistance) / dispDistance();
                    mPrevDistance = dist;
                    scale += 1;
                    scale = scale * scale;
                    zoomTo(scale, mWidth / 2, mHeight / 2);
                    cutting();
                } else if (!isScaling) {
                    int distanceX = mPrevMoveX - (int) event.getX();
                    int distanceY = mPrevMoveY - (int) event.getY();
                    mPrevMoveX = (int) event.getX();
                    mPrevMoveY = (int) event.getY();
                    mMatrix.postTranslate(-distanceX, -distanceY);
                    cutting();
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_POINTER_2_UP:
                if (event.getPointerCount() <= 1) {
                    isScaling = false;
                    checkExecuteCallback(event);
                } else {
                    if (mDefaultScale == 0f) {
                        mDefaultScale = mScale;
                    }
                }
                mPrevDistance = 0;
                mPrevMoveX = 0;
                mPrevMoveY = 0;
                mLastX = 0;
                mLastY = 0;
                break;
        }
        return true;
    }

    /**
     * 检查是否执行回调
* * @param event */
private void checkExecuteCallback(MotionEvent event) { int delta = (int) distance(mLastX, event.getX(), mLastY, event.getY()); if (delta < mSlop && mListener != null) { // 此时仅仅是点击,执行回调,dismiss dialog mListener.onDismiss(null); } } /** * 检查是否滑动到放大的边缘
* * @param event * @return */
private boolean checkEdge(MotionEvent event) { if (isGingerbread()) { return super.dispatchTouchEvent(event); } mapDisplayRect(); // Log.d("", "#############----" +mDisplayRect.left + " " + // mDisplayRect.right + " " + getWidth() + " " + mSlop); // Log.d("", "#############----" +getScale() + " " + mDefaultScale); // 已经滑动到边缘 if (Math.abs(mDisplayRect.left) <= mSlop || (Math.abs(mDisplayRect.left) > mSlop && getScale() - mDefaultScale <= 0.5f) || Math.abs(mDisplayRect.right - getWidth()) < mSlop || (Math.abs(mDisplayRect.right - getWidth()) >= mSlop && getScale() - mDefaultScale <= 0.5f)) { return true; } return false; } private final RectF mDisplayRect = new RectF(); /** * 将图片的尺寸矩阵map成RectF
* * @return */
private RectF mapDisplayRect() { Drawable d = getDrawable(); if (null != d) { mDisplayRect.set(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); getImageMatrix().mapRect(mDisplayRect); return mDisplayRect; } return null; } public void setOndismissListener(OnDismissListener listener) { mListener = listener; } private boolean isGingerbread() { if (VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD) { return true; } return false; } }

获取验证码倒计时按钮

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 鉴于经常用到获取验证码倒计时按钮 在网上也没有找到理想的 自己写一个
 * PS: 由于发现timer每次cancle()之后不能重新schedule方法,所以计时完毕只恐timer.
 * 每次开始计时的时候重新设置timer, 没想到好办法初次下策
 * 注意把该类的onCreate()onDestroy()和activity的onCreate()onDestroy()同步处理
 */
public class TimeButton extends Button implements OnClickListener {
    private long lenght = 120 * 1000;// 倒计时长度,这里给了默认60秒
    private String textafter = "重新获取";
    private String textbefore = "获取验证码";
    private final String TIME = "time";
    private final String CTIME = "ctime";
    private OnClickListener mOnclickListener;
    private Timer t;
    private TimerTask tt;
    private long time;
    Map map = new HashMap();

    public TimeButton(Context context) {
        this(context, null);
    }

    public TimeButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOnClickListener(this);
    }

    @SuppressLint("HandlerLeak")
    Handler han = new Handler() {
        public void handleMessage(android.os.Message msg) {
            TimeButton.this.setText(time / 1000 + textafter);
            time -= 1000;
            if (time < 0) {
                TimeButton.this.setEnabled(true);
                TimeButton.this.setText(textbefore);
                clearTimer();
            }
        }

        ;
    };

    private void initTimer() {
        time = lenght;
        t = new Timer();
        tt = new TimerTask() {

            @Override
            public void run() {
                han.sendEmptyMessage(0x01);
            }
        };
    }

    private void clearTimer() {
        if (tt != null) {
            tt.cancel();
            tt = null;
        }
        if (t != null)
            t.cancel();
        t = null;
    }

    @Override
    public void setOnClickListener(OnClickListener l) {
        if (l instanceof TimeButton) {
            super.setOnClickListener(l);
        } else {
            this.mOnclickListener = l;
        }
    }

    @Override
    public void onClick(View v) {
        if (mOnclickListener != null)
            mOnclickListener.onClick(v);
        initTimer();
        this.setText(time / 1000 + textafter);
        this.setEnabled(false);
        t.schedule(tt, 0, 1000);
        // t.scheduleAtFixedRate(task, delay, period);
    }

    /**
     * 和activity的onDestroy()方法同步
     */
    public void onDestroy() {
        if (map == null)
            map = new HashMap();
        map.put(TIME, time);
        map.put(CTIME, System.currentTimeMillis());
        clearTimer();
    }

    /**
     * 和activity的onCreate()方法同步
     */
    public void onCreate(Bundle bundle) {
        if (map == null)
            return;
        if (map.size() <= 0)// 这里表示没有上次未完成的计时
            return;
        long time = System.currentTimeMillis() - map.get(CTIME) - map.get(TIME);
        map.clear();
        if (time > 0) {
            return;
        } else {
            initTimer();
            this.time = Math.abs(time);
            t.schedule(tt, 0, 1000);
            this.setText(time + textafter);
            this.setEnabled(false);
        }
    }

    /**
     * 设置计时时候显示的文本
     */
    public TimeButton setTextAfter(String text1) {
        this.textafter = text1;
        return this;
    }

    /**
     * 设置点击之前的文本
     */
    public TimeButton setTextBefore(String text0) {
        this.textbefore = text0;
        this.setText(textbefore);
        return this;
    }

    /**
     * 设置到计时长度
     */
    public TimeButton setLenght(long lenght) {
        this.lenght = lenght;
        return this;
    }
}

下拉刷新上拉加载

import android.content.Context;
import android.graphics.Color;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;

/**
 * 继承自SwipeRefreshLayout,从而实现滑动到底部时上拉加载更多的功能.
 */
public class RefreshLayout<T extends AbsListView> extends SwipeRefreshLayout implements OnScrollListener {

    /**
     * 滑动到最下面时的上拉操作
     */
    private int mTouchSlop;

    /**
     *
     */
    protected T mAbsListView;

    /**
     * ListView滚动监听器,用于外部
     */
    private OnScrollListener mListViewOnScrollListener;

    private OnResultListener mScrollListener;

    /**
     * 上拉监听器, 到了最底部的上拉加载操作
     */
    private OnLoadListener mOnLoadListener;
    /**
     * 按下时的y坐标
     */
    protected int mYDown;
    /**
     * 抬起时的y坐标, 与mYDown一起用于滑动到底部时判断是上拉还是下拉
     */
    protected int mLastY;
    /**
     * 是否在加载中 ( 上拉加载更多 )
     */
    protected boolean isLoading = false;

    private int mColor1;
    private int mColor2;

    /**
     * ListView的加载中footer
     */
    protected View mFooterView;

    private int mScrollDirection = 0; // 0:代表向下滚动;1:向上滚动

    /**
     * @param context
     */
    public RefreshLayout(Context context) {
        this(context, null);
    }

    public RefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);

        if (isInEditMode()) {
            return;
        }

        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

        // 获取color资源的id
        mColor1 = Color.parseColor("#FFB0C4DE");
        mColor2 = Color.parseColor("#FF87CEFA");

    }

    @SuppressWarnings("deprecation")
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

        if (isInEditMode()) {
            return;
        }
        super.onLayout(changed, left, top, right, bottom);

        // 初始化ListView对象
        if (mAbsListView == null) {
            getRefreshView();
        }

        // 设置颜色
        this.setColorScheme(mColor1, mColor2);
    }

    /**
     * 获取ListView对象
     */
    @SuppressWarnings("unchecked")
    protected void getRefreshView() {
        int childs = getChildCount();
        if (childs <= 0) {
            return;
        }
        View childView = null;
        for (int i = 0; i < childs; i++) {
            childView = getChildAt(i);
            if (childView instanceof AbsListView) {
                mAbsListView = (T) childView;
                // 设置滚动监听器给ListView, 使得滚动的情况下也可以自动加载
                mAbsListView.setOnScrollListener(this);
            }
        }
    }

    @SuppressWarnings("unchecked")
    public T findRefreshViewById(int id) {
        mAbsListView = (T) this.findViewById(id);
        mAbsListView.setOnScrollListener(this);
        return mAbsListView;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        try {
            return dealTouchEvent(event);
        } catch (IllegalStateException exception) {
        }
        return true;
    }

    private boolean dealTouchEvent(MotionEvent event) {
        final int action = event.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                // 按下
                mYDown = (int) event.getRawY();
                break;

            case MotionEvent.ACTION_MOVE:
                // 移动
                mLastY = (int) event.getRawY();
                break;

            case MotionEvent.ACTION_UP:
                // 抬起
                if (canLoad()) {
                    loadData();
                }
                if (mScrollListener != null) {
                    if (isPullUp()) {
                        mScrollDirection = 1;
                    } else {
                        mScrollDirection = 0;
                    }
                }
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    /**
     * 是否可以加载更多, 条件是到了最底部, listview不在加载中, 且为上拉操作.
     *
     * @return
     */
    private boolean canLoad() {
        return isBottom() && !isLoading && isPullUp() && mOnLoadListener != null;
    }

    /**
     * 判断是否到了最底部
     */
    private boolean isBottom() {
        if (mAbsListView == null) {
            getRefreshView();
        }
        // 已经到最后一项且可见的第一项>0
        if (mAbsListView != null && mAbsListView.getAdapter() != null) {
            int childCount = mAbsListView.getAdapter().getCount();
            return childCount > 1
                    && mAbsListView.getLastVisiblePosition() == childCount - 1;
            // && mAbsListView.getFirstVisiblePosition() >= 0;
        }
        return false;
    }

    /**
     * 是否是上拉操作
     *
     * @return
     */
    private boolean isPullUp() {
        return mLastY > 0 && (mYDown - mLastY) >= mTouchSlop * 3;
    }

    /**
     * 如果到了最底部,而且是上拉操作.那么执行onLoad方法
     */
    protected void loadData() {
        setLoading(true);
        mOnLoadListener.onLoad();
    }

    /**
     * @param loading
     */
    public void setLoading(boolean loading) {
        isLoading = loading;
    }

    public AbsListView getListView() {
        if (mAbsListView == null) {
            getRefreshView();
        }
        return mAbsListView;
    }

    /**
     * 使外部可以监听到listview的滚动
     *
     * @param listener
     */
    public void addOnScrollListener(OnScrollListener listener) {
        mListViewOnScrollListener = listener;
    }

    /**
     * @param loadListener
     */
    public void setOnLoadListener(OnLoadListener loadListener) {
        mOnLoadListener = loadListener;
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        // 回调给外部的监听器
        if (mListViewOnScrollListener != null) {
            mListViewOnScrollListener.onScrollStateChanged(view, scrollState);
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                         int totalItemCount) {

        // 回调给外部的监听器
        if (mListViewOnScrollListener != null) {
            mListViewOnScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,
                    totalItemCount);
        }

        if (mScrollListener != null) {
            mScrollListener.onResult(mScrollDirection);
        }

        // 滚动时到了最底部也可以加载更多
        if (canLoad()) {
            loadData();
        }
    }

    /**
     * 加载更多的监听器
     */
    public static interface OnLoadListener {
        public void onLoad();
    }

    public void setOnScrollDirectionListener(OnResultListener listener) {
        mScrollListener = listener;
    }

    public interface OnResultListener {
        void onResult(int var1);
    }
}

你可能感兴趣的:(安卓)