2016-11-23 259 views
7

我需要基於一個EditText我RecyclerView必須過濾列表,以實現搜索功能,同時typngAndroid的 - 實現搜索過濾器的RecyclerView

下面的代碼:

DisplayAdapter.java這是適配器

public class DisplayAdapter extends RecyclerView.Adapter<DisplayAdapter.MyViewHolder>{ 
    private List<DataHolder> displayedList; 
    public class MyViewHolder extends RecyclerView.ViewHolder{ 
     public TextView english_d; 
     public MyViewHolder(View view){ 
       super(view); 
       english_d = (TextView) view.findViewById(R.id.engword); 
     } 
    } 
    public DisplayAdapter(List<DataHolder> displayedList){ 
     this.displayedList = displayedList; 
     } 

    @Override 
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int position) { 
    // create a layout 
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false); 

    return new MyViewHolder(itemView); 
} 
@Override 
public void onBindViewHolder(MyViewHolder holder, int position) { 
    DataHolder content = displayedList.get(position); 
    holder.english_d.setText(content.getEnglish()); 
    } 
@Override 
public int getItemCount() { 
    return displayedList.size(); 
    } 
} 

DataHolder.java

public class DataHolder { 
private String english; 


public DataHolder() { 
} 

public DataHolder(String english, String norse) { 
    this.english = english; 

} 

public String getEnglish() { 
    return english; 
} 

public void setEnglish(String english) { 
    this.english = english; 
    } 

} 

和這裏的,我一起工作的片段:

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View view = inflater.inflate(R.layout.activity_two_fragment, container, false); 

     rv = (RecyclerView) view.findViewById(R.id.list_view_english); 
     rv.setHasFixedSize(true); 

     inputSearch = (EditText) view.findViewById(R.id.inputSearch); 

     rv.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL)); 
     final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); 
     rv.setLayoutManager(layoutManager); 


     DisplayContent(); 


     disp_adapter = new DisplayAdapter(displayedList); 

     rv.setAdapter(disp_adapter); 
    return view; 
} 

回答

32

添加新的功能更新列表

public void updateList(List<DataHolder> list){ 
    displayedList = list; 
    notifyDataSetChanged(); 
} 

添加textWatcher搜索可以說你正在使用EDITTEXT作爲搜索現場

searchField.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 

      // TODO Auto-generated method stub 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 

      // TODO Auto-generated method stub 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 

      // filter your list from your input 
      filter(s.toString()); 
      //you can use runnable postDelayed like 500 ms to delay search text 
     } 
    }); 


void filter(String text){ 
    List<DataHolder> temp = new ArrayList(); 
    for(DataHolder d: displayedList){ 
      //or use .equal(text) with you want equal match 
      //use .toLowerCase() for better matches 
      if(d.getEnglish().contains(text)){ 
       temp.add(d); 
      } 
    } 
    //update recyclerview 
    disp_adapter.updateList(temp); 
} 
+6

'if(d.getEnglish()。equal(text)){ temp.add(d); (d.getEnglish()。contains(text)){ }'change to'if(d.getEnglish()。contains(text))temp.add(d); }' –

+4

感謝兄弟工作正常d.getName()。toLowerCase()。contains(text.toLowerCase())將得到明確結果感謝 – Sam

+1

該方法適用於感謝 –

1

This可以幫助你。它有辦法創建一個帶有SearchView的RecyclerView來過濾RecyclerView的項目。

1

我已經做過這樣的

.xml文件

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

<android.support.design.widget.AppBarLayout 
    android:id="@+id/appBar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    app:elevation="1dp" 
    android:theme="@style/AppTheme.AppBarOverlay" 
    android:layout_marginBottom="@dimen/bottom_margin"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     app:popupTheme="@style/AppTheme.PopupOverlay"/> 

</android.support.design.widget.AppBarLayout> 

<EditText 
    android:id="@+id/etSearch" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:hint="Search" 
    android:imeOptions="actionDone" 
    android:singleLine="true"/> 

<android.support.v7.widget.RecyclerView 
    android:id="@+id/rvCategory" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
</android.support.v7.widget.RecyclerView> 
</LinearLayout> 

.JAVA類文件

package com.example.myapplication; 

import android.content.Context; 
import android.content.Intent; 
import android.database.Cursor; 
import android.database.sqlite.SQLiteDatabase; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.support.v7.widget.CardView; 
import android.support.v7.widget.LinearLayoutManager; 
import android.support.v7.widget.RecyclerView; 
import android.support.v7.widget.Toolbar; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.Filter; 
import android.widget.Filterable; 
import android.widget.ImageView; 
import android.widget.TextView; 

import org.json.JSONObject; 

import java.util.ArrayList; 

