android快速索引的实现
来源:互联网 发布:全自动挂机赚钱软件 编辑:程序博客网 时间:2024/06/07 00:09
从图中可以看出,这种快速索引在客户端的运用非常多,例如:快速检索城市,快速检索联系人等。接下来就来看看如何实现这种效果吧。
画字母
要实现这个效果, 先得把右侧的字母条画出来, 这里我们写个类, 继承自 View, 由于其内部不需要包含其他布局, 所以继承 View 即可, 无需继承 ViewGroup.
public class QuickIndexBar extends View { private static final String TAG = "TAG"; private static final String[] LETTERS = new String[]{ "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 Paint mPaint; public interface OnLetterChangeListener{ void OnLetterChange(String letter); } public QuickIndexBar(Context context) { this(context, null); } public QuickIndexBar(Context context, AttributeSet attrs) { this(context, attrs, 0); } public QuickIndexBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // 初始化画笔 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.WHITE); mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12f, getResources().getDisplayMetrics())); mPaint.setTypeface(Typeface.DEFAULT_BOLD); } }
这里面要注意的是, 使用 Canvas 画文字的时候, 是从左下角开始的.
@Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mHeight = getMeasuredHeight(); mCellHeight = mHeight * 1.0f / LETTERS.length; mCellWidth = getMeasuredWidth(); } @Override protected void onDraw(Canvas canvas) { // 绘制字母 for (int i = 0; i < LETTERS.length; i++) { String text = LETTERS[i]; // 求x坐标 int x = (int) (mCellWidth / 2.0f - mPaint.measureText(text) / 2.0f); // 求y坐标 // 格子高度的一半 + 文字高度的一半 + 其上边所有格子高度 Rect bounds = new Rect(); mPaint.getTextBounds(text, 0, text.length(), bounds); int y = (int) (mCellHeight / 2.0f + bounds.height() / 2.0f + mCellHeight * i); canvas.drawText(text, x, y, mPaint); } }
这样一来, 字母就画出来了, 如果想要更自由一些的话, 可以使用自定义属性传入字体颜色.
触摸事件和回调
界面效果有了, 接下来就是处理触摸事件以及回调了, 处理触摸事件肯定是重写 onTouchEvent 方法了, 回调的话, 定义一个回调接口, 提供 get/set 方法, 在 onTouchEvent 相应的位置调用. onTouchEvent 代码如下:
@Override public boolean onTouchEvent(MotionEvent event) { switch (MotionEventCompat.getActionMasked(event)) { case MotionEvent.ACTION_DOWN: // 根据y值获取当前触摸到的字母 float y = event.getY(); int index = (int) (y / mCellHeight); // 如果字母索引发生变化 if(index != touchIndex){ if(index >= 0 && index < LETTERS.length){ Log.d(TAG, LETTERS[index]); if(mLetterChangeListener != null){ // 执行回调 mLetterChangeListener.OnLetterChange(LETTERS[index]); } } touchIndex = index; } break; case MotionEvent.ACTION_MOVE: // 根据y值获取当前触摸到的字母 int i = (int) (event.getY() / mCellHeight); // 如果字母索引发生变化 if(i != touchIndex){ if(i >= 0 && i < LETTERS.length){ Log.d(TAG, LETTERS[i]); if(mLetterChangeListener != null){ mLetterChangeListener.OnLetterChange(LETTERS[i]); } } touchIndex = i; } break; case MotionEvent.ACTION_UP: // 恢复默认索引值 touchIndex = -1; break; default: break; } invalidate(); return true; }
回调接口:
public interface OnLetterChangeListener{ void OnLetterChange(String letter); } // 字母变化监听 private OnLetterChangeListener mLetterChangeListener; public OnLetterChangeListener getLetterChangeListener() { return mLetterChangeListener; } public void setLetterChangeListener( OnLetterChangeListener mLetterChangeListener) { this.mLetterChangeListener = mLetterChangeListener; }
ListView 的处理
首先我们要获取一个所有名字的集合, 并且对它按照拼音顺序排序.
private void fillAndSort(ArrayList<Friend> names) { for (int i = 0; i < NAMES.length; i++) { names.add(new Friend(NAMES[i])); } Collections.sort(names); } Friend 类如下:public class Friend implements Comparable<Friend>{ private String name; private String pinyin; public Friend(String name) { super(); this.name = name; // 获取拼音 pinyin = PinyinUtils.getPinyin(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPinyin() { return pinyin; } public void setPinyin(String pinyin) { this.pinyin = pinyin; } @Override public int compareTo(Friend another) { return pinyin.compareTo(another.getPinyin()); }}那么接下来就是 ListView 的 Adapter 了, 这里要注意一点就是, 相同字母开头的名字, 只有第一个显示, 其他的不显示.
@Override public View getView(int position, View convertView, ViewGroup parent) { View view = convertView; if(convertView == null){ view = View.inflate(mContext, R.layout.item_list, null); } ViewHolder mViewHolder = ViewHolder.getHolder(view); Friend friend = names.get(position); // 跟上一个进行比较,如果不同,则显示。 String letter = null; String currentLetter = friend.getPinyin().charAt(0) + ""; if(position == 0){ // 第一个人直接显示 letter = currentLetter; }else { // 获取上一个人的拼音 String preLetter = names.get(position - 1).getPinyin().charAt(0) + ""; if(!TextUtils.equals(preLetter, currentLetter)){ letter = currentLetter; } } mViewHolder.mIndex.setVisibility(letter == null ? View.GONE : View.VISIBLE); if(letter != null){ mViewHolder.mIndex.setText(letter); } mViewHolder.mName.setText(friend.getName()); return view; }
每个 item 的布局如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/tv_index" android:layout_width="match_parent" android:layout_height="40dp" android:background="#555555" android:gravity="center_vertical" android:paddingLeft="20dp" android:visibility="gone" android:text="A" android:textColor="#ffffff" android:textSize="20sp" /> <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="50dp" android:gravity="center_vertical" android:paddingLeft="20dp" android:text="宋江" android:textColor="#000000" android:textSize="22sp" /></LinearLayout>也就是说, 其实每个条目都是有个字母索引, 有个名字, 只是首字母相同的名字, 只有第一个显示索引。最后就是在索引条上滑动的时候移动到 ListView 相应的位置了, 这个就是实现它提供的回调:
QuickIndexBar mQuickIndexBar = (QuickIndexBar) findViewById(R.id.quickIndex); mQuickIndexBar.setLetterChangeListener(new OnLetterChangeListener() { @Override public void OnLetterChange(String letter) { Utils.showToast(getApplicationContext(), letter); // 执行ListView的定位方法 for (int i = 0; i < names.size(); i++) { Friend friend = names.get(i); String l =friend.getPinyin().charAt(0) + ""; if(TextUtils.equals(letter, l)){ // 中断循环,快速定位 mListView.setSelection(i); break; } } } });
0 0
- android快速索引的实现
- Android实现快速索引详解
- 快速索引的简单实现
- Android仿微信实现快速索引选择联系人
- 关于android实现fastindexbar(快速索引)详解
- Android 自定义View-实现快速索引
- Android仿微信实现快速索引选择联系人
- Android 使用RecyclerView实现快速索引
- android 索引的实现
- Android 索引的实现
- Android 索引的实现
- 快速索引实现
- 快速集成android实现listview的字母A-Z排序,界面侧边字母索引
- 快速集成android实现listview的字母A-Z排序,界面侧边字母索引
- Android 地区快速索引
- Android快速索引:实现微信通讯录效果
- Android快速索引:实现微信通讯录效果
- Android09_SearchView联系人的索引快速(弹出)查询的实现
- win7 64位安装redis 及Redis Desktop Manager使用
- WebLogic10.3.6的远程调试设置及修改远程调试端口
- MSScriptControl.ScriptControl控件使用问题
- Git 常用命令
- mysql LIMIT 子句用法及原理
- android快速索引的实现
- js实现window.open不被拦截的解决方法汇总
- Tcpdump简单使用
- php删除目录及目录下文件
- 浏览器缓存机制
- linux 命令行快捷键
- 剑指offer----青蛙跳台阶的解析与实现
- CocoaPods 安装 使用
- 每天一个命令(8) pwd (print name of current/working directory)