欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

自定义view之简单实现字母索引列表

程序员文章站 2022-04-03 16:02:07
自定义view之简单实现字母索引列表效果思路大体可分为两部分,一个是中间显示的英文字符,一个是右侧的字母索引列表,通过自定义view方法,计算每个字母的高度,然后依次绘制,通过触碰,绘制中心显示的文字,最后通过handler延时操作使其消失代码import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import android.graphics....

自定义view之简单实现字母索引列表

效果

自定义view之简单实现字母索引列表自定义view之简单实现字母索引列表

思路

大体可分为两部分,一个是中间显示的英文字符,一个是右侧的字母索引列表,通过自定义view方法,计算每个字母的高度,然后依次绘制,通过触碰,绘制中心显示的文字,最后通过handler延时操作使其消失

代码

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;


public class LetterSideBar extends View {
    private Paint paint = new Paint();
    private Paint tempPaint = new Paint();
    private boolean isTouch = false;
    // 定义26个字母
    public static String[] mLetters = {"A", "B", "C", "D", "E", "F", "G", "H", "I",
            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
            "W", "X", "Y", "Z", "#"};
    private String mCurrentTouchLetter;
    private int currentPos;
    int textWidth = (int) paint.measureText("A");

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

    public LetterSideBar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public LetterSideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        paint.setAntiAlias(true);
        paint.setTextSize(sp2px(20));
        paint.setColor(Color.BLUE);
    }
    //sp转px
    private float sp2px(int sp){
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                sp, getResources().getDisplayMetrics());
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int itemHeight = (getHeight() - getPaddingTop() - getPaddingBottom()) / mLetters.length;
        for (int i = 0 ; i < mLetters.length ;i++){
            int letterCenterY = i * itemHeight + itemHeight / 2 + getPaddingTop();
            Paint.FontMetrics fontMetrics = paint.getFontMetrics();
            int dy = (int) ((fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
            int baseLine = letterCenterY + dy;
            int textWidth = (int) paint.measureText(mLetters[i]);
            int x = getWidth()/2 - textWidth/2;
            int dis =0;

            if (Math.abs(i - currentPos) < 3 && isTouch){
                dis = 60-Math.abs(i - currentPos) * 20;
            }
            if (mLetters[i].equals(mCurrentTouchLetter)){
                paint.setColor(Color.RED);
            }else {
                paint.setColor(Color.BLUE);
            }
            drawCenter(mCurrentTouchLetter,canvas,isTouch);
            canvas.drawText(mLetters[i], x+getWidth()/2-getPaddingRight()-dis, baseLine, paint);
        }
    }

    private void drawCenter(final String mLetter, final Canvas canvas, boolean isTouch) {
        canvas.save();
        if (isTouch){
            tempPaint.setColor(Color.BLUE);
            tempPaint.setTextSize(sp2px(40));
            tempPaint.setAntiAlias(true);
            canvas.drawCircle(getWidth()/2,getHeight()/2,getWidth()/5,tempPaint);
            tempPaint.setColor(Color.WHITE);
            Paint.FontMetrics fontMetrics = tempPaint.getFontMetrics();
            int dy = (int) ((fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
            final int baseLine = getHeight()/2 + dy;
            int textWidth = (int) paint.measureText(mLetter);
            final int x = getWidth()/2 - textWidth;
            canvas.drawText(mLetter,x,baseLine,tempPaint);
            canvas.restore();
        }else {
            canvas.restore();
        }

    }
    Handler handler=new Handler(Looper.getMainLooper());
    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_DOWN:
                float currentY = event.getY();
                float currentX = event.getX();
                if (currentX > getWidth() - getPaddingRight() -textWidth-getPaddingLeft() -60){
                    int itemHeight = (getHeight() - getPaddingTop() -getPaddingBottom()) / mLetters.length;
                    currentPos = (int) (currentY / itemHeight);
                    if (currentPos < 0){
                        currentPos = 0;
                    }
                    if (currentPos > mLetters.length -1){
                        currentPos = mLetters.length -1;
                    }
                    mCurrentTouchLetter = mLetters[currentPos];
                    isTouch = true;
                    invalidate();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            isTouch = false;
                            invalidate();
                        }
                    },2000);
                }
                break;
            default:
                break;
        }
        return true;
    }
}

本文地址:https://blog.csdn.net/wu_zixuan97/article/details/108712663