1. 程式人生 > >Android快速索引條控制元件QuickIndexBar

Android快速索引條控制元件QuickIndexBar

Android快速索引條控制元件

效果展示

程式碼實現

自定義view,畫出靜態的圖形

在canvas上指定好位置,用各種畫筆Paint,重要的是分析的過程。

    private Paint paint;
    private int cellWidth, cellHeight;

    private void init() {
        paint = new Paint();
        paint.setTextSize(40);
        paint.setColor(Color.WHITE);
        paint.setTypeface(Typeface.DEFAULT_BOLD);
        paint.setAntiAlias(true
); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (cellHeight == 0) cellHeight = getMeasuredHeight() / indexs.length; if (cellWidth == 0) cellWidth = getMeasuredWidth(); //分別畫26個字母 for (int i = 0; i < indexs.length; i++) { //先測量用此畫筆畫字母的大小,用一個矩形把它包裹起來,這樣方便計算字母的高度
Rect bounds = new Rect(); paint.getTextBounds(indexs[i], 0, indexs[i].length(), bounds); //計算畫每個字母的起始座標 float x = cellWidth / 2 - paint.measureText(indexs[i]) / 2; float y = cellHeight / 2 + bounds.height() / 2 + i * cellHeight; canvas.drawText(indexs[i], x, y, paint); } }

實現onTouch事件,完成動態效果

    private int lastIndex = -1;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
//        if (x >= 0 && x <= cellWidth) {  //只對quickindexbar的觸控事件有效
//            return false;
//        }
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                if (isSameIndex(y / cellHeight)) break;


                String word = indexs[((int) (y / cellHeight))];
                lastIndex = y / cellHeight;
                if (mIndexChangedListener != null) {
                    mIndexChangedListener.indexChanged(word);
                }

                break;
            case MotionEvent.ACTION_UP:
                lastIndex = -1;
                break;
            default:
                break;
        }

        //自行處理觸控事件,不向上傳遞
        return true;
    }

    /**
     * 當前的索引位置是否和上一個相等
     *
     * @return
     */
    private boolean isSameIndex(int currIndex) {
        return lastIndex == currIndex;
    }

    private IndexChangedListener mIndexChangedListener;

    public void setIndexChangedListener(IndexChangedListener indexChangedListener) {
        mIndexChangedListener = indexChangedListener;
    }

    public interface IndexChangedListener {
        void indexChanged(String word);
    }

給觸控事件新增更加人性化的互動

QuickIndexBar互動效果的實現

在處理onTouch事件時,改變畫筆的設定,畫出不同的圖案。

在onTouch中呼叫

    //重新呼叫onDraw
    invalidate();
在onDraw中增加下面的邏輯:
畫每個元素之前先設定不同的畫筆。    

    if (i == lastIndex) {               //正在touch的位置 需要更加人性化的互動
    paint.setTextSize(60);
    paint.setColor(Color.GRAY);
    } else {
    paint.setTextSize(40);
    paint.setColor(Color.WHITE);
    }

中間放大框的實現

當前Activity接受到QuickIndexBar的變化事件後,呼叫showIndexLabel方法,通過handler完成延遲操作。

    private Handler mHandler = new Handler();

    private void showIndexLabel(String word) {
    mLabel.setVisibility(View.VISIBLE);
    mLabel.setText(word);

    mHandler.removeCallbacksAndMessages(null); //移除所有訊息佇列
    mHandler.postDelayed(new Runnable() {      //傳送延時訊息
        @Override
        public void run() {
            mLabel.setVisibility(View.GONE);
        }
    }, DEFAULT_DELAY);
    }

完整程式碼