Android实现recyclerview城市字母索引列表

 更新时间:2022年01月21日 10:08:33   作者:“嗯哈  
大家好,本篇文章主要讲的是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);
        }
    }

}

MainActivity

public class MainActivity extends AppCompatActivity {

    @BindView(R.id.recy_list)
    RecyclerView recyList;
    @BindView(R.id.fastIndexView)
    FastIndexView fastIndexView;
    //主要用于展示数据的list
    private List<CityInfoModel> list;
    //第一次加载之后缓存的数据
    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) {
                //这个是用来比较是否是同一组数据的
                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<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实现recyclerview城市字母索引列表的文章就介绍到这了,更多相关Android recyclerview字母索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

最新评论