右侧26字母导航栏
2020-01-10 本文已影响0人
龙_君
1111.png 2222.png这是一个自定义View,可以放到右侧,也可以放到左侧,
3333.png可以在WordNavView中添加导航栏中的数据
自定义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