大家好,本篇文章主要讲的是Android实现recyclerview城市字母索引列表,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下。
转拼音的依赖
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<CityAdapter.BaseViewHolder> {
private List<CityInfoModel> mDatas;
private Context mContext;
public CityAdapter(Context context, List<CityInfoModel> 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);
}
}
}
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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_list"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<com.simin.indexrecyclerview.FastIndexView
android:id="@+id/fastIndexView"
android:layout_width="25dp"
android:layout_height="match_parent"
app:layout_constraintHeight_percent="0.7" />
</LinearLayout>