Android實現(xiàn)recyclerview城市字母索引列表
轉拼音的依賴
implementation 'com.github.SilenceDut:jpinyin:v1.0'
FastIndexView實現(xiàn)列表右側字母索引列表
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; /** * 根據(jù)手機的分辨率從 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) { //創(chuàng)建不同的 ViewHolder View view = null; //根據(jù)viewtype來創(chuàng)建條目 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; //主要用于展示數(shù)據(jù)的list private List<CityInfoModel> list; //第一次加載之后緩存的數(shù)據(jù) private List<CityInfoModel> 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<CityInfoModel> cityInfoModels = bindData(list); layoutManager = new LinearLayoutManager(this); recyList.setLayoutManager(layoutManager); recyList.addItemDecoration(new CustomItemDecoration(this, new CustomItemDecoration.TitleDecorationCallback() { @Override public String getGroupId(int position) { //這個是用來比較是否是同一組數(shù)據(jù)的 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綁定數(shù)據(jù) * * @param allCity 所有城市列表 */ public List<CityInfoModel> bindData(List<CityInfoModel> 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<CityInfoModel>() { @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
<?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>
到此這篇關于Android實現(xiàn)recyclerview城市字母索引列表的文章就介紹到這了,更多相關Android recyclerview字母索引內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Android自定義view實現(xiàn)標簽欄功能(只支持固定兩個標簽)
這篇文章主要介紹了Android自定義view實現(xiàn)標簽欄(只支持固定兩個標簽),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06Android使用Intent傳大數(shù)據(jù)簡單實現(xiàn)詳解
這篇文章主要為大家介紹了Android使用Intent傳大數(shù)據(jù)簡單實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03Android 圖片切換器(dp、sp、px) 的單位轉換器
這篇文章主要介紹了Android 圖片切換器(dp、sp、px) 的單位轉換器的相關資料,需要的朋友可以參考下2017-03-03Android中Glide獲取圖片Path、Bitmap用法詳解
這篇文章主要介紹了Android中Glide獲取圖片Path、Bitmap用法以及代碼分析,需要的朋友們參考一下吧。2017-12-12android TextView設置中文字體加粗實現(xiàn)方法
android TextView設置中文字體加粗如何實現(xiàn),接下來介紹實現(xiàn)方法,有需要的朋友可以參考下2013-01-01