使用搜索视图未更新适配器

时间:2018-01-17 13:14:52

标签: java android android-recyclerview android-adapter

这基本上是一个笔记应用程序,我们通过从用户那里获取标题和描述来动态地向我们的应用程序添加数据,问题是当我们通过标题搜索某些笔记时,而不是给出可能的笔记适配器中设置的数据消失,逻辑写入适配器类

中的filter()函数

MainActivity.java

public class MainActivity extends AppCompatActivity implements SearchView.OnQueryTextListener {
private ArrayList<Notes> list;
private NotesAdapter notesAdapter;//this is our notes adapter
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
@Override //
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    list=new ArrayList<>();//this is the list which we have to pass into adapter
    recyclerView=findViewById(R.id.rv);
    notesAdapter=new NotesAdapter(this,list);
    View dialogView= LayoutInflater.from(this).inflate(R.layout.dialog_main,null,false);
    final EditText title=dialogView.findViewById(R.id.t);
    final EditText description=dialogView.findViewById(R.id.d);
    final AlertDialog alertDialog=new AlertDialog.Builder(this)
            .setTitle("Enter the details:")
            .setCancelable(false)
            .setView(dialogView)
            .setPositiveButton("add", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    list.add(new Notes(title.getText().toString(),description.getText().toString(),false));
                    notesAdapter.notifyItemChanged(list.size());
                }
            })
            .setNegativeButton("no", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            }).create();


    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override // on pressing the fab we will get an alert dialog box where we can add title and description and with the option to add it or not 
        public void onClick(View view) {
            alertDialog.show();
        }
    });
    recyclerView.setAdapter(notesAdapter);
    linearLayoutManager=new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
    recyclerView.setLayoutManager(linearLayoutManager);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    final MenuItem searchItem = menu.findItem(R.id.search);
    final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
    searchView.setOnQueryTextListener(this);
    return true;
}``

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.search) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public boolean onQueryTextSubmit(String s) {
    notesAdapter.filter(s);
    return true;
}

@Override
public boolean onQueryTextChange(String s) {
    notesAdapter.filter(s);
    return true;
}

NotesAdapter.java

 public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesHolder> {
    private ArrayList<Notes> arrayList;
    private ArrayList<Notes> arrayListCopy;
    Context c;
    NotesAdapter(Context context,ArrayList<Notes> list){
        this.arrayList=list;
        this.c=context;
         this.arrayListCopy=new ArrayList<>(list);//this is where I store identical list which I get from Adapter
    }
    public class NotesHolder extends RecyclerView.ViewHolder {
        TextView textView;
        public NotesHolder(View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.tv);
        }
    }

    @Override
    public NotesAdapter.NotesHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new NotesHolder(LayoutInflater.from(c).inflate(R.layout.item_row,parent,false));
    }

    @Override
    public void onBindViewHolder(final NotesAdapter.NotesHolder holder, final int position) {
              final Notes currentNote=arrayList.get(position);
        holder.textView.setText(currentNote.getTitle());
        holder.textView.setOnLongClickListener(new View.OnLongClickListener() {
           @Override
           public boolean onLongClick(View view) {
               arrayList.remove(holder.getAdapterPosition());
               notifyItemRemoved(holder.getAdapterPosition());
               return true;
           }
       });
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(c,AnotherActivity.class);
                intent.putExtra("NAME",currentNote.getDescription());
                c.startActivity(intent);
            }
        });
    }

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

     public void filter(String text){//This is my filter function 
        arrayList.clear();
        if(TextUtils.isEmpty(text)){
            arrayList.addAll(arrayListCopy);
        }
        else{
            text=text.toLowerCase();
            for(Notes note:arrayListCopy){
                if(note.getTitle().toLowerCase().contains(text)){
                    arrayList.add(note);
                }
            }
        }
        notifyDataSetChanged();//the data set is still not updated and instead it vanishes
    }
}

一旦我搜索到某些内容,整个列表就会消失,我错过了哪里?我应该如何修改适配器类中的过滤器功能?

3 个答案:

答案 0 :(得分:0)

更改你的getItemCount:

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

答案 1 :(得分:0)

问题是arrayListarrayListCopy是对同一列表的引用。

NotesAdapter(Context context,ArrayList<Notes> list){
    this.arrayList=list;
    this.c=context;
    this.arrayListCopy=list;
}

对其中一个所做的更改将反映在两者中。例如,arrayList.clear()也会清空arrayListCopy列表。

你能做的是这样的事情:

List<Notes> originalList;
NotesAdapter(Context context,ArrayList<Notes> list){
    this.arrayList=list;
    this.c=context;
    this.originalList= new ArrayList<>(list); // create a new List that contains all the elements of `list`.
}

要过滤,请执行以下操作:

public void filter(String text){ 
    arrayList.clear();
    if(text.isEmpty()){
        arrayList.addAll(originalList);
    } else{
        text=text.toLowerCase();
        for(Notes note : originalList){
            if(note.getTitle().toLowerCase().contains(text)){
                arrayList.add(note);
            }
        }
    }
    notifyDataSetChanged();
}

在创建适配器之后,您似乎正在向list内的MainActivity添加项目,这意味着您必须使用其他一些机制来添加新项目,以便{{ 1}}将包含所有项目。类似的东西:

originalList

此处,public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NotesHolder> { public void addItem(Notes item){ originalList.add(item); if(text.isEmpty() || item.getTitle().toLowerCase().contains(text.toLowerCase())){ arrayList.add(item); } } } 只是对传递给text方法的text变量的引用。 从filter创建新项目时,请执行以下操作:

MainActivity

答案 2 :(得分:0)

试试这个:

NotesAdapter(Context context,ArrayList<Notes> list){
    this.arrayList = new ArrayList<>(list.size());
    this.c=context;
     this.arrayListCopy=new ArrayList<>(list);//this is where I store identical list which I get from Adapter
}

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

 public void filter(String text){//This is my filter function 
    arrayList.clear();
    if(text.trim().isEmpty() || text == null){
        arrayList.addAll(arrayListCopy);
    }
    else{
        text=text.toLowerCase();
        for(Notes note:arrayListCopy){
            if(note.getTitle().toLowerCase().contains(text)){
                arrayList.add(note);
            }
        }
    }
    notifyDataSetChanged();//the data set is still not updated and instead it vanishes
}

原始答案:

在这里,您引用相同的变量(即arrayListarrayListCopy)指向同一个变量。相反,在构造函数中初始化arrayList

this.arrayList = new ArrayList<>(arrayListCopy.size());