2016-01-17 303 views
2

我已经使用this解决方案来过滤我的RecyclerView。使用该解决方案,我可以在输入时获得结果。但是,当我清除搜索小部件时,我没有收到完整列表,而是收到空的RecyclerViewRecyclerView过滤器不工作

这就是我的结果。 https://imgur.com/nwyetEd

这是我Adapter

public class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { 

    private LayoutInflater inflater; 
    private ContactViewHolder viewHolder; 
    private ArrayList<Contact> contactsList = new ArrayList<>(); 
    private VolleySingleton volleySingleton; 
    private ImageLoader imageLoader; 
    boolean fromMyContacts; 
    Context context; 

    public ContactsAdapter(Context context, boolean fromMyContacts){ 
     inflater = LayoutInflater.from(context); 
     this.context = context; 
     volleySingleton = VolleySingleton.getsInstance(); 
     imageLoader = volleySingleton.getImageLoader(); 
     this.fromMyContacts = fromMyContacts; 
    } 

    public void setContactsList(ArrayList<Contact> contactsList){ 
     this.contactsList = contactsList; 
     notifyItemRangeChanged(0, contactsList.size()); 
    } 

    @Override 
    public ContactViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = inflater.inflate(R.layout.contact_list, parent, false); 
     viewHolder = new ContactViewHolder(view); 
     return viewHolder; 
    } 

    @Override 
    public void onBindViewHolder(ContactViewHolder holder, int position) { 
     Contact current = contactsList.get(position); 
     viewHolder.name.setText(current.name); 
     viewHolder.phone.setText(current.phone); 
     viewHolder.city.setText(current.location + ", " + current.city); 

     if(fromMyContacts) { 
      if (current.verified) { 
       viewHolder.verified.setImageResource(R.drawable.ic_check_circle); 
      } else { 
       viewHolder.verified.setImageResource(R.drawable.ic_cancel); 
      } 
     } 

     String image_url = current.image_url; 
     if(!image_url.equals("null")){ 
      Picasso.with(context).load(image_url).into(viewHolder.contactIcon); 
     }else{ 
      viewHolder.contactIcon.setImageResource(R.drawable.contact_icon); 
     } 
    } 

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

    public Contact removeItem(int position){ 
     final Contact contacts = contactsList.remove(position); 
     notifyItemRemoved(position); 
     return contacts; 
    } 

    public void addItem(int position, Contact contactList){ 
     contactsList.add(position, contactList); 
     notifyItemInserted(position); 
    } 

    public void moveItem(int fromPosition, int toPosition){ 
     final Contact contacts = contactsList.remove(fromPosition); 
     contactsList.add(toPosition, contacts); 
     notifyItemMoved(fromPosition, toPosition); 
    } 

    public void animateTo(List<Contact> contacts){ 
     applyAndAnimateRemovals(contacts); 
     applyAndAnimateAdditions(contacts); 
     applyAndAnimateMovedItems(contacts); 
    } 

    private void applyAndAnimateRemovals(List<Contact> newModels) { 
     for (int i = contactsList.size() - 1; i >= 0; i--) { 
      final Contact model = contactsList.get(i); 
      if (!newModels.contains(model)) { 
       removeItem(i); 
      } 
     } 
    } 

    private void applyAndAnimateAdditions(List<Contact> newModels) { 
     for (int i = 0, count = newModels.size(); i < count; i++) { 
      final Contact model = newModels.get(i); 
      if (!contactsList.contains(model)) { 
       addItem(i, model); 
      } 
     } 
    } 

    private void applyAndAnimateMovedItems(List<Contact> newModels) { 
     for (int toPosition = newModels.size() - 1; toPosition >= 0; toPosition--) { 
      final Contact model = newModels.get(toPosition); 
      final int fromPosition = contactsList.indexOf(model); 
      if (fromPosition >= 0 && fromPosition != toPosition) { 
       moveItem(fromPosition, toPosition); 
      } 
     } 
    } 
} 

这是我Model

public class Contact { 

    String name; 
    String phone; 
    String city; 
    String location; 
    Boolean verified; 
    String image_url; 

    public Contact(String name, String phone, String city, String location, Boolean verified, String image_url){ 
     this.name = name; 
     this.phone = phone; 
     this.city = city; 
     this.location = location; 
     this.verified = verified; 
     this.image_url = image_url; 
    } 

} 

