android recyclerView上item的EditextView焦点乱跑和数据混乱

       **一:这部分代码是解决数据混乱的问题**

public StandGradeScoreListAdapter(Context context) {
this.context = context;
inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
}

   inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
       //通过设置tag,防止position紊乱
       holder.editReduceMark.setTag(position);
       holder.editReduceMark.clearFocus();
        //1、为了避免TextWatcher在第2步被调用,提前将他移除。
        if (holder.editReduceMark.getTag() != null && holder.editReduceMark.getTag() instanceof TextWatcher) {
            holder.editReduceMark.removeTextChangedListener((TextWatcher) holder.editReduceMark.getTag());
            holder.editReduceMark.clearFocus();
            inputMethodManager.hideSoftInputFromWindow(holder.editReduceMark.getWindowToken(), 0);
        }
        // 第2步:移除TextWatcher之后,设置EditText的Text。
          holder.editReduceMark.setTextColor(context.getResources().getColor(R.color.color_ff333333));
          if (standardList.get(position).getExaminerRemark()!=null){
              holder.editReduceMark.setText(standardList.get(position).getExaminerRemark());
          }else {
              holder.editReduceMark.setText("");
          }

           TextWatcher watcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
            }
            @Override
            public void afterTextChanged(Editable editable) {
                if (holder.editReduceMark.hasFocus()) {//判断当前EditText是否有焦点在
                    if (mTextListener!=null){
                        //通过接口回调将数据传递到Activity中
                        mTextListener.onTextChanged((Integer) holder.editReduceMark.getTag(), editable.toString());//holder.editReduceMark.getText().toString()
                    }
                }
            }
        };

        //设置EditText的焦点监听器判断焦点变化,当有焦点时addTextChangedListener,失去焦点时removeTextChangedListener
        holder.editReduceMark.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (hasFocus) {
                    holder.editReduceMark.addTextChangedListener(watcher);
                    new Handler().postDelayed(() ->  holder.editReduceMark.setSelection(holder.editReduceMark.getText().toString().length()), 30);
                } else {
                    holder.editReduceMark.removeTextChangedListener(watcher);
                    holder.editReduceMark.clearFocus();
                    inputMethodManager.hideSoftInputFromWindow(holder.editReduceMark.getWindowToken(), 0);
                }
            }
        });
       holder.editReduceMark.clearFocus();

二:新建recyclerView的适配管理器FoucsLinearLayoutManager
public class FoucsLinearLayoutManager extends LinearLayoutManager {

public FoucsLinearLayoutManager(Context context) {
    super(context);
}

public FoucsLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
    super(context, orientation, reverseLayout);
}

public FoucsLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
}


/**
 *   public boolean requestChildRectangleOnScreen (View child, Rect rectangle, boolean immediate)
 * 

*   当组里的某个子视图需要被定位在屏幕的某个矩形范围时,调用此方法。重载此方法的ViewGroup可确认以下几点: *

*   * 子项目将是组里的直系子项 *   * 矩形将在子项目的坐标体系中 *   重载此方法的ViewGroup应该支持以下几点: *   * 若矩形已经是可见的,则没有东西会改变 *   * 为使矩形区域全部可见,视图将可以被滚动显示 *   参数 *   child 发出请求的子视图 *   rectangle 子项目坐标系内的矩形,即此子项目希望在屏幕上的定位 *   immediate 设为true,则禁止动画和平滑移动滚动条 *

*   返回值 *   进行了滚动操作的这个组(group),是否处理此操作。 * * @param parent * @param child * @param rect * @param immediate * @return */ @Override public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate) { //这里的child 是整个HeadView 而不是某个具体的editText LogUtil.e("requestChildRectangleOnScreen()====> chlild==" + child.getId(), "parent==" + parent.getId()); return false; } @Override public boolean requestChildRectangleOnScreen(RecyclerView parent, View child, Rect rect, boolean immediate, boolean focusedChildVisible) { //这里的child 是整个HeadView 而不是某个具体的editText LogUtil.e("requestChildRectangleOnScreen( focusedChildVisible=)====> chlild==" + child.getId() , "parent==" + parent.getId()); return false; }

}

三:直接调用
1) recyclerView.setLayoutManager(new FoucsLinearLayoutManager(getContext()));//说明下不要用系统的LinearLayoutManager
2)获取数据的回调方法:
scoreListAdapter.setOnTextChangeListener(new StandGradeScoreListAdapter.onTextChangeListener() {
//带扣分备注
private Map map=new HashMap<>();
@Override
public void onTextChanged(int postion, String content) {
factorList.get(position).getStandardList().get(postion).setExaminerRemark(content);
map = new HashMap<>();
StandardListsBean.DataBean.ContentListBean.FactorListBean.StandardListBean listBean1=new StandardListsBean.DataBean.ContentListBean.FactorListBean.StandardListBean();
listBean1.scoreTableStandardId=factorList.get(position).getStandardList().get(postion).getScoreTableStandardId();
listBean1.remark=factorList.get(position).getStandardList().get(postion).getExaminerRemark();
LogUtil.i(“listBean1Remark”,"==="+factorList.get(position).getStandardList().get(postion).getExaminerRemark());
map.put(factorList.get(position).getStandardList().get(postion).getScoreTableStandardId(), listBean1);

            for (Integer key : map.keySet()) {
                StandardListsBean.DataBean.ContentListBean.FactorListBean.StandardListBean standardListBean = map.get(key);
                boolean door = true;
                for (int i = 0; i 

此部分代码亲测有效,解决了recyclerView嵌套recyclerView,并且子recyclerView上item嵌套多个EdittextView,由于recyclerView的复用问题,导致的数据混乱和焦点胡乱跑,总是跑到页面顶部或者其他item上,体验极度不好,所以再次做个记录

你可能感兴趣的:(移动开发,笔记,android,android,studio)