2

我有一个 recyclerview,它的标题是通过使用两种不同的元素类型实现的。在我的标题中有一个编辑文本,我想用它来过滤列表的非标题元素。下面是我目前的实现,我有一个问题和一个问题。

我担心的是,我在 publishResults 中使用 notifyItemRangeRemoved 和 notifyItemInserted 所做的是更新回收站视图的错误方法。我最初是在做 notifyDatasetChanged 但他会导致标题行也被刷新并且编辑文本失去焦点。我真正想要的是一种只刷新项目行并保持标题行不变的方法。

我当前的问题是,如果我向下滚动太多,则使用现有代码,编辑文本会失去焦点。即使滚动到列表底部,我也希望编辑文本保持焦点。

用于将 ListView 与 setHeaderView 一起使用的代码并且以某种方式工作,因此必须以某种方式实现目标,只是不确定回收器视图的技巧是什么。任何帮助深表感谢。

public class SideListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
    private static final int TYPE_HEADER = 0;
    private static final int TYPE_ITEM = 1;

    private final List<String> data;
    public List<String> filteredData;

    private HeaderActionListener headerActionListener;

    public SideListAdapter(Context context, ArrayList<String> data, HeaderActionListener headerActionListener) {
        this.data = data;
        filteredData = new ArrayList<>(data);
        this.context = context;
        this.headerActionListener = headerActionListener;
    }

    @Override
    public Filter getFilter() {
        return new TestFilter();
    }

    static class SideListItem extends RecyclerView.ViewHolder {
        LinearLayout baseLayout;
        public SideListItem(View itemView) {
            super(itemView);
            baseLayout = (LinearLayout) itemView.findViewById(R.id.settings_defaultcolor);
        }
    }

    class SideListHeader extends SideListHeader {
        EditText sort;

        public SideListHeaderLoggedIn(View itemView) {
            super(itemView);
            sort = (EditText) itemView.findViewById(R.id.sort);
        }
    }


    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_ITEM) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
            return new SideListItem(v);
        } else if (viewType == SideListHeader) {
            View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.header, parent, false);
            return new SideListHeader(v);
        }

        throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
    }

    public interface HeaderActionListener {
        boolean onSortEditorAction(TextView arg0, int arg1, KeyEvent arg2);
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {

        if (holder instanceof SideListHeader) {
            final SideListHeader sideListHeader = (SideListHeader) holder;

            sideListHeader.sort.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                @Override
                public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {

                }
            });

            sideListHeader.sort.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {

                }

                @Override
                public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {

                }

                @Override
                public void afterTextChanged(Editable editable) {
                    String result = sideListHeader.sort.getText().toString().replaceAll(" ", "");
                    getFilter().filter(result);
                }
            });
        }

        if (holder instanceof SideListItem) {            
            // Inflate normal item //
        }
    }

    //    need to override this method
    @Override
    public int getItemViewType(int position) {
        if (isPositionHeader(position)) {
            return  TYPE_HEADER;
        }
        return TYPE_ITEM;
    }

    private boolean isPositionHeader(int position) {
        return position == 0;
    }

    //increasing getItemcount to 1. This will be the row of header.
    @Override
    public int getItemCount() {
        return filteredData.size() + 1;
    }

    private class TestFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            String prefix = constraint.toString().toLowerCase();
            if (prefix.isEmpty()) {
                ArrayList<String> list = new ArrayList<>(data);
                results.values = list;
                results.count = list.size();
            } else {
                final ArrayList<String> list = new ArrayList<>(data);
                final ArrayList<String> nlist = new ArrayList<>();

                for (int i = 0 ; i < list.size(); i++) {
                    String item = list.get(i);
                    if (item.contains(prefix)) {
                        nlist.add(item);
                    }               
                }

                results.values = nlist;
                results.count = nlist.size();
            }
            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            notifyItemRangeRemoved(1, getItemCount()-1);
            filteredData.clear();
            filteredData.addAll((List<String>)results.values);
            for(int i = 1; i < getItemCount() - 1; i++){
                 notifyItemInserted(i);
            }
        }
    }
}
4

0 回答 0