美文网首页android
RecyclerView中的CheckBox与EditText

RecyclerView中的CheckBox与EditText

作者: Elasor丶 | 来源:发表于2018-03-08 14:31 被阅读0次

注:
1.这里只记录了RecyclerView中全为CheckBox或者全为EditText的情况,当列表控件为ListView时,基本思想一样
2.当RecyclerView中全为EditText并且设备存在物理键盘时,滚动后输入文本会记录在复用后position的相应实体类中

Bean:

public class A0Bean {

    //类型1:列表中存在CheckBox
    public static final int ITEM_TYPE_CHECKBOX = 0;
    //类型2:列表中存在EditText
    public static final int ITEM_TYPE_EDITTEXT = 1;

    //标题,可有可无,只是为了方便观察
    private String name;
    //EditText中的内容
    private String content;
    //CheckBox是否选中
    private boolean focused;
    //RecyclerView中getItemViewType()使用;
    private int itemType;

    public A0Bean(String name, String content, int itemType) {
        this(name, content, itemType, false);
    }

    public A0Bean(String name, String content, int itemType, boolean focused) {
        this.name = name;
        this.content = content;
        this.itemType = itemType;
        this.focused = focused;
    }
    //省略set与get方法..
}

Adapter:

public class A0Adapter extends RecyclerView.Adapter<A0Adapter.Holder> {

    private Context mContext;
    private List<A0Bean> mList;

    //EditText类型下判断是否获得焦点
    private int mCurrentFocusPosition = 0;

    public A0Adapter(Context mContext, List<A0Bean> mList) {
        this.mContext = mContext;
        this.mList = mList;
    }

    @Override
    public int getItemCount() {
        return null == mList ? 0 : mList.size();
    }

    @Override
    public int getItemViewType(int position) {
        return mList.get(position).getItemType();
    }

    @Override
    public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
        switch (viewType) {
            case A0Bean.ITEM_TYPE_CHECKBOX:
                View view1 = LayoutInflater.from(mContext).inflate(R.layout.item_a0_content_checkbox, parent, false);
                return new CheckHolder(view1);
            case A0Bean.ITEM_TYPE_EDITTEXT:
                View view2 = LayoutInflater.from(mContext).inflate(R.layout.item_a0_content_edittext, parent, false);
                return new EditHolder(view2);
            default:
                return null;
        }
    }

    @Override
    public void onBindViewHolder(Holder holder, int position) {
        if (holder instanceof CheckHolder) {
            onCheckHolder((CheckHolder) holder, position);
        } else if (holder instanceof EditHolder) {
            onEditHolder((EditHolder) holder, position);
        }
    }

    private void onEditHolder(final EditHolder editHolder, final int position) {
        final A0Bean a0Bean = mList.get(position);

        String name = a0Bean.getName();
        String content = a0Bean.getContent();

        //复用时获取TAG,移除Item中EditText的TextWatcher,非常重要
        Object tag = editHolder.etItemContent.getTag();
        if (null != tag && tag instanceof TextWatcher) {
            editHolder.etItemContent.removeTextChangedListener((TextWatcher) tag);
        }

        editHolder.tvItemTitle.setText(name);
        editHolder.etItemContent.setText(content);

        //当position与之前获得焦点的position相同时获得焦点并将光标移至文本末尾
        if (mCurrentFocusPosition == position) {
            editHolder.etItemContent.requestFocus();
            editHolder.etItemContent.setSelection(editHolder.etItemContent.getText().length());
        }

        //当EditText中的文本变化时保存下来
        TextWatcher watcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                a0Bean.setContent(s.toString());
                mCurrentFocusPosition = position;
                notifyDataSetChanged();
            }
        };
        editHolder.etItemContent.addTextChangedListener(watcher);

        //复用时移除
        editHolder.etItemContent.setTag(watcher);

        //当EditText中文本太长导致EditText与RecyclerView滚动冲突,此为解决方法
        editHolder.etItemContent.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if ((v.getId() == R.id.et_item_content && canVerticalScroll(editHolder.etItemContent))) {
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    if (event.getAction() == MotionEvent.ACTION_UP) {
                        v.getParent().requestDisallowInterceptTouchEvent(false);
                    }
                }
                return false;
            }
        });
    }

    private void onCheckHolder(CheckHolder checkHolder, int position) {
        final A0Bean a0Bean = mList.get(position);

        String name = a0Bean.getName();
        boolean focused = a0Bean.isFocused();

        checkHolder.tvItemTitle.setText(name);
        checkHolder.cbItemSelect.setChecked(focused);

        //注意:这是setOnClickListener
        checkHolder.cbItemSelect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                a0Bean.setFocused(!a0Bean.isFocused());
                notifyDataSetChanged();
            }
        });
    }

    /**
     * EditText竖直方向是否可以滚动
     * @param editText 需要判断的EditText
     * @return true:可以滚动  false:不可以滚动
     */
    private boolean canVerticalScroll(EditText editText) {
        //滚动的距离
        int scrollY = editText.getScrollY();
        //控件内容的总高度
        int scrollRange = editText.getLayout().getHeight();
        //控件实际显示的高度
        int scrollExtent = editText.getHeight() - editText.getCompoundPaddingTop() -editText.getCompoundPaddingBottom();
        //控件内容总高度与实际显示高度的差值
        int scrollDifference = scrollRange - scrollExtent;

        if(scrollDifference == 0) {
            return false;
        }

        return (scrollY > 0) || (scrollY < scrollDifference - 1);
    }

    //省略Holder..
}

最后有一点,RecyclerView向下滚动后,若软键盘未关闭,也会出现开头说的第二点描述的情况,
所以为RecyclerView设置了滚动时关闭软键盘,不过可能不太严谨,应该先判断软键盘的状态

    rvA0Content.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().peekDecorView().getWindowToken(), 0);
        }
    });

相关文章

本文标题:RecyclerView中的CheckBox与EditText

本文链接:https://www.haomeiwen.com/subject/vokyfftx.html