android 自定义侧边栏
16lz
2021-01-24
正在学习自定义控件,写的不好请多多指教
效果图
代码:
mTextSize | dimension | 未选中字体大小 |
mTextColor | color | 未选中字体颜色 |
mSelectTextSize | dimension | 选中字体大小 |
mSelectTextColor | color | 选中字体颜色 |
isShowDialog | boolean | 是否显示对话框 |
mDialogWidth | dimension | 对话框的宽度 |
mDialogHeight | dimension | 对话框的高度 |
mDialogBg | color|reference | 对话框的背景 |
package com.xbd.test;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Rect;import android.graphics.drawable.Drawable;import android.os.Build;import android.support.annotation.Nullable;import android.support.v7.app.AlertDialog;import android.util.AttributeSet;import android.view.Gravity;import android.view.MotionEvent;import android.view.View;import android.view.WindowManager;import android.widget.TextView;import java.util.ArrayList;import java.util.List;/** * 自定义索引控件 */public class SideBarView extends View { /** * 是否显示对话框,默认显示 */ private boolean isShowDialog = true; /** * 对话框的宽度 */ private int mDialogWidth = 100; /** * 对话框的高度 */ private int mDialogHeight = 100; /** * 对话框的背景 */ private Drawable mDialogBg = null; /** * 未选中字体大小 */ private int mTextSize = 16; /** * 未选中字体颜色 */ private int mTextColor = Color.BLACK; /** * 选中字体大小 */ private int mSelectTextSize = mTextSize; /** * 选中字体颜色 */ private int mSelectTextColor = mTextColor; /** * 画笔 */ private Paint mTextPaint; /** * 宽度 */ private int width = 0; /** * 高度 */ private int height = 0; /** * 每一个item的高度 */ private float perHeight = 0; /** * 每一个item的宽度 */ private float perWidth = 0; /** * 文字的高度 */ private float mTextHeight = 0; /** * 第一个距上方的高度 */ private float mMarginTop = 0; private List wordsList; /** * 显示选中的文字 */ private AlertDialog mShowTextDialog; private TextView mShowText; /** * 选中的位置 */ private int mSelectIndex = -1; /** * 点击回调 */ private OnItemSelectedListener mSelectedListener; public SideBarView(Context context) { super(context); } public SideBarView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context, attrs); } public SideBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } /** * 初始化属性 * * @param context */ private void init(Context context, AttributeSet attrs) { if (attrs != null) { TypedArray arrays = context.obtainStyledAttributes(attrs, R.styleable.SideBarView); //对话框 isShowDialog = arrays.getBoolean(R.styleable.SideBarView_isShowDialog, isShowDialog); mDialogWidth = arrays.getDimensionPixelSize(R.styleable.SideBarView_mDialogWidth, mDialogWidth); mDialogHeight = arrays.getDimensionPixelSize(R.styleable.SideBarView_mDialogHeight, mDialogHeight); mDialogBg = arrays.getDrawable(R.styleable.SideBarView_mDialogBg); //未选中的字体颜色和字体大小 mTextColor = arrays.getColor(R.styleable.SideBarView_mTextColor, mTextColor); mTextSize = arrays.getDimensionPixelSize(R.styleable.SideBarView_mTextSize, mTextSize); //选中的字体颜色和字体大小,默认是未选中的 mSelectTextColor = arrays.getColor(R.styleable.SideBarView_mSelectTextColor, mTextColor); mSelectTextSize = arrays.getDimensionPixelSize(R.styleable.SideBarView_mSelectTextSize, mTextSize); arrays.recycle(); } mTextPaint = new Paint(); mTextPaint.setTextSize(mTextSize); mTextPaint.setColor(mTextColor); //抗锯齿 mTextPaint.setAntiAlias(true); //设置这个drawText的x坐标,默认是距离左边屏幕的距离,设置后就是字符串中心的位置 mTextPaint.setTextAlign(Paint.Align.CENTER); wordsList = new ArrayList<>(); wordsList.add("#"); wordsList.add("A"); wordsList.add("B"); wordsList.add("C"); wordsList.add("D"); wordsList.add("E"); wordsList.add("F"); wordsList.add("G"); wordsList.add("H"); wordsList.add("I"); wordsList.add("J"); wordsList.add("K"); wordsList.add("L"); wordsList.add("M"); wordsList.add("N"); wordsList.add("O"); wordsList.add("P"); wordsList.add("Q"); wordsList.add("R"); wordsList.add("S"); wordsList.add("T"); wordsList.add("U"); wordsList.add("V"); wordsList.add("W"); wordsList.add("X"); wordsList.add("Y"); wordsList.add("Z"); wordsList.add("*"); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = w; height = h; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //如果每一行代码 if (perHeight == 0) { //首先获取内边距 float paddingTop = getPaddingTop(); float paddingBottom = getPaddingBottom(); float paddingLeft = getPaddingLeft(); float paddingRight = getPaddingRight(); perHeight = (height - paddingTop - paddingBottom) / wordsList.size(); perWidth = width - paddingLeft - paddingRight; } int size = wordsList.size(); //距控件上方的距离 //float textWidth = mTextPaint.measureText(wordsList.get(i)); //由(width/2-textWidth/2)+getPaddingLeft()+textWidth/2得来 float marginLeft = width / 2 + getPaddingLeft(); for (int i = 0; i < size; i++) { if (mTextHeight == 0) { Rect rect = new Rect(); mTextPaint.getTextBounds(wordsList.get(i), 0, wordsList.get(i).length(), rect); mTextHeight = rect.height(); //因为drawText的y坐标是baseline,所以要计算mMarginTop,保持居中 //由marginTop = (perHeight - mTextHeight) / 2 + getPaddingTop() + mTextHeight得来 mMarginTop = (perHeight + mTextHeight) / 2 + getPaddingTop(); } if (mSelectIndex == i) { mTextPaint.setColor(mSelectTextColor); mTextPaint.setTextSize(mSelectTextSize); } else { mTextPaint.setColor(mTextColor); mTextPaint.setTextSize(mTextSize); } canvas.drawText(wordsList.get(i), marginLeft, mMarginTop + i * perHeight, mTextPaint); } } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: float itemHeight = event.getY(); //如果点击的位置在上边距的内部,则默认为0 if (itemHeight < getPaddingTop()) { itemHeight = 0; } else if (itemHeight > getPaddingTop() + perHeight * wordsList.size()) { //-1是因为获取选中的位置时是wordsList.size,超出范围 itemHeight = perHeight * wordsList.size() - 1; } else { itemHeight -= getPaddingTop(); } mSelectIndex = (int) (itemHeight / perHeight); //显示对话框 if (isShowDialog) { openShowDialog(wordsList.get(mSelectIndex)); } if (mSelectedListener != null) { OnItemSelectedListener listener = mSelectedListener; listener.onItemSelected(mSelectIndex); } invalidate(); return true; case MotionEvent.ACTION_UP: mSelectIndex = -1; if (isShowDialog) { closeShowDialog(); } invalidate(); return true; } return super.onTouchEvent(event); } /** * 初始化显示文字的对话框 */ private void initShowDialog() { if (mShowTextDialog == null) { AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.SideBarDialog); mShowText = new TextView(getContext()); mShowText.setTextSize(mTextSize); mShowText.setTextColor(mTextColor); if (mDialogBg != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { mShowText.setBackground(mDialogBg); } else { mShowText.setBackgroundDrawable(mDialogBg); } } mShowText.setGravity(Gravity.CENTER); builder.setView(mShowText); mShowTextDialog = builder.create(); } } /** * 显示文字对话框 * * @param text */ public void openShowDialog(String text) { if (mShowTextDialog == null) { initShowDialog(); } if (text == null) { mShowText.setText(""); } else { mShowText.setText(text); } if (!mShowTextDialog.isShowing()) { mShowTextDialog.show(); WindowManager.LayoutParams params = mShowTextDialog.getWindow().getAttributes(); params.width = mDialogWidth; params.height = mDialogWidth; mShowTextDialog.getWindow().setAttributes(params); } } /** * 关闭显示对话框 */ private void closeShowDialog() { if (mShowTextDialog != null && mShowTextDialog.isShowing()) { mShowTextDialog.dismiss(); } } /** * 设置回调事件 * * @param listener */ public void setOnItemSelectedListener(OnItemSelectedListener listener) { this.mSelectedListener = listener; } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); if (mShowTextDialog != null) { if (mShowTextDialog.isShowing()) { mShowTextDialog.cancel(); } mShowTextDialog = null; } if (mSelectedListener != null) { mSelectedListener = null; } } /** * 点击回调 */ public interface OnItemSelectedListener { void onItemSelected(int pos); }}
更多相关文章
- 显示倒计时的Dialog
- Android中对同一个TextView设置不同字体样式
- Android(安卓)WebView 向上向下滑动监听
- Android(安卓)强制下线功能 第一行代码
- 在android中如何在代码中设置textview的属性和效果
- android退出应用程序解决方案
- Android常用控件-DatePicker以及对话框的两种使用方法
- Android(安卓)实现仿支付宝的密码均分输入框
- Android(安卓)getDecorView用途——屏幕截图