这是Activity,我用我的过滤器

public class MyContactsActivity extends AppCompatActivity implements View.OnClickListener, SearchView.OnQueryTextListener { 

    private RecyclerView recyclerView; 
    private ContactsAdapter adapter; 
    private NetworkChecker networkChecker; 
    private SessionManager sessionManager; 
    private AppConfig appConfig; 
    private RelativeLayout loading, retry; 
    private Button tryAgain; 
    AlertHelper alertHelper; 
    final ArrayList<Contact> contactArrayList = new ArrayList<>(); 
    String url; 

    DebugHelper debugHelper; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_my_contacts); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     debugHelper = new DebugHelper(); 

     loading = (RelativeLayout) findViewById(R.id.loadingPanel); 
     retry = (RelativeLayout) findViewById(R.id.retry); 
     tryAgain = (Button) findViewById(R.id.tryAgainButton); 

     tryAgain.setOnClickListener(this); 

     alertHelper = new AlertHelper(this); 
     networkChecker = new NetworkChecker(this); 
     sessionManager = new SessionManager(this); 
     appConfig = new AppConfig(); 

     String phone = sessionManager.getLoggedInUserPhone(); 
     url = appConfig.getApiUrlForSpecificContacts(phone); 



     recyclerView = (RecyclerView) findViewById(R.id.contactsView); 
     adapter = new ContactsAdapter(getApplicationContext(), true); 
     recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); 

     sendJsonRequest(url); 
     recyclerView.setAdapter(adapter); 

     recyclerView.addOnItemTouchListener(
       new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() { 
        @Override 
        public void onItemClick(View view, int position) { 
         TextView phone = (TextView) view.findViewById(R.id.contact_phone); 
         TextView name = (TextView) view.findViewById(R.id.contact_name); 
         Intent i = new Intent(getApplicationContext(), ContactProfileActivity.class); 
         i.putExtra("selected_user_phone", phone.getText()); 
         i.putExtra("selected_user_name", name.getText()); 
         startActivity(i); 
        } 
       }) 
     ); 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       startActivity(new Intent(getApplicationContext(), AddContactActivity.class)); 
      } 
     }); 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
    } 

    private void sendJsonRequest(String url) { 
     if (networkChecker.networkAvailable()) { 
      loading.setVisibility(View.VISIBLE); 
      RequestQueue requestQueue = VolleySingleton.getsInstance().getmRequestQueue(); 

      StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        loading.setVisibility(View.GONE); 
        retry.setVisibility(View.GONE); 
        try { 
         JSONObject jsonObject = new JSONObject(response); 
         JSONArray jsonArray = jsonObject.getJSONArray("contact_info"); 

         if(jsonArray != null){ 
          for (int i = 0; i < jsonArray.length(); i++) { 
           JSONObject currentContact = jsonArray.getJSONObject(i); 

           String name = currentContact.getString("name"); 
           String phone = currentContact.getString("phone"); 
           String city = currentContact.getString("city"); 
           String address = currentContact.getString("address"); 
           Boolean verified = currentContact.getBoolean("verified"); 
           String image_url = currentContact.getString("image_url"); 

           Contact contact = new Contact(name, phone, city, address, verified, image_url); 

           contactArrayList.add(contact); 

          } 
          adapter.setContactsList(contactArrayList); 
         } 
         else{ 
          alertHelper.displayDialog("No Contacts Found."); 
         } 
        }catch (Exception e){ 
         retry.setVisibility(View.VISIBLE); 
         tryAgain.setClickable(true); 
         alertHelper.displayDialog(getString(R.string.action_failed_try_again)); 
        } 
       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        loading.setVisibility(View.GONE); 
        retry.setVisibility(View.VISIBLE); 
        tryAgain.setClickable(true); 
        if (error instanceof TimeoutError || error instanceof NoConnectionError) { 
         alertHelper.displayDialog(getString(R.string.connection_failed)); 
        } else { 
         alertHelper.displayDialog(getString(R.string.action_failed_try_again)); 
        } 
       } 
      }); 

      requestQueue.add(stringRequest); 

     } else { 
      retry.setVisibility(View.VISIBLE); 
      tryAgain.setClickable(true); 
     } 
    } 

    @Override 
    public boolean onPrepareOptionsMenu(Menu menu) { 
     return super.onPrepareOptionsMenu(menu); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.contact_list_menu, menu); 
     debugHelper.L("Search Click Vayo"); 
     final MenuItem item = menu.findItem(R.id.action_search); 
     final SearchView searchView = (SearchView) MenuItemCompat.getActionView(item); 
     searchView.setOnQueryTextListener(this); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // Handle action bar item clicks here. The action bar will 
     // automatically handle clicks on the Home/Up button, so long 
     // as you specify a parent activity in AndroidManifest.xml. 
     int id = item.getItemId(); 

     switch (id) { 
      case android.R.id.home: 
       onBackPressed(); 
       return true; 

     } 

     return super.onOptionsItemSelected(item); 
    } 


    @Override 
    public void onClick(View v) { 
     switch (v.getId()){ 
      case R.id.tryAgainButton: 
       sendJsonRequest(url); 
       break; 
     } 
    } 

    @Override 
    public boolean onQueryTextSubmit(String query) { 
     return false; 
    } 

    @Override 
    public boolean onQueryTextChange(String query) { 
     final List<Contact> filteredModelList = filter(contactArrayList, query); 
     adapter.animateTo(filteredModelList); 
     recyclerView.scrollToPosition(0); 
     return true; 
    } 

    private List<Contact> filter(List<Contact> models, String query) { 
     query = query.toLowerCase(); 
     if(query.equals("")) { return contactArrayList; } 
     final List<Contact> filteredModelList = new ArrayList<>(); 
     for (Contact model : models) { 
      final String text = model.name.toLowerCase(); 
      if (text.contains(query)) { 
       filteredModelList.add(model); 
      } 
     } 
     return filteredModelList; 
    } 

