使用RecyclerView自定义目录快速索引
2017-01-11 23:26
357 查看
快速索引在众多APP中是很常见的一个功能,尤其是在即时通讯和搜索的功能中,最近使用到就写了一个,希望对大家有用!
先看一下效果:
首先我们要写的就是自定义QuickIndexBar快速索引类
然后在xml中进行应用
记得引入pinyin4j jar包,具体可以在网上下载也可以从demo获取然后查看bean对象,并获取拼音字母
获得拼音转换类
跳转指定条目
MainActivity中的操作
最后看看Adapter中的操作
到这里完成操作,睡觉啦!困屎了……………………….
Demo下载地址:http://download.csdn.net/download/huangxiaoguo1/9735282
先看一下效果:
首先我们要写的就是自定义QuickIndexBar快速索引类
package com.example.quickindebar.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class QuickIndexBar extends View { 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 paint; private int mCellWidth; private int mCellHeight; private float mTextHeight; private int currentIndex =-1; private OnLetterChangeListener onLetterChangeListener; public OnLetterChangeListener getOnLetterChangeListener() { return onLetterChangeListener; } public void setOnLetterChangeListener(OnLetterChangeListener onLetterChangeListener) { this.onLetterChangeListener = onLetterChangeListener; } public interface OnLetterChangeListener{ void onLetterChange(String letter); //手指抬起 void onReset(); } 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); paint = new Paint(); // paint.setColor(Color.); paint.setColor(Color.BLACK); paint.setTextSize(20); //消除锯齿 paint.setAntiAlias(true); Paint.FontMetrics fontMetrics = paint.getFontMetrics(); mTextHeight = (float) Math.ceil( fontMetrics.descent - fontMetrics.ascent); //1.1---2 2.1--3 } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCellWidth = getMeasuredWidth(); mCellHeight = getMeasuredHeight()/LETTERS.length; } /** * 绘制控件 * @param canvas */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 字.画字(); for (int i = 0; i < LETTERS.length; i++) { String letter = LETTERS[i]; float mTextWidth = paint.measureText(letter); float x =(mCellWidth- mTextWidth)*0.5f; float y = (mCellHeight + mTextHeight) *0.5f+mCellHeight*i; if (i == currentIndex){ paint.setColor(Color.GREEN); }else{ paint.setColor(Color.BLACK); } canvas.drawText(letter, x,y,paint); } } /** * 处理 按下 移动 手指抬起 * @param event * @return */ @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: System.out.println("我按下了!!"); int downY = (int) event.getY(); //获取当前索引 currentIndex = downY/mCellHeight; if (currentIndex<0||currentIndex>LETTERS.length-1){ }else{ // ToastUtil.showToast(getContext(),LETTERS[currentIndex]); if (onLetterChangeListener != null){ onLetterChangeListener.onLetterChange(LETTERS[currentIndex]); } } //重新绘制 invalidate(); break; case MotionEvent.ACTION_MOVE: System.out.println("我移动了!!"); int moveY = (int) event.getY(); //获取当前索引 currentIndex = moveY/mCellHeight; if (currentIndex<0||currentIndex>LETTERS.length-1){ }else{ // ToastUtil.showToast(getContext(),LETTERS[currentIndex]); if (onLetterChangeListener != null){ onLetterChangeListener.onLetterChange(LETTERS[currentIndex]); } } //重新绘制 invalidate(); break; case MotionEvent.ACTION_UP: System.out.println("我手指抬起了!!"); currentIndex = -1; //手动刷新 invalidate(); //表示手指抬起了 if(onLetterChangeListener!= null){ onLetterChangeListener.onReset(); } break; } // 为了 能够接受 move+up事件 return true; } }
然后在xml中进行应用
<?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.support.v7.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="match_parent"/> <com.example.quickindebar.view.QuickIndexBar android:layout_width="30dp" android:id="@+id/quickindexbar" android:layout_height="match_parent" android:layout_alignParentRight="true" android:background="#dcdcdc" /> <TextView android:layout_width="80dp" android:textColor="#fff" android:visibility="gone" android:background="@drawable/shape_corners" android:layout_centerInParent="true" android:text="A" android:id="@+id/tv_tips" android:textSize="20dp" android:gravity="center" android:layout_height="80dp" /> </RelativeLayout>
记得引入pinyin4j jar包,具体可以在网上下载也可以从demo获取然后查看bean对象,并获取拼音字母
package com.example.quickindebar.bean; import com.example.quickindebar.utils.PinYinUtil; /** * Created by 黄家三少 on 2017/1/11. */ public class HaoHan implements Comparable<HaoHan> { public String name; public String pinyin; public HaoHan(String name){ this.name = name; this.pinyin= PinYinUtil.getPinYin(name); } @Override public int compareTo(HaoHan another) { return this.pinyin.compareTo(another.pinyin); } }
获得拼音转换类
package com.example.quickindebar.utils; import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType; import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat; import net.sourceforge.pinyin4j.format.HanyuPinyinToneType; import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination; /** * Created by 黄家三少 on 2017/1/11. */ public class PinYinUtil { public static String getPinYin(String text) { { StringBuilder stringBuilder = null; try { HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE); format.setCaseType(HanyuPinyinCaseType.UPPERCASE); stringBuilder = new StringBuilder(); char[] chars = text.toCharArray(); for (char ch : chars) { if (Character.isWhitespace(ch)) { continue; } if (ch > 128 || ch < -127) { String[] array = PinyinHelper.toHanyuPinyinStringArray(ch, format); stringBuilder.append(array[0]); } } } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { badHanyuPinyinOutputFormatCombination.printStackTrace(); } return stringBuilder.toString(); } } }
跳转指定条目
/** * RecyclerView 移动到当前位置, * * @param manager manager * @param mRecyclerView 当前的RecyclerView * @param n 要跳转的位置 */ public static void MoveToPosition(LinearLayoutManager manager, RecyclerView mRecyclerView, int n) { int firstItem = manager.findFirstVisibleItemPosition(); int lastItem = manager.findLastVisibleItemPosition(); if (n <= firstItem) { mRecyclerView.scrollToPosition(n); } else if (n <= lastItem) { int top = mRecyclerView.getChildAt(n - firstItem).getTop(); mRecyclerView.scrollBy(0, top); } else { mRecyclerView.scrollToPosition(n); } }
MainActivity中的操作
package com.example.quickindebar; import android.content.Context; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; import android.view.View; import android.widget.TextView; import com.example.quickindebar.adapter.MyAdapter; import com.example.quickindebar.bean.Cheeses; import com.example.quickindebar.bean.HaoHan; import com.example.quickindebar.utils.UIUtils; import com.example.quickindebar.view.QuickIndexBar; import com.example.quickindebar.view.RecycleViewDivider; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MainActivity extends AppCompatActivity { private QuickIndexBar quickindexbar; private RecyclerView mRecyclerView; private List<HaoHan> haoHans = new ArrayList<HaoHan>(); private TextView tv_tips; private Context mContext; private MyAdapter mAdapter; private LinearLayoutManager manager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; fillDataAndSort(); initView(); initListener(); } /** * 填充数据&排序 */ private void fillDataAndSort() { HaoHan haoHan; for (int i = 0; i < Cheeses.NAMES.length; i++) { haoHan = new HaoHan(Cheeses.NAMES[i]); haoHans.add(haoHan); } //排序 Collections.sort(haoHans); } private void initView() { tv_tips = (TextView) findViewById(R.id.tv_tips); mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview); quickindexbar = (QuickIndexBar) findViewById(R.id.quickindexbar); manager = new LinearLayoutManager(mContext); manager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(manager); int mColor = ContextCompat.getColor(mContext, R.color.light_gray); mRecyclerView.addItemDecoration(new RecycleViewDivider(mContext, LinearLayoutManager.HORIZONTAL, 2, mColor)); mAdapter = new MyAdapter(mContext, haoHans); mRecyclerView.setAdapter(mAdapter); } private void initListener() { quickindexbar.setOnLetterChangeListener(new QuickIndexBar.OnLetterChangeListener() { //选择的字母 变化的时候调用 @Override public void onLetterChange(String letter) { // ToastUtil.showToast(MainActivity.this, letter); tv_tips.setVisibility(View.VISIBLE); tv_tips.setText(letter); for (int i = 0; i < haoHans.size(); i++) { if (TextUtils.equals(haoHans.get(i).pinyin.charAt(0) + "", letter)) { UIUtils.MoveToPosition(manager, mRecyclerView, i); break; } } } //手指抬起的时候调用 @Override public void onReset() { tv_tips.setVisibility(View.GONE); } }); mAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void OnClick(int position) { UIUtils.showToast(Cheeses.NAMES[position]); } }); } }
最后看看Adapter中的操作
package com.example.quickindebar.adapter; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import com.example.quickindebar.R; import com.example.quickindebar.bean.HaoHan; import java.util.List; import butterknife.ButterKnife; import butterknife.InjectView; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private Context mContext; private List<HaoHan> haoHans; public MyAdapter(Context context) { this.mContext = context; } private OnItemClickListener onItemClickListener; public MyAdapter(Context mContext, List<HaoHan> haoHans) { this.mContext = mContext; this.haoHans = haoHans; } public interface OnItemClickListener { void OnClick(int position); } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.onItemClickListener = onItemClickListener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(mContext).inflate(R.layout.item_haohan, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(ViewHolder holder, final int position) { HaoHan preHaohan = null; if (position == 0) { preHaohan = null; } else { preHaohan = haoHans.get(position - 1);// 上一个好汉 } HaoHan haoHan = haoHans.get(position); boolean showPinyin = true; if (preHaohan == null) { showPinyin = true; } else { if (haoHan.pinyin.charAt(0) == preHaohan.pinyin.charAt(0)) { showPinyin = false; } else { showPinyin = true; } } // char holder.tvPinyin.setVisibility(showPinyin ? View.VISIBLE : View.GONE); holder.tvPinyin.setText(haoHan.pinyin.charAt(0) + ""); // holder.tvName.setText(haoHan.name); holder.tvName.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (onItemClickListener != null) { onItemClickListener.OnClick(position); } } }); } @Override public int getItemCount() { return haoHans.size(); } static class ViewHolder extends RecyclerView.ViewHolder { @InjectView(R.id.tv_pinyin) TextView tvPinyin; @InjectView(R.id.tv_name) TextView tvName; public ViewHolder(View itemView) { super(itemView); ButterKnife.inject(this, itemView); } } }
到这里完成操作,睡觉啦!困屎了……………………….
Demo下载地址:http://download.csdn.net/download/huangxiaoguo1/9735282
相关文章推荐
- Android 使用RecyclerView实现快速索引
- iOS之TableView分组目录(快速索引)的使用
- 快速索引 (对View的自定义)
- Android使用RecyclerView实现自定义列表、点击事件以及下拉刷新
- Android开发-自定义View-AndroidStudio(十四)快速索引(1)
- [AS2.2]Behavior使用和自定义RecyclerView万用适配器
- 自定义view实战笔记--快速索引
- 快速索引 (对View的自定义,黑马程序员)
- 学习笔记 Tianmao 篇 recyclerView 的自定义使用
- 使用自定义ViewHelper来简化Asp.net MVC view的开发-索引
- RecyclerView简单使用之自定义RecyclerView分割线
- Android 首字母分组快速索引 自定义WaveSiderBarView
- 快速索引 (对View的自定义)
- android中RecyclerView使用自定义的列表布局
- Android开发-自定义View-AndroidStudio(十五)快速索引(2)
- iOS开发 自定义tableView样式(使用代码/使用Interface Builder)、分组显示、给TableView增加索引、给TableView增加SearchBariOS开发 自定义tab
- 快速索引 (对View的自定义)
- Android 自定义View-实现快速索引
- 关于RecyclerView的下拉刷新,自定义帧动画,第三方框架PtrFrameLayout使用手册
- Android开发-自定义View-AndroidStudio(十五)快速索引(2)