自定义控制6-索引条
属性文件:
<!--右侧索引条的属性--> <declare-styleable name="SideLetterBar"> <attr name="text_normal_color" format="color"/> <!--选择与没选择的颜色--> <attr name="text_selected_color" format="color"/> <!--文本的大小--> <attr name="text_size" format="dimension"/> </declare-styleable>
控件类:
import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; import com.tstest.R; /** * 索引条 */ public class SideLetterBar extends View { /** * 索引的数据源 */ private String[] b = {"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"}; /** * 被选中的索引,-1代表没有选择任何一个 */ private int choose = -1; private Paint paint = new Paint(); /** * 是否在屏幕中间显示被选中的索引值 */ private boolean showBg = false; /** * 显示在屏幕中间的数据,也就是被选中的索引 */ private TextView overlay; /** * 回调 */ private OnLetterChangedListener onLetterChangedListener; //================================数据=========================== /** * 正常的颜色,选中的颜色,文本的大小 */ private int text_normal_color = Color.parseColor("#666666"); private int text_selected_color = Color.parseColor("#000000"); private int text_size = 20; public SideLetterBar(Context context) { this(context,null); } public SideLetterBar(Context context, AttributeSet attrs) { this(context, attrs,0); } public SideLetterBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); //获取自定义属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SideLetterBar); for (int i = 0; i < typedArray.getIndexCount(); i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.SideLetterBar_text_normal_color: text_normal_color = typedArray.getColor(attr, Color.BLUE);//文本正常的颜色 break; case R.styleable.SideLetterBar_text_selected_color: text_selected_color = typedArray.getColor(attr, Color.RED); break; case R.styleable.SideLetterBar_text_size: text_size = typedArray.getDimensionPixelSize(attr, 30); break; } } typedArray.recycle();//回收 } /** * 设置悬浮的textview * @param overlay */ public void setOverlay(TextView overlay){ this.overlay = overlay; } /** * 设置被选中的数据 * @param selectedText 索引条中的数据 */ public void setSelectedData(String selectedText){ choose = -1; for (int i = 0; i < b.length; i++) { if(b[i].equals(selectedText)){ choose = i; break; } } invalidate(); } /** * 设置数据源 * @param data */ public void setSideBarData(String[] data){ b = data; choose = -1; invalidate(); } @SuppressWarnings("deprecation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (showBg) { canvas.drawColor(Color.TRANSPARENT); } int height = getHeight(); int width = getWidth(); int singleHeight = height / b.length;//每个的高度 Paint.FontMetrics fontMetrics = paint.getFontMetrics(); for (int i = 0; i < b.length; i++) { paint.setTextSize(text_size); paint.setColor(text_normal_color);//正常的颜色 paint.setAntiAlias(true); if (i == choose) { paint.setColor(text_selected_color);//被选中的颜色 paint.setFakeBoldText(true); //加粗 } float xPos = width / 2 - paint.measureText(b[i]) / 2; float yPos = singleHeight * i + (singleHeight - (fontMetrics.bottom - fontMetrics.top))/2 + fontMetrics.bottom - fontMetrics.top; canvas.drawText(b[i], xPos, yPos, paint); paint.reset(); } } @Override public boolean dispatchTouchEvent(MotionEvent event) { final int action = event.getAction(); final float y = event.getY(); final int oldChoose = choose; final OnLetterChangedListener listener = onLetterChangedListener; final int c = (int) (y / getHeight() * b.length); switch (action) { case MotionEvent.ACTION_DOWN: showBg = true; if (oldChoose != c && listener != null) { if (c >= 0 && c < b.length) { listener.onLetterChanged(b[c]); choose = c; invalidate(); if (overlay != null){ overlay.setVisibility(VISIBLE); overlay.setText(b[c]); } } } break; case MotionEvent.ACTION_MOVE: if (oldChoose != c && listener != null) { if (c >= 0 && c < b.length) { listener.onLetterChanged(b[c]); choose = c; invalidate(); if (overlay != null){ overlay.setVisibility(VISIBLE); overlay.setText(b[c]); } } } break; case MotionEvent.ACTION_UP: showBg = false; choose = -1; invalidate(); if (overlay != null){ overlay.setVisibility(GONE); } break; } return true; } @Override public boolean onTouchEvent(MotionEvent event) { return super.onTouchEvent(event); } /** * 索引改变的监听 * @param onLetterChangedListener */ public void setOnLetterChangedListener(OnLetterChangedListener onLetterChangedListener) { this.onLetterChangedListener = onLetterChangedListener; } public interface OnLetterChangedListener { void onLetterChanged(String letter); } }
使用:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!--悬浮的TextView的背景颜色--> <corners android:radius="10dp"/> <solid android:color="#888888"/> </shape>
布局以及使用
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <!--显示被选中的索引--> <TextView android:id="@+id/tv_letter_overlay" android:layout_width="120dp" android:layout_height="120dp" android:gravity="center" android:layout_centerInParent="true" android:background="@drawable/overlay_bg" android:textSize="40sp" android:textStyle="bold" android:textColor="#ffffff" android:visibility="gone"/> <!--右侧索引--> <com.tstest.view.SideLetterBar android:id="@+id/side_bar" android:layout_width="50dp" android:layout_height="match_parent" android:layout_marginTop="20dp" android:layout_marginBottom="20dp" android:gravity="center" android:layout_alignParentRight="true" app:text_normal_color="#000000" app:text_selected_color="#6699ff" app:text_size="15sp"/> </RelativeLayout>
SideLetterBar side_bar = (SideLetterBar) findViewById(R.id.side_bar); TextView side_text = (TextView) findViewById(R.id.tv_letter_overlay); side_bar.setOverlay(side_text);//屏幕中央显示的被选中的索引值 side_bar.setOnLetterChangedListener(new SideLetterBar.OnLetterChangedListener() { @Override public void onLetterChanged(String letter) { Log.e("tag","选择的:"+letter); } }); side_bar.setSelectedData("Z");//设置当前选中的索引值 //设置数据值 side_bar.setSideBarData(new String[]{"还","有","3","小","时","下","班"});
效果图: