效果图:
项目结构:
核心代码:
自定义索引的类
IndexView
package com.example.mytongxunlu; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.Typeface; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.orhanobut.logger.Logger; /** * 自定义通讯录 */ public class IndexView extends View { /** * 每条的宽和高 */ private int itemWidth; private int itemHeight; private Paint paint; private String[] words = {"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"}; public IndexView(Context context, AttributeSet attrs) { super(context, attrs); paint = new Paint(); paint.setColor(Color.WHITE);//设置颜色 paint.setAntiAlias(true);//设置抗锯齿 paint.setTypeface(Typeface.DEFAULT_BOLD);//设置粗体字 // 设置字体大小 paint.setTextSize(DensityUtil.dip2px(context,20)); } /** * 测量方法 * * @param widthMeasureSpec * @param heightMeasureSpec */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 每个索引的宽度 itemWidth = getMeasuredWidth(); // 每个索引的高度 itemHeight = getMeasuredHeight() / words.length; Logger.t("111").d("onMeasure>>>"); } /** * 绘制 * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Logger.t("111").d("onDraw>>>"); for (int i = 0; i < words.length; i++) { String word = words[i];//A Rect rect = new Rect(); //画笔 //0,1的取一个字母 paint.getTextBounds(word, 0, 1, rect); //字母的高和宽 int wordWidth = rect.width(); int wordHeight = rect.height(); //计算每个字母在视图上的坐标位置 float wordX = itemWidth / 2 - wordWidth / 2; float wordY = itemHeight / 2 + wordHeight / 2 + i * itemHeight; canvas.drawText(word, wordX, wordY, paint); } } }
工具类,px和dp的相互转化
DensityUtil
布局 activity_main.xml中package com.example.mytongxunlu; import android.content.Context; /** * 工具类,px和dp的相互转化 */ public class DensityUtil { /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dip2px(Context context, float dpValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } /** * 根据手机的分辨率从 px(像素) 的单位 转成为 dp */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } }
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.mytongxunlu.MainActivity"> <ListView android:id="@+id/lv_main" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:id="@+id/tv_word" android:layout_width="80dp" android:layout_height="80dp" android:layout_centerInParent="true" android:background="#44000000" android:gravity="center" android:text="A" android:textColor="#000000" android:textSize="30sp" android:visibility="visible" /> <com.example.mytongxunlu.IndexView android:id="@+id/iv_words" android:layout_width="30dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#ff0000" /> </RelativeLayout>
源码下载:
Myself ---- mytongxunlu
http://download.csdn.net/download/zhaihaohao1/10111351
参考视频:
http://www.gulixueyuan.com/course/124/learn#lesson/1923