Android自定义SideBar

SideBar类似于手机通讯录或者微信通讯录右侧的A~Z的字母导航。

public class SideBar extends View {
//    public static String[] letter = { "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", "#" };
    List<String> letters = new ArrayList<>();
    private Paint paint = new Paint();
    /**
     * 计算出来的高度
     */
    private int mCalViewHeight;
    private int selection = -1;
    private TextView mTextDialog;
    // 触摸事件
    private OnTouchingLetterChangedListener onTouchingLetterChangedListener;

    /**
     * 为SideBar设置显示字母的TextView
     * @param textDialog
     */
    public void setTextView(TextView textDialog) {
        this.mTextDialog = textDialog;
    }

    public void setLetterData(List<String> letters){
        this.letters = letters;
        requestLayout();
        invalidate();
    }

    public SideBar(Context context) {
        super(context);
    }

    public SideBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public SideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public SideBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if(letters.size() > 0){
            mCalViewHeight = (int)((letters.size()) * 30 + (letters.size() - 1) * 6);
        }
        if(mCalViewHeight > height){
            mCalViewHeight = height;
        }
        super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(mCalViewHeight, MeasureSpec.EXACTLY));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(letters.size() == 0){
            return;
        }
        int height = getHeight();
        int width = getWidth();
        int singleLetterHeight = height / letters.size(); //获取每个字母的高度

        for(int i = 0; i < letters.size(); i++){
            paint.setColor(Color.parseColor("#4D4D4D")); //字母颜色
            paint.setTypeface(Typeface.DEFAULT_BOLD);  //字母黑色字体类型
            paint.setAntiAlias(true);  //抗锯齿,对边界锯齿进行模糊处理
            paint.setDither(true);   //防抖动,对图像抖动进行模糊平滑处理,使之看起来更柔和
            paint.setTextSize(30);
            if(i == selection){
                paint.setColor(Color.parseColor("#3399ff"));
                paint.setFakeBoldText(true);   //设置粗体字
            }
            //X坐标等于中间减去字符串宽度的一半
            float xPos = width / 2 - paint.measureText(letters.get(i)) / 2;
            float yPos = singleLetterHeight * i + singleLetterHeight;
            canvas.drawText(letters.get(i), xPos, yPos, paint);
            paint.reset();
        }
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        float y = event.getY();
        int selectedNumber = (int)(y / getHeight() * letters.size());   //点击y坐标所占总高度的比例*letter数组的长度=点击letter中的个数
        int oldSelection = selection;
        OnTouchingLetterChangedListener listener = onTouchingLetterChangedListener;

        switch (event.getAction()){
            case MotionEvent.ACTION_UP:
                setBackground(new ColorDrawable(0x00000000));
                selection = -1;
                invalidate();
                if(mTextDialog != null){
                    mTextDialog.setVisibility(GONE);
                }
                break;
            default:
                setBackgroundResource(R.drawable.sidebar_background);
                if(oldSelection != selectedNumber){
                    if(selectedNumber >= 0 && selectedNumber < letters.size()){
                        if(listener != null){
                            listener.onTouchingLetterChanged(letters.get(selectedNumber));
                        }
                        if (mTextDialog != null){
                            mTextDialog.setText(letters.get(selectedNumber));
                            mTextDialog.setVisibility(VISIBLE);
                        }

                        selection = selectedNumber;
                        invalidate();
                    }
                }
                break;
        }
        return true;
    }

    /**
     * 触摸事件
     * @param onTouchingLetterChangedListener
     */
    public void setOnTouchingLetterChangedListener(OnTouchingLetterChangedListener onTouchingLetterChangedListener) {
        this.onTouchingLetterChangedListener = onTouchingLetterChangedListener;
    }

    /**
     * @author coder
     *
     */
    public interface OnTouchingLetterChangedListener {
        void onTouchingLetterChanged(String s);
    }
}

使用方式:

    
@BindView(R.id.dialog)   
TextView mDialog;    
@BindView(R.id.sideBar)
SideBar mSideBar;

mSideBar.setTextView(mDialog);
//设置右侧SideBar触摸监听
mSideBar.setOnTouchingLetterChangedListener(new SideBar.OnTouchingLetterChangedListener() {
    @Override
    public void onTouchingLetterChanged(String s) {
        //该字母首次出现的位置
        //int position = mAdapter.getPosition(s);
        //if (position != -1) {
            //mLayoutManager.scrollToPositionWithOffset(position, 0);
        //}
        //TODO
    }
});


参考:1.SortRecyclerView

2.Android 使用RecyclerView实现(仿微信)的联系人A-Z字母排序和过滤搜索功能

3.自定义实现微信通讯录效果View

猜你喜欢

转载自blog.csdn.net/u014611408/article/details/85105027
今日推荐