自定义View实现联系人快速查找
2016-11-09 02:44
288 查看
这个功能也经常用到比如:微信好友列表, 联系人通讯录, 应用管理, 文件管理等
效果图:
实现步骤:
- 绘制 A-Z.的索引,处理Touch事件
- 根据回调回调显示当前索引
- 汉字转换成拼音,将数据进行分组
- 在ListView中使用自定义控件
自定义View代码:
MainActivity:
Adapter:
获取拼音:
效果图:
实现步骤:
- 绘制 A-Z.的索引,处理Touch事件
- 根据回调回调显示当前索引
- 汉字转换成拼音,将数据进行分组
- 在ListView中使用自定义控件
自定义View代码:
public class QuickIndexView extends View { int touchIndex = -1; 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; private int cellWidth; private float cellHeight; private OnLetterIndexChangeListener mLetterIndexChangeListener; public interface OnLetterIndexChangeListener { void onLetterIndexChange(String letter); } public void setOnLetterIndexChangeListener(OnLetterIndexChangeListener mLetterIndexChangeListener) { this.mLetterIndexChangeListener = mLetterIndexChangeListener; } public QuickIndexView(Context context) { this(context, null); } public QuickIndexView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public QuickIndexView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); // Paint.ANTI_ALIAS_FLAG 字体抗锯齿 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.GRAY); // 粗体 mPaint.setTypeface(Typeface.DEFAULT_BOLD); mPaint.setTextSize(DensityUtils.dp2px(getContext(), 12)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (int i = 0; i < LETTERS.length; i++) { String letter = LETTERS[i]; // 计算字体放置x坐标 int x = (int) (cellWidth / 2.0f - mPaint.measureText(letter) / 2.0f); // 获取文本的高度 Rect rect = new Rect();// 矩形 mPaint.getTextBounds(letter, 0, letter.length(), rect); int letterHeight = rect.height(); // 每个text单元格增加高度 int y = (int) (cellHeight / 2.0f + letterHeight / 2.0f + i * cellHeight); // 根据按下的字母, 设置画笔颜色 mPaint.setColor(touchIndex == i ? Color.BLACK : Color.GRAY); canvas.drawText(letter, x, y, mPaint); } } @Override public boolean onTouchEvent(MotionEvent event) { int index = 0; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 得到index值,总高度/每个单元格的高度 index = (int) (event.getY() / cellHeight); if (index >= 0 && index < LETTERS.length) { // 判断是否同个一index,是就不再显示 if (touchIndex != index) { if (mLetterIndexChangeListener != null) { mLetterIndexChangeListener.onLetterIndexChange(LETTERS[index]); } // 记录当前index touchIndex = index; } } break; case MotionEvent.ACTION_MOVE: index = (int) (event.getY() / cellHeight); if (index >= 0 && index < LETTERS.length) { if (touchIndex != index) { if (mLetterIndexChangeListener != null) { mLetterIndexChangeListener.onLetterIndexChange(LETTERS[index]); } touchIndex = index; } } break; case MotionEvent.ACTION_UP: touchIndex = -1; break; } invalidate(); return true; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); // 获取单元格的宽 cellWidth = getMeasuredWidth(); int mHeight = getMeasuredHeight(); // 获取单元格的高 cellHeight = mHeight * 1.0f / LETTERS.length; } }
MainActivity:
public class MainActivity extends AppCompatActivity { private ArrayList<Person> datas; private TextView tv_center; private Animation alpha_show; private Animation alpha_die; private boolean animationState = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); alpha_show = AnimationUtils.loadAnimation(this, R.anim.alpha_show); alpha_die = AnimationUtils.loadAnimation(this, R.anim.alpha_die); datas = new ArrayList<>(); QuickIndexView qi_view = (QuickIndexView) findViewById(R.id.qi_view); tv_center = (TextView) findViewById(R.id.tv_center); final ListView lv_itme = (ListView) findViewById(R.id.lv_itme); qi_view.setOnLetterIndexChangeListener(new QuickIndexView.OnLetterIndexChangeListener() { @Override public void onLetterIndexChange(String letter) { showCenterIndex(letter); for (int i = 0; i < datas.size(); i++) { Person person = datas.get(i); String index = person.getPinYin().charAt(0)+""; if (TextUtils.equals(index,letter)){ lv_itme.setSelection(i); break; } } } }); datas = fillAndSortData(); lv_itme.setAdapter(new MainAdapter(datas, getApplicationContext())); } private Handler mHandler = new Handler(); private void showCenterIndex(String letter) { tv_center.setText(letter); if (animationState){ tv_center.startAnimation(alpha_show); animationState = false; } tv_center.setVisibility(View.VISIBLE); mHandler.removeCallbacksAndMessages(null); mHandler.postDelayed(new Runnable() { @Override public void run() { animationState = true; tv_center.startAnimation(alpha_die); tv_center.setVisibility(View.GONE); } },1000); } private ArrayList<Person> fillAndSortData() { ArrayList<Person> Persons = new ArrayList<>(); for (int i = 0; i < Cheeses.NAMES.length; i++) { String name = Cheeses.NAMES[i]; Persons.add(new Person(name)); } Collections.sort(Persons); return Persons; } }
Adapter:
public class MainAdapter extends BaseAdapter { private ArrayList<Person> datas; Context context; public MainAdapter(ArrayList<Person> datas, Context context) { this.datas = datas; this.context = context; } @Override public int getCount() { return datas.size(); } @Override public Object getItem(int position) { return datas.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder mHolder = null; if (convertView == null) { mHolder = new ViewHolder(); }else{ mHolder = (ViewHolder) convertView.getTag(); } String str = null; String index = datas.get(position).getPinYin().charAt(0) + ""; if (position == 0) { str = index; } else { //获取上一个inedx判断时否相等 String preIndex = datas.get(position - 1).getPinYin().charAt(0) + ""; if (!TextUtils.equals(preIndex, index)) { str = index; } } // 根据str是否为空缺定是否显示 mHolder.lv_index.setVisibility(str == null?View.GONE: View.VISIBLE); mHolder.lv_index.setText(index); mHolder.lv_name.setText(datas.get(position).getName().trim()); return mHolder.getView(); } class ViewHolder { public TextView lv_index; public TextView lv_name; public View view; public ViewHolder() { view = View.inflate(context, R.layout.list_itme, null); lv_index = (TextView) view.findViewById(R.id.lv_index); lv_name = (TextView) view.findViewById(R.id.lv_name); view.setTag(this); } public View getView() { return view; } } }
获取拼音:
public class PinYinHelper { public static String getPinyin(String text) { HanyuPinyinOutputFormat hFormat = new HanyuPinyinOutputFormat(); // 大写 hFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE); // 没有声调 hFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE); char[] charArray = text.toCharArray(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < charArray.length; i++) { char c = charArray[i]; // 空格跳过 if (Character.isWhitespace(c)) { continue; } if (c >= -127 && c < 128) { // 不是汉字 sb.append(c); } else { String pinYin = ""; try { pinYin = PinyinHelper.toHanyuPinyinStringArray(c, hFormat)[0]; sb.append(pinYin); } catch (BadHanyuPinyinOutputFormatCombination e) { e.printStackTrace(); sb.append(pinYin); } } } return sb.toString(); } }
相关文章推荐
- 自定义view实现联系人快速检索
- Android09_SearchView联系人的索引快速(弹出)查询的实现
- android自定义View----通讯录导航栏(快速查找索引)
- 自定义View之快速索引栏的实现
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- 自定义View 实现字母快速索引控件
- 自定义View:快速索引实现
- 实现带快速导航的ListView(自定义View和自定义ViewGroup的结合),可直接使用和修改使用
- Android实现列表仿联系人快速查找和关键字搜索
- SupSurfaceCanvasView--快速实现自定义绘制SurfaceView帮助类
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- 4、快速实现自定义View
- Android自定义View——实现联系人列表字母索引
- 自定义ViewGroup 实现拖动跟快速滚动的效果
- Android客户端之“微服私访”App的系统学习(七)XRecyclerView快速实现列表界面+自定义Search输入框,软键盘搜索按钮监听+TextView部分样式改变
- 安卓仿手机联系人右侧快速搜索菜单自定义View
- 自定义TabBarView,快速实现Tab+ViewPager的Activity
- 自定义View实现手机qq5.X的抽屉特效和聊天界面联系人左滑功能
- Android 自定义View-实现快速索引