Filter 具有标题和编辑文本的回收器视图
我有一个recyclerview,其标题是通过使用两种不同的元素类型实现的。在我的标题中有一个编辑文本,我想用它来过滤列表中的非标题元素。下面是我当前的实现,我有一个顾虑和一个问题 我担心的是,我在publishResults中使用notifyItemRangeRemoved和notifyItemInserted所做的操作是更新回收器视图的错误方法。我最初是在做notifyDatasetChanged,但是他的操作会导致标题行也被刷新,编辑文本失去焦点。我真正想要的是一种只刷新项目行并保持标题行不变的方法 我目前的问题是,对于现有代码,如果向下滚动过多,编辑文本就会失去焦点。我希望编辑文本保持焦点,即使我滚动到列表底部 该代码用于将ListView与setHeaderView一起使用,并且以某种方式工作,因此必须有某种方式来实现目标,只是不确定使用recycler视图的诀窍是什么。非常感谢您的帮助Filter 具有标题和编辑文本的回收器视图,filter,android-edittext,android-recyclerview,header-row,Filter,Android Edittext,Android Recyclerview,Header Row,我有一个recyclerview,其标题是通过使用两种不同的元素类型实现的。在我的标题中有一个编辑文本,我想用它来过滤列表中的非标题元素。下面是我当前的实现,我有一个顾虑和一个问题 我担心的是,我在publishResults中使用notifyItemRangeRemoved和notifyItemInserted所做的操作是更新回收器视图的错误方法。我最初是在做notifyDatasetChanged,但是他的操作会导致标题行也被刷新,编辑文本失去焦点。我真正想要的是一种只刷新项目行并保持标题行
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);
}
}
}
}
公共类SideListAdapter扩展了RecyclerView。适配器实现可过滤{
私有静态最终int TYPE_头=0;
私有静态最终整数类型\ u项=1;
私人最终名单数据;
公共列表过滤器数据;
私有HeaderActionListener HeaderActionListener;
public SideListAdapter(上下文上下文、ArrayList数据、HeaderActionListener HeaderActionListener){
这个数据=数据;
filteredData=新的ArrayList(数据);
this.context=上下文;
this.headerActionListener=headerActionListener;
}
@凌驾
公共过滤器getFilter(){
返回新的TestFilter();
}
静态类SideListItem扩展了RecyclerView.ViewHolder{
线性布局基础布局;
公共侧列表项(视图项视图){
超级(项目视图);
baseLayout=(LinearLayout)itemView.findViewById(R.id.settings\u defaultcolor);
}
}
类SideListHeader扩展了SideListHeader{
编辑文本排序;
public SideListHeaderLoggedIn(视图项视图){
超级(项目视图);
sort=(EditText)itemView.findViewById(R.id.sort);
}
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
if(viewType==类型\项){
视图v=LayoutInflater.from(parent.getContext()).flate(R.layout.list_项,parent,false);
返回新的侧列表项(v);
}else if(viewType==SideListHeader){
视图v=LayoutInflater.from(parent.getContext()).flate(R.layout.header,parent,false);
返回新的SideListHeader(v);
}
抛出新的RuntimeException(“没有与类型“+viewType+”+匹配的类型,请确保正确使用类型”);
}
公共接口HeaderActionListener{
布尔onSortEditorAction(TextView arg0、int arg1、KeyEvent arg2);
}
@凌驾
public void onBindViewHolder(RecyclerView.ViewHolder,最终int位置){
if(侧列表头的保持架实例){
最终SideListHeader SideListHeader=(SideListHeader)持有者;
sideListHeader.sort.setOnEditorActionListener(新的TextView.OnEditorActionListener(){
@凌驾
公共布尔onEditorAction(TextView v、int actionId、KeyEvent事件){
}
});
sideListHeader.sort.addTextChangedListener(新的TextWatcher(){
@凌驾
更改前的公共无效(CharSequence CharSequence,int i,int i2,int i3){
}
@凌驾
public void onTextChanged(CharSequence CharSequence,int i,int i2,int i3){
}
@凌驾
public void PostTextChanged(可编辑){
字符串结果=sideListHeader.sort.getText().toString().replaceAll(“,”);
getFilter().filter(结果);
}
});
}
如果(SideListItem的持有者实例){
//给正常物品充气//
}
}
//需要重写此方法
@凌驾
public int getItemViewType(int位置){
if(isPositionHeader(位置)){
返回类型_头;
}
返回类型\ U项目;
}
专用布尔值isPositionHeader(int位置){
返回位置==0;
}
//将getItemcount增加到1。这将是标题行。
@凌驾
public int getItemCount(){
返回filteredData.size()+1;
}
私有类TestFilter扩展了筛选器{
@凌驾
受保护的筛选器结果性能筛选(CharSequence约束){
FilterResults results=新的FilterResults();
字符串前缀=constraint.toString().toLowerCase();
if(前缀.isEmpty()){
ArrayList=新的ArrayList(数据);
结果.值=列表;
results.count=list.size();
}否则{
最终ArrayList=新ArrayList(数据);
final ArrayList nlist=新的ArrayList();
对于(int i=0;i