美文网首页
右侧26字母导航栏

右侧26字母导航栏

作者: 龙_君 | 来源:发表于2020-01-10 15:11 被阅读0次

    这是一个自定义View,可以放到右侧,也可以放到左侧,

    1111.png 2222.png

    可以在WordNavView中添加导航栏中的数据

    3333.png

    自定义View代码

    package com.jiyun.crazyshopping.ui.brand.view;
    
    
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.RectF;
    import android.text.TextPaint;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    
    import androidx.annotation.Nullable;
    
    import java.util.HashMap;
    import java.util.Map;
    
    //Created by lake on 2017/7/18.
    //右侧字母导航
    public class WordNavView extends View {
    
        //字母颜色
        private int mTextColor = Color.GRAY;
    
        //字母大小
        private float mTextSize = 36;
    
        //字母内容
        private String[] mTextList= {"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 float mTextWidth;
    
        //字母高度
        private float mTextHeight;
    
        // 位置与字母关系表
        private Map<Float,String> mPointMap;
    
        //手势监听
        private GestureDetector mGestureDetector;
    
        //当前选择的字母
        private String mCurWord = "A";
    
        //是否显示黑色背景
        private boolean isShowBlackBg =false;
    
        // 背景画笔
        private Paint mBgPaint;
    
        //字母焦点监听
        private OnTouchingWordChangedListener onTouchingWordChangedListener;
        private TextPaint mPaint;
    
        public WordNavView(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
            initPaint();
        }
    
        //初始化画笔
        private void initPaint() {
            mPaint = new TextPaint();
            mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);//消除锯齿
            mPaint.setColor(mTextColor);
            mPaint.setTextSize(mTextSize);
    
            mBgPaint = new Paint();
            mBgPaint.setFlags(Paint.ANTI_ALIAS_FLAG);//消除锯齿
            mBgPaint.setColor(Color.BLACK);
            mBgPaint.setStyle(Paint.Style.FILL);//充满
    
            Paint.FontMetrics fontMetrics= mPaint.getFontMetrics();
            mTextHeight = Math.abs(fontMetrics.top);
    
            mGestureDetector = new GestureDetector(getContext(),new MySimpleGestureDetector());
    
        }
    
        // 绘图
        @Override
        protected void onDraw(Canvas canvas) {
            mPointMap = new HashMap<>();
            mPaint.setColor(mTextColor);
            if(isShowBlackBg){
                RectF rectF = new RectF(getPaddingLeft(),getPaddingTop(),getPaddingLeft()+getWidth(),getPaddingTop()+getHeight());
                canvas.drawRoundRect(rectF, getWidth()/2, getWidth()/2, mBgPaint);
                mPaint.setColor(Color.WHITE);
            }
            for (int i = 0; i < mTextList.length; i++) {
                mTextWidth = mPaint.measureText(mTextList[i]);
                canvas.drawText(mTextList[i], getPaddingLeft()+getWidth()/2-mTextWidth/2
                        , getPaddingTop() + getHeight()/mTextList.length*(i+1)-mTextHeight/5, mPaint);
                mPointMap.put(getPaddingTop() + getHeight()/mTextList.length*(i+1)-mTextHeight/5,mTextList[i]);
            }
            super.onDraw(canvas);
        }
    
        // 手势监听事件
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            super.onTouchEvent(event);
            mGestureDetector.onTouchEvent(event);
            if(event.getAction()==MotionEvent.ACTION_DOWN){
                //显示黑背景
                isShowBlackBg = true;
            }else if(event.getAction()==MotionEvent.ACTION_UP){
                //隐去背景
                isShowBlackBg =false;
            }
            postInvalidate();
            return true;
        }
    
        //手势监听
        private class MySimpleGestureDetector extends GestureDetector.SimpleOnGestureListener{
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                float y = e2.getY();
                for (Map.Entry<Float, String> entry : mPointMap.entrySet()) {
                    if(y>=entry.getKey()-getHeight()/mTextList.length/2&&y<=entry.getKey()+getHeight()/mTextList.length/2){
                        if(!mCurWord.equals(entry.getValue())){
                            Log.e("lake",entry.getValue());
                            if(onTouchingWordChangedListener != null){
                                onTouchingWordChangedListener.onTouchingWordChanged(entry.getValue());
                            }
                        }
                        mCurWord=entry.getValue();
                        break;
                    }
                }
                return super.onScroll(e1, e2, distanceX, distanceY);
            }
    
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                float y =e.getY();
                for (Map.Entry<Float, String> entry : mPointMap.entrySet()) {
                    if(y>=entry.getKey()-getHeight()/mTextList.length/2&&y<=entry.getKey()+getHeight()/mTextList.length/2){
                        Log.e("lake",entry.getValue());
                        if(onTouchingWordChangedListener != null){
                            onTouchingWordChangedListener.onTouchingWordChanged(entry.getValue());
                        }
                        break;
                    }
                }
                return super.onSingleTapUp(e);
            }
        }
        //向外公开的方法 字母监听
        public void setOnTouchingWordChangedListener(OnTouchingWordChangedListener onTouchingWordChangedListener) {
            this.onTouchingWordChangedListener = onTouchingWordChangedListener;
        }
    
        //接口
        public interface OnTouchingWordChangedListener {
            void onTouchingWordChanged(String s);
        }
    }
    

    直接嵌套到布局里就行了

    //直接以你的类名布局就可以了
            <com.***.***.WordNavView
                android:id="@+id/wordNavView"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:layout_alignParentLeft="true"
                android:layout_alignParentTop="true" />
    

    在Java代码中使用,设置WordNavView的点击事件

       //控件实现接口
            brandWordNavView.setOnTouchingWordChangedListener(new WordNavView.OnTouchingWordChangedListener() {
                @Override
                public void onTouchingWordChanged(String s) {
                     //s 为当前触摸的字母 将RecyclerView的当前位置设置到对应的字母头位置就可以了
     Toast.makeText(BaseApp.getContext(),s,Toast.LENGTH_LONG).show();
                }
            });
    
    z.gif

    相关文章

      网友评论

          本文标题:右侧26字母导航栏

          本文链接:https://www.haomeiwen.com/subject/wczxyctx.html