转拼音的依赖
implementation 'com.github.SilenceDut:jpinyin:v1.0'
FastIndexView实现列表右侧字母索引列表
public class FastIndexView extends View { private static final String INDEX_NAME = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ"; private OnLetterUpdateListener listener; private Paint mPaint; private float cellHeight, viewWidth; private int touchIndex = -1, selectedColor; public FastIndexView(Context context) { this(context, null); } public FastIndexView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public FastIndexView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setTextSize(AppUtils.dp2px(14)); mPaint.setAntiAlias(true); //获取文字被选中的颜色 // selectedColor = ContextCompat.getColor(context, ); selectedColor = Color.parseColor("#999DA1"); } @Override protected void onDraw(Canvas canvas) { for (int i = 0; i < INDEX_NAME.length(); i++) { String text = INDEX_NAME.substring(i, i + 1); //计算绘制字符的X方向起点 int x = (int) (viewWidth / 2.0f - mPaint.measureText(text) / 2.0f); Rect bounds = new Rect(); mPaint.getTextBounds(text, 0, text.length(), bounds); int textHeight = bounds.height(); //计算绘制字符的Y方向起点 int y = (int) (cellHeight / 2.0f + textHeight / 2.0f + i * cellHeight); mPaint.setColor(/*touchIndex == i ? Color.WHITE : */selectedColor); canvas.drawText(text, x, y, mPaint); } } @Override public boolean onTouchEvent(MotionEvent event) { int index; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: //计算当前触摸的字符索引 index = (int) (event.getY() / cellHeight); if (index >= 0 && index < INDEX_NAME.length()) { if (listener != null) { listener.onLetterUpdate(INDEX_NAME.substring(index, index + 1)); } touchIndex = index; } break; case MotionEvent.ACTION_MOVE: //计算当前触摸的字符索引 index = (int) (event.getY() / cellHeight); if (index >= 0 && index < INDEX_NAME.length()) { if (index != touchIndex) { if (listener != null) { listener.onLetterUpdate(INDEX_NAME.substring(index, index + 1)); } touchIndex = index; } } break; } invalidate(); return true; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //得到当前控件的宽度 viewWidth = getMeasuredWidth(); int mHeight = getMeasuredHeight(); //获取单个字符能够拥有的高度 cellHeight = mHeight * 1.0f / INDEX_NAME.length(); } public interface OnLetterUpdateListener { void onLetterUpdate(String letter); } public void setListener(OnLetterUpdateListener listener) { this.listener = listener; } }
public class AppUtils { private static float density; /** * 根据手机的分辨率从 dp 的单位 转成为 px(像素) */ public static int dp2px(float dpValue) { if (density == 0) density = Resources.getSystem().getDisplayMetrics().density; return (int) (0.5f + dpValue * Resources.getSystem().getDisplayMetrics().density); } }
CityAdapter
public class CityAdapter extends RecyclerView.Adapter{ private List mDatas; private Context mContext; public CityAdapter(Context context, List data) { this.mDatas = data; this.mContext = context; } @Override public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //创建不同的 ViewHolder View view = null; //根据viewtype来创建条目 view = LayoutInflater.from(mContext).inflate(R.layout.item_layout_normal, parent, false); return new NormalHolder(view); } @Override public void onBindViewHolder(BaseViewHolder holder, final int position) { CityInfoModel cityInfoModel = mDatas.get(position); NormalHolder realHolder = (NormalHolder) holder; realHolder.tvContent.setText(cityInfoModel.getCityName()); realHolder.tvContent.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } }); } static class BaseViewHolder extends RecyclerView.ViewHolder { BaseViewHolder(View itemView) { super(itemView); } } @Override public int getItemCount() { if (mDatas != null) { return mDatas.size(); } return 0; } private class NormalHolder extends BaseViewHolder { TextView tvContent; public NormalHolder(View itemView) { super(itemView); tvContent = itemView.findViewById(R.id.tv_city); } } }
MainActivity
public class MainActivity extends AppCompatActivity { @BindView(R.id.recy_list) RecyclerView recyList; @BindView(R.id.fastIndexView) FastIndexView fastIndexView; //主要用于展示数据的list private Listlist; //第一次加载之后缓存的数据 private List cacheList; //页面recyclerview的适配器 private CityAdapter mainAdapter; //布局管理器 private LinearLayoutManager layoutManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); initAdapter(); initListener(); } private void initAdapter() { list = new ArrayList<>(); cacheList = new ArrayList<>(); list.add(new CityInfoModel("安徽省")); list.add(new CityInfoModel("北京市")); list.add(new CityInfoModel("上海市")); list.add(new CityInfoModel("广州市")); list.add(new CityInfoModel("深圳市")); list.add(new CityInfoModel("天津市")); list.add(new CityInfoModel("南京市")); list.add(new CityInfoModel("杭州市")); list.add(new CityInfoModel("重庆市")); list.add(new CityInfoModel("成都市")); list.add(new CityInfoModel("石家庄市")); list.add(new CityInfoModel("自贡市")); list.add(new CityInfoModel("攀枝花市")); list.add(new CityInfoModel("泸州市")); list.add(new CityInfoModel("德阳市")); list.add(new CityInfoModel("绵阳市")); list.add(new CityInfoModel("广元市")); list.add(new CityInfoModel("遂宁市")); List cityInfoModels = bindData(list); layoutManager = new LinearLayoutManager(this); recyList.setLayoutManager(layoutManager); recyList.addItemDecoration(new CustomItemDecoration(this, new CustomItemDecoration.TitleDecorationCallback() { @Override public String getGroupId(int position) { //这个是用来比较是否是同一组数据的 return list.get(position).getSortId(); } @Override public String getGroupName(int position) { CityInfoModel cityInfoModel = list.get(position); //拼音都是小写的 return cityInfoModel.getSortId().toUpperCase(); } })); mainAdapter = new CityAdapter(this, cityInfoModels); recyList.setAdapter(mainAdapter); } private void initListener() { fastIndexView.setListener(new FastIndexView.OnLetterUpdateListener() { @Override public void onLetterUpdate(String letter) { moveToLetterPosition(letter); } }); } //滚动recyclerview private void moveToLetterPosition(String letter) { //这里主要是为了跳转到最顶端 if ("#".equals(letter)) { letter = "*"; } for (int i = 0; i < list.size(); i++) { CityInfoModel cityInfoModel = list.get(i); if (cityInfoModel.getSortId().toUpperCase().equals(letter)) { layoutManager.scrollToPositionWithOffset(i, 0); return; } } } /** * 给View绑定数据 * * @param allCity 所有城市列表 */ public List bindData(List allCity) { if (allCity != null) { for (CityInfoModel cityModel : allCity) { try { String pingYin = PinyinHelper.convertToPinyinString(cityModel.getCityName(), " ", PinyinFormat.WITHOUT_TONE); cacheList.add(new CityInfoModel(cityModel.getCityName(), pingYin.substring(0, 1), pingYin)); } catch (PinyinException e) { e.printStackTrace(); } } //排序 Collections.sort(cacheList, new Comparator () { @Override public int compare(CityInfoModel o1, CityInfoModel o2) { return o1.getSortName().compareTo(o2.getSortName()); } }); this.list.clear(); this.list.addAll(cacheList); } return list; } }
CityInfoModel
public class CityInfoModel { private String cityName;//用于显示的城市的名字 private String sortId;//用于排序的id 在这里是城市拼音的首字母 private String sortName;//用于排序的全拼音 这个是用于后面的排序以及搜索 public CityInfoModel(String cityName) { this.cityName = cityName; } public CityInfoModel(String cityName, String sortId, String sortName) { this.cityName = cityName; this.sortId = sortId; this.sortName = sortName; } public String getCityName() { return cityName; } public void setCityName(String cityName) { this.cityName = cityName; } public String getSortId() { return sortId; } public void setSortId(String sortId) { this.sortId = sortId; } public String getSortName() { return sortName; } public void setSortName(String sortName) { this.sortName = sortName; } }
activity_main
到此这篇关于Android实现recyclerview城市字母索引列表的文章就介绍到这了,更多相关Android recyclerview字母索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!