文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

在这里插入图片描述

转拼音的依赖

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(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;

    
    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;
            }
        }
    }

    
    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字母索引内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