谁能帮助我,请?

+0

为什么不会你保留副本全部结果,并使用它时,搜索过滤器是空的? –

+0

@ItzikSamara我添加了使用我的过滤器的地方。请建议我该怎么做。 –

回答

0

假设contactsList是变种的充分接触

private List<Contact> filter(List<Contact> models, String query) { 
    query = query.toLowerCase(); 
    if(query.equals("")) { return contactsList; } 

    final List<Contact> filteredModelList = new ArrayList<>(); 
    for (Contact model : models) { 
     final String text = model.name.toLowerCase(); 
     if (text.contains(query)) { 
      filteredModelList.add(model); 
     } 
    } 
    return filteredModelList; 
} 
+0

这不起作用。 :( –

+0

显示publishResult代码也 –

+0

我的'适配器'是我将结果绑定到视图的地方。我没有任何publishResult代码。 –

0

他这样定义:

public void setModels(List<ExampleModel> models) { 
    mModels = new ArrayList<>(models); 
} 

初始化喜欢他做的方式。

你soultion是:

this.contactsList = new ArrayList<>(contactsList); 
0

您需要从Activity移动你filter()方法您Adapter。在您的适配器上添加一个额外的变量来保存未过滤的数据集的副本。在你的情况下,你需要contactsListcopyOfContactsList变量。

更改适配器的构造函数如下:

public class ContactsAdapter extends RecyclerView.Adapter<ContactViewHolder> { 

    .... 
    private ArrayList<Contact> contactsList = new ArrayList<>(); 
    private ArrayList<Contact> copyOfContactsList = new ArrayList<>(); 
    .... 

    public ContactsAdapter(Context context, ArrayList<Contact> dataSet, boolean fromMyContacts){ 
     ... 
     this.contactsList = dataSet; 
     copyOfContactsList.addAll(dataSet); 
     ... 
    } 

,这是过滤器的方法添加到您的Adapter

public void filter(String text) { 
    if(text.isEmpty()){ 
     contactsList.clear(); 
     contactsList.addAll(copyOfContactsList); 
    } else{ 
     ArrayList<Contact> result = new ArrayList<>(); 
     text = text.toLowerCase(); 
     for(Contact item: copyOfContactsList){ 
      if(item.getName().toLowerCase().contains(text)){ 
       result.add(item); 
      } 
     } 
     contactsList.clear(); 
     contactsList.addAll(result); 
    } 
    notifyDataSetChanged(); 
} 
+0

好的解决方案。我有两个列表,过滤工作正常。但我尝试将项目的适​​配器位置传递给下一个活动,但它无法正常工作。任何想法在这一个:https://stackoverflow.com/questions/46027110/recyclerview-wrong-position-in-filtered-list – AJW