Android recyclView实现通讯录

本文介绍了如何使用RecyclerView结合GridLayoutManager手写实现通讯录功能,特别强调了根据数据动态显示或隐藏字母指示条,并提供了关键代码段,包括自定义LinearLayout、Adapter、ItemDecoration和汉字转拼音的方法。通过这种方式,实现了类似微信通讯录的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先上设计图

网上找了一些代码 感觉没有办法实现,所以干脆自己手写,使用的是recyclerview +GridLayoutManager

然后右边自己写的自定义LinearLayout 直接上代码 因为我看许多按钮都是写死的26个字母 我想做的是,如果这个字母下没有数据就不显示,所以数据由外面传递过来

 

public class LetterView extends LinearLayout {

    private Context mContext;
    private CharacterClickListener mListener;
    private List<TextView> textViews = new ArrayList<>();
    private int choose = -1;// 选中

    public LetterView(Context context) {
        super(context);

        mContext = context;

        setOrientation(VERTICAL);
    }

    public void setItems(List<String> list) {
        for (int i = 0; i < list.size(); i++) {

            TextView tv = buildTextLayout(list.get(i));

            addView(tv);
        }
    }

    private TextView buildTextLayout(final String str) {
        TextView tv = new TextView(mContext);
        tv.setPadding(0, AndroidUtilities.dp(1), 0, AndroidUtilities.dp(1));
        tv.setGravity(Gravity.CENTER);
        tv.setClickable(true);
        tv.setTextColor(Theme.TEXT_COLOR_2);
        tv.setText(str);
        tv.setTextSize(11);
        tv.setLayoutParams(LayoutHelper.createLinear(25, LayoutHelper.WRAP_CONTENT));

        textViews.add(tv);

        return tv;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        final float y = event.getY();// 点击y坐标
        final int oldChoose = choose;
        final int c = (int) (y / getHeight() * textViews.size());// 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.

        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                choose = -1;

                if (mListener != null) {
                    mListener.onCancel();
                }

                break;
            default:
                if (oldChoose != c) {
                    if (c >= 0 && c < textViews.size()) {
                        if (mListener != null) {
                            mListener.clickCharacter(textViews.get(c).getText().toString());
                        }

                        choose = c;
                    }
                }
                break;
        }
        return true;
    }

    public void setCharacterListener(CharacterClickListener listener) {
        mListener = listener;
    }

    public interface CharacterClickListener {
        void clickCharacter(String character);

        void onCancel();
    }
}

然后在activity中使用

 

RelativeLayout container = new RelativeLayout(context);
container.setPadding(AndroidUtilities.dp(15), 0, AndroidUtilities.dp(0), 0);

recyclerView = new RecyclerView(context);
recyclerView.setHasFixedSize(true);
recyclerView.setPadding(0, 0, AndroidUtilities.dp(25), 0);
gridLayoutManager = new GridLayoutManager(mContext, 3, GridLayoutManager.VERTICAL, false);

recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new MyItemDecoration());
container.addView(recyclerView, LayoutHelper.createRelative(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));

letterView = new LetterView(context);
letterView.setCharacterListener(new LetterView.CharacterClickListener() {
    @Override
    public void clickCharacter(String character) {
        if (hintView.getVisibility() == View.GONE) {
            textAnimation(true);
        }

        hintView.setText(character);

        if (lettes.containsKey(character)) {
            gridLayoutManager.scrollToPositionWithOffset(lettes.get(character), 0);
        }
    }

    @Override
    public void onCancel() {
        if (hintView.getVisibility() == View.VISIBLE) {
            isRunAnimation = false;//保证立即执行隐藏动画

            textAnimation(false);
        }
    }
});
RelativeLayout.LayoutParams letterLP = LayoutHelper.createRelative(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT);
letterLP.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
letterLP.addRule(RelativeLayout.CENTER_VERTICAL);
container.addView(letterView, letterLP);

adapter = new ScoreFilterAdapter(context);
adapter.setListener(listener);
recyclerView.setAdapter(adapter);

hintView = new TextView(context);
hintView.setTypeface(Theme.fontBold);
hintView.setBackgroundResource(R.drawable.bg_score_filter_text);
hintView.setVisibility(View.GONE);
hintView.setGravity(Gravity.CENTER);
hintView.setTextColor(Color.WHITE);
hintView.setTextSize(24);
container.addView(hintView, LayoutHelper.createRelative(100, 100, RelativeLayout.CENTER_IN_PARENT));

然后上adapter的代码

 

public class ScoreFilterAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    private Context mContext;

    private List<ScoreFilterActivity.MatchData> list;
    private Map<String, Integer> lettes;

    private List<ScoreFilterActivity.MatchData> currSelectList;

    public ScoreFilterAdapter(Context context) {
        mContext = context;
        list = new ArrayList<>();
        lettes = new HashMap<>();
        currSelectList = new ArrayList<>();
    }

    public void setList(List<ScoreFilterActivity.MatchData> data, Map<String, Integer> lettes) {
        if (data != null && lettes != null) {
            this.list.clear();
            this.list.addAll(data);
            this.lettes.clear();
            this.lettes.putAll(lettes);
            notifyDataSetChanged();
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case ITEM1:
                return new ItemViewHolder(new ScoreFilterCell(mContext), true);
            case ITEM2:
                return new ItemViewHolder(new ScoreFilterCell(mContext), false);
        }
        return null;
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ScoreFilterActivity.MatchData bean = list.get(position);
        ((ItemViewHolder) holder).setData(bean);
    }

    //建立不同布局
    public final static int ITEM1 = 101;
    public final static int ITEM2 = 102;

    @Override
    public int getItemViewType(int position) {
        //根据每个字母下第一个联系人在数据中的位置,来显示headView
        ScoreFilterActivity.MatchData matchData = list.get(position);
        if (lettes.get(matchData.getFirstChar()) == position) {
            return ITEM1;
        } else {
            return ITEM2;
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if (manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    switch (type) {
                        case ITEM1:
                            return 3;
                        case ITEM2:
                            return 1;
                        default:
                            return 1;
                    }
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class ItemViewHolder extends RecyclerView.ViewHolder {

        private ScoreFilterCell cell;

        public ItemViewHolder(ScoreFilterCell cell, boolean isShow) {
            super(cell);

            this.cell = cell;

            this.cell.isShowHead(isShow);
        }

        public void setData(final ScoreFilterActivity.MatchData data) {
            this.cell
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值