自定义控件之快速索引QuickIndexBar
来源:互联网 发布:益云网络 编辑:程序博客网 时间:2024/04/30 02:32
1.定义个类继承view
主要使用三个方法:
一.onSizeChanged() {计算这个自定义控件的宽和每个字母所占的格子的高}
二.onDraw(){调用canvas.drawText}
三.onTouchEvent(){处理触摸逻辑}
public class QuickIndexBar extends View {private Paint paint;private float cellWidth;private float cellHeight;public QuickIndexBar(Context context) {this(context, null);}public QuickIndexBar(Context context, AttributeSet attrs) {this(context, attrs, 0);}public QuickIndexBar(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {paint = new Paint();paint.setColor(Color.GRAY);//抗锯齿paint.setAntiAlias(true);paint.setTextSize(20);//设置粗体和斜体paint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD_ITALIC));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);for (int i = 0; i < Cheeses.LETTERS.length; i++) {String letter = Cheeses.LETTERS[i];//定义一个矩形Rect rect = new Rect();//把letter装进一个矩形区域内//这个方法将letter进行测量,将letter的宽高设置到Rect中//参数2:字母的开始//参数3:字母的结束paint.getTextBounds(letter, 0, 1, rect);int textWidth = rect.width();int textHeight = rect.height();//等于一个单位宽度/2+文本占用的宽度/2float x = cellWidth / 2 - textWidth / 2;//等于一个单位高度/2+文本占用的高度/2+每个单位高度*ifloat y = cellHeight / 2 + textHeight / 2 + i * cellHeight;//判断绘制的文本是否是当前选择的索引,如果是,则高亮显示paint.setColor(i == currentIndex ? Color.RED : Color.GRAY);paint.setTextSize(i==currentIndex?30:20);canvas.drawText(letter, x, y, paint);}//绘制一个文本在View上//canvas.drawText("#",10f,20f,paint);//canvas.drawText("#",10f,50f,paint);//canvas.drawText("#",10f,80f,paint);//canvas.drawText("#",10f,110f,paint);//canvas.drawText("#",10f,140f,paint);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);cellWidth = this.getMeasuredWidth();cellHeight = this.getMeasuredHeight() * 1.0f / Cheeses.LETTERS.length;}private int currentIndex = -1;private int preIndex = -1;@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:if (listener != null) {preIndex = currentIndex;float y = event.getY();//计算触摸的点所在的位置currentIndex = (int) (y / cellHeight);//识别被触摸到的letterString letter = Cheeses.LETTERS[currentIndex];//检查触摸的位置与上一个位置是否一致,如果不一致,则打印if (preIndex != currentIndex) {Log.i("test", "letter:" + letter);listener.onLetterChanged(letter);}invalidate();}break;case MotionEvent.ACTION_UP:if (listener != null) {listener.onLetterDismiss();}currentIndex=-1;invalidate();break;default:break;}return true;}private OnLetterChangedListener listener;public interface OnLetterChangedListener {void onLetterChanged(String letter);void onLetterDismiss();}public void setOnLetterChangedListener(OnLetterChangedListener listener) {this.listener = listener;}}
2.布局文件
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> <com.itheima.quickindexbarhm91.QuickIndexBar android:id="@+id/qib" android:layout_width="20dp" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#770095ff"/> <TextView android:id="@+id/tv_show_letter" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="@drawable/tv_bg" android:gravity="center" android:textColor="@android:color/white" android:textSize="20sp" android:visibility="gone" /></RelativeLayout>
3.activity
public class MainActivity extends AppCompatActivity {private TextView tv_show_letter;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);tv_show_letter = (TextView) findViewById(R.id.tv_show_letter);QuickIndexBar qib = (QuickIndexBar) findViewById(R.id.qib);qib.setOnLetterChangedListener(new QuickIndexBar.OnLetterChangedListener() {@Overridepublic void onLetterChanged(String letter) {tv_show_letter.setVisibility(View.VISIBLE);tv_show_letter.setText(letter);}@Overridepublic void onLetterDismiss() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {tv_show_letter.setVisibility(View.GONE);}}, 200);}});List<ContactInfo> contacts=new ArrayList<ContactInfo>();for (int i = 0; i < Cheeses.NAMES.length; i++) {contacts.add(new ContactInfo(Cheeses.NAMES[i]));}//让ContactInfo具有可排序性,让Collections对ContactInfo集合进行排序Collections.sort(contacts);ListView lv= (ListView) findViewById(R.id.lv);lv.setAdapter(new ContactAdapter(contacts));}}4.要显示的数据对象类
public class ContactInfo implements Comparable<ContactInfo>{private String firstLetter;private String name;public ContactInfo(String name) {this.firstLetter= PinyinUtil.chineseWordToPinyin(name).substring(0, 1);this.name = name;}public String getFirstLetter() {return firstLetter;}public void setFirstLetter(String firstLetter) {this.firstLetter = firstLetter;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "ContactInfo{" +"firstLetter='" + firstLetter + '\'' +", name='" + name + '\'' +'}';}@Overridepublic int compareTo(ContactInfo another) {return this.firstLetter.compareTo(another.firstLetter);}}5.适配器
public class ContactAdapter extends BaseAdapter {private List<ContactInfo> contacts;public ContactAdapter(List<ContactInfo> contacts) {this.contacts = contacts;}@Overridepublic int getCount() {return contacts == null ? 0 : contacts.size();}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder = null;if (convertView == null) {convertView = View.inflate(parent.getContext(), R.layout.lv_contact_list_item, null);holder = new ViewHolder();holder.tv_first_letter = (TextView) convertView.findViewById(R.id.tv_first_letter);holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);convertView.setTag(holder);} else {holder = (ViewHolder) convertView.getTag();}ContactInfo info = contacts.get(position);holder.tv_first_letter.setText(info.getFirstLetter());holder.tv_name.setText(info.getName());if (position == 0) {holder.tv_first_letter.setVisibility(View.VISIBLE);} else {//如果当前条目对应的首字母和上一个一致,则让首字母隐藏ContactInfo lastInfo = contacts.get(position - 1);if (lastInfo.getFirstLetter().equals(info.getFirstLetter())) {holder.tv_first_letter.setVisibility(View.GONE);} else {holder.tv_first_letter.setVisibility(View.VISIBLE);}}return convertView;}private class ViewHolder {private TextView tv_first_letter;private TextView tv_name;}}
6.由于显示数据时要显示每个名字的字母 所以要将汉子转为拼音 提取出首字母 这里用到了一个拼音jar包 pinyin4j-2.5.0.jar
public class PinyinUtil {private static HanyuPinyinOutputFormat format;public static String chineseWordToPinyin(String chineseWord) {if (format == null) {format = new HanyuPinyinOutputFormat();}//设置去除声调format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);format.setCaseType(HanyuPinyinCaseType.UPPERCASE);//将汉语字符串转化为字符数据char[] chars = chineseWord.toCharArray();StringBuffer sb=new StringBuffer();for (char c : chars) {//跨过空格if(Character.isWhitespace(c)){continue;}else{//拼配汉字的正则表达式if(Character.toString(c).matches("[\\u4E00-\\u9FA5]")) {try {String[] results = PinyinHelper.toHanyuPinyinStringArray(c, format);//for (String result : results) {//Log.i("test","result:"+result);//}String result = results[0];sb.append(result);} catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {badHanyuPinyinOutputFormatCombination.printStackTrace();}}else{//如果是字母if(Character.isLetter(c)){//直接变为字母sb.append(c);}else{//如果是"火星文",以#代替sb.append("#");}}}}return sb.toString();}}
0 0
- 自定义控件之快速索引QuickIndexBar
- 自定义控件之A-Z快速检索QuickIndexBar
- Android快速索引条控件QuickIndexBar
- 自定义控件:快速索引
- 安卓 简单的 联系人快速检索控件QuickIndexBar实现
- 自定义控件--快速索引(一)
- 自定义控件--快速索引(二)
- 自定义控件--快速索引(三)
- 自定义控件实现快速索引,字典排序
- 自定义View 实现字母快速索引控件
- Android自定义类似联系人列表的 快速索引控件
- 使用自定义控件和ListView实现快速索引功能
- Android自定义控件之实现快速检索
- 快速检索(一)之自定义快速检索QiuckIndexBar控件
- android自定义控件索引
- 自定义View之快速索引栏的实现
- 自定义控件--快速检索
- 自定义联系人快速索引栏
- ZOJ_3203_Light Bulb
- 案例十二:多文件输出MultipleOutputs
- 8跳棋(1)90跳棋(2)221跳棋(3)
- jqeury源码分析事件
- 在css文件里php变量
- 自定义控件之快速索引QuickIndexBar
- String固定起始位置字符串反转,去除前后或所有空格
- window下装kafka
- 跨时钟域时序的数据同步设计
- HDU5920 Ugly Problem(高精度)
- hadoop伪分布式环境搭建
- Python读取excel数据进行SUMO仿真
- vector
- Android NDK 开发(三)JNI 调用Java属性和方法