public class Home extends AppCompatActivity implements ResultCallBack{ 

SQLiteDatabase db; 

ArrayList<String> alCategorName=new ArrayList<>(); 

RecyclerView rvCategory; 
EditText etSearch; 
Category bookadapter; 
ArrayList<String> alBookInfo; 

String strURL="http://localhost:21246/api/TreasuryBooks?BookId=1"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_home); 

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
    toolbar.setTitleTextColor(getResources().getColor(R.color.white)); 
    setSupportActionBar(toolbar); 

//  AsyncTask_WebAPI asyncTask=new AsyncTask_WebAPI(this,strURL,this); 
//  asyncTask.execute(); 

    etSearch=(EditText)findViewById(R.id.etSearch); 
    etSearch.setText(""); 

    DatabaseAccess da= DatabaseAccess.getInstance(this); 
    db=da.open(); 
    alBookInfo=new ArrayList<String>(); 

    Cursor c = db.rawQuery("select BookName from Books", null); 
    int rows = c.getCount(); 

    c.moveToFirst(); 

    for(int i=0;i<rows;i++) 
    { 
     String strBoookName=c.getString(c.getColumnIndex("BookName")); 
     alBookInfo.add(strBoookName); 
     c.moveToNext(); 
    } 

    c.close(); 
    db.close(); 

    rvCategory=(RecyclerView)findViewById(R.id.rvCategory); 

    //Recycler view adapter 
    bookadapter=new Category(this,alBookInfo); 
    rvCategory.setLayoutManager(new LinearLayoutManager(this)); 
    rvCategory.setAdapter(bookadapter); 

    //text change listner 
    etSearch.addTextChangedListener(new TextWatcher() { 
     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count,    int after) { 

     } 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      bookadapter.getFilter().filter(s.toString()); 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 

     } 
    }); 
} 

@Override 
public void onBackPressed() { 
    Home.this.finish(); 
} 

@Override 
protected void onRestart() { 
    super.onRestart(); 
    etSearch.setText(""); 
} 

@Override 
public void onResultListener(Object object) { 
    JSONObject jsonObject=(JSONObject)object; 
    try { 
     String strId = jsonObject.getString("id"); 
     String strBookId=jsonObject.getString("BookId"); 
     String strBookName=jsonObject.getString("BookName"); 

     db.rawQuery("insert into Books values('"+strId+"','"+strBookId+"','"+strBookName+"'",null); 
    } 
    catch (Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

Recyclerview適配器

//Recycler view adapter Class with filterable interface 

    private class Category extends RecyclerView.Adapter<viewHolder> implements Filterable 
{ 
    ArrayList<String> alBooks=new ArrayList<String>(); 
    Context context; 
    viewHolder holder; 

    public Category() 
    {} 

    public Category(Context context,ArrayList<String> albooks) 
    { 
     this.context=context; 
     this.alBooks=albooks; 
    } 

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

    @Override 
    public viewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

     View v= LayoutInflater.from(parent.getContext()).inflate(R.layout.home_cardview,parent,false); 
     holder=new viewHolder(v); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(viewHolder holder, int position) { 
     holder.tvBookName.setText(alBooks.get(position)); 
    } 

    private Filter fRecords; 

    //return the filter class object 
    @Override 
    public Filter getFilter() { 
     if(fRecords == null) { 
      fRecords=new RecordFilter(); 
     } 
     return fRecords; 
    } 

    //filter class 
    private class RecordFilter extends Filter { 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 

      FilterResults results = new FilterResults(); 

      //Implement filter logic 
    // if edittext is null return the actual list 
      if (constraint == null || constraint.length() == 0) { 
       //No need for filter 
       results.values = alBookInfo; 
       results.count = alBookInfo.size(); 

      } else { 
       //Need Filter 
     // it matches the text entered in the edittext and set the data in adapter list 
       ArrayList<String> fRecords = new ArrayList<String>(); 

       for (String s : alBookInfo) { 
        if (s.toUpperCase().trim().contains(constraint.toString().toUpperCase().trim())) { 
         fRecords.add(s); 
        } 
       } 
       results.values = fRecords; 
       results.count = fRecords.size(); 
      } 
      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint,FilterResults results) { 

     //it set the data from filter to adapter list and refresh the recyclerview adapter 
      alBooks = (ArrayList<String>) results.values; 
      notifyDataSetChanged(); 
      } 
     } 
    } 

    private class viewHolder extends RecyclerView.ViewHolder { 
    CardView cv; 
    TextView tvBookName; 

    viewHolder(final View itemview) { 
     super(itemview); 

     cv = (CardView) itemview.findViewById(R.id.cardview); 
     tvBookName = (TextView) itemview.findViewById(R.id.categoryName); 

     itemview.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Intent intent=new  Intent(Home.this,Act_Fragment_Container.class); 
       intent.putExtra("BookName", tvBookName.getText()); 
       startActivity(intent); 
      } 
     }); 
    } 
    } 

}在同一類

附加再循環視圖適配器,以避免混淆....

+0

請注意,android:singleLine =「true」已棄用,建議使用android:maxLines =「1」。 –