RecyclerView with editTags - android

I am doing one application. In that i need to search the recycler item and once the user selects item from recycler then it should be set as a tag to that edit text. I did this from this https://android-arsenal.com/details/1/3581, but its not working properly. Can any help me how can i achieve the searching the items from recycler view and set it as a edit tag for that selected item.
This is the screen for reference.
I am doing like this
public class ActivityTagFriends extends BaseActivity implements TagsEditText.TagsEditListener, View.OnClickListener {
TextView tv_cancel, tv_title, tv_Done;
RecyclerView rv_TagFriends;
private TagsEditText mTagsEditText;
private List<String> list = new ArrayList<String>();
TagFriendsAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tag_friends);
tv_cancel = (TextView) findViewById(R.id.tvCancel);
tv_cancel.setText("Cancel");
tv_cancel.setTextColor(getResources().getColor(R.color.red));
tv_title = (TextView) findViewById(R.id.tvTitle);
tv_title.setText("Tag Friends");
tv_title.setTextColor(getResources().getColor(R.color.black));
tv_Done = (TextView) findViewById(R.id.tvDone);
tv_Done.setText("Done");
tv_Done.setTextColor(getResources().getColor(R.color.red));
rv_TagFriends= (RecyclerView) findViewById(R.id.rv_TagFriends);
mTagsEditText = (TagsEditText) findViewById(R.id.tagsEditText);
mTagsEditText.setHint("Search");
mTagsEditText.setTagsListener(this);
mTagsEditText.setTagsWithSpacesEnabled(true);
mTagsEditText.setAdapter(new ArrayAdapter<>(this,
R.layout.tag_friends_row, R.id.tv_TagName,list));
mTagsEditText.setThreshold(1);
rv_TagFriends.setHasFixedSize(true);
rv_TagFriends.setLayoutManager(new LinearLayoutManager(this));
countryList(); // in this method, Create a list of items.
// call the adapter with argument list of items and context.
// mAdapter = new TagFriendsAdapter(list,this);
// rv_TagFriends.setAdapter(mAdapter);
addTextListener();
}
// this method is used to create list of items.
public void countryList(){
list.add("Afghanistan");
list.add("Albania");
list.add("Algeria");
list.add("Bangladesh");
list.add("Belarus");
list.add("Canada");
list.add("Cape Verde");
list.add("Central African Republic");
list.add("Denmark");
list.add("Dominican Republic");
list.add("Egypt");
list.add("France");
list.add("Germany");
list.add("Hong Kong");
list.add("India");
list.add("Iceland");
}
public void addTextListener(){
mTagsEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase();
final List<String> filteredList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
final String text = list.get(i).toLowerCase();
if (text.contains(query)) {
filteredList.add(list.get(i));
}
}
rv_TagFriends.setLayoutManager(new LinearLayoutManager(ActivityTagFriends.this));
mAdapter = new TagFriendsAdapter(filteredList, ActivityTagFriends.this);
rv_TagFriends.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
// data set changed
}
});
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
// mTagsEditText.showDropDown();
// data set changed
}
}
#Override
public void onClick(View v) {
}
#Override
public void onTagsChanged(Collection<String> tags) {
}
#Override
public void onEditingFinished() {
}
}
Thanks in advance.

Okay I got your problem use this code
Your activity layout(activity_main.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:TagsEditText="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"
tools:context="mabbas007.myapplication.MainActivity">
<mabbas007.tagsedittext.TagsEditText
android:id="#+id/tagsEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
TagsEditText:allowSpaceInTag="true"
TagsEditText:tagsBackground="#drawable/square_default"
TagsEditText:tagsCloseImageRight="#drawable/tag_close" />
<TextView
android:background="#android:color/darker_gray"
android:padding="10dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Suggestion"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
adapter layout(adapter_item.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:padding="10dp"
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<View
android:layout_width="match_parent"
android:background="#color/colorAccent"
android:layout_height="1dp"/>
</LinearLayout>
Activity code
public class MainActivity extends AppCompatActivity
implements TagsEditText.TagsEditListener {
RecyclerView rv_TagFriends;
private TagsEditText mTagsEditText;
private List<String> list = new ArrayList<String>();
TagFriendsAdapter mAdapter;
ArrayList<String > tags;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tags=new ArrayList<>();
rv_TagFriends= (RecyclerView) findViewById(R.id.rv);
mTagsEditText = (TagsEditText) findViewById(R.id.tagsEditText);
mTagsEditText.setHint("Search");
mTagsEditText.setTagsListener(this);
mTagsEditText.setTagsWithSpacesEnabled(true);
//mTagsEditText.setAdapter(mAdapter);
mTagsEditText.setThreshold(1);
rv_TagFriends.setHasFixedSize(true);
rv_TagFriends.setLayoutManager(new LinearLayoutManager(this));
countryList(); // in this method, Create a list of items.
// call the adapter with argument list of items and context.
// mAdapter = new TagFriendsAdapter(list,this);
// rv_TagFriends.setAdapter(mAdapter);
addTextListener();
}
// this method is used to create list of items.
public void countryList(){
list.add("Afghanistan");
list.add("Albania");
list.add("Algeria");
list.add("Bangladesh");
list.add("Belarus");
list.add("Canada");
list.add("Cape Verde");
list.add("Central African Republic");
list.add("Denmark");
list.add("Dominican Republic");
list.add("Egypt");
list.add("France");
list.add("Germany");
list.add("Hong Kong");
list.add("India");
list.add("Iceland");
}
public void addTextListener(){
mTagsEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase().trim();
if (query.toString().equals(""))
return;
if (tags.size()!=0)
query=query.toString().substring(query.toString().indexOf(tags.get(tags.size()-1).toLowerCase())+tags.get(tags.size()-1).toString().length()).trim();
if (query.toString().equals("")){
final List<String> filteredList = new ArrayList<>();
rv_TagFriends.setLayoutManager(new LinearLayoutManager(MainActivity.this));
mAdapter = new TagFriendsAdapter(filteredList, MainActivity.this);
rv_TagFriends.setAdapter(mAdapter);
}else {
final List<String> filteredList = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
final String text = list.get(i).toLowerCase();
if (text.contains(query)) {
filteredList.add(list.get(i));
}
}
rv_TagFriends.setLayoutManager(new LinearLayoutManager(MainActivity.this));
mAdapter = new TagFriendsAdapter(filteredList, MainActivity.this);
rv_TagFriends.setAdapter(mAdapter);
}
}
});
}
#Override
public void onTagsChanged(Collection<String> tags) {
}
#Override
public void onEditingFinished() {
}
public class TagFriendsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private List<String > data;
private MainActivity mainActivity;
public TagFriendsAdapter(List<String> data , MainActivity mainActivity) {
this.data = data;
this.mainActivity=mainActivity;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_item, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
((MyViewHolder)holder).text.setText(data.get(position)+"");
((MyViewHolder)holder).text.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mainActivity.add(data.get(position)+"");
}
});
}
#Override
public int getItemCount() {
return data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView text;
public MyViewHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(R.id.text);
}
}
}
public void add(String s){
for (int i = 0; i < tags.size(); i++) {
if (s.equals(tags.get(i)))
return;
}
tags.add(s);
String [] tag=tags.toArray(new String [0]);
mTagsEditText.setTags(tag);
}
}

Related

Implementing Search filter Causing problem when pressed backspace

I am trying to implement a search filter on complex object data in recyclerview when I type in the Edit text first-time it works properly, but whenever I try to delete characters by pressing back-space in order to modify our search- I am repeatedly failing in this regard.
I can only search once !!
etSearch = (EditText) findViewById(R.id.edittext);
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) {
myAdapter.filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});
now the filter code
public void filter(CharSequence sequence) {
ArrayList<user> temp = new ArrayList<>();
if (!TextUtils.isEmpty(sequence)) {
for (user s : arr) {
Log.d("users ",s.getName());
if (s.getName().toLowerCase().contains(sequence)) {
temp.add(s);
}
}
} else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
notifyDataSetChanged();
temp.clear();
}
Whats the issue, I cannot search more than once-any help is appreciated
Here is my Adapter class
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
{
Context cxt;
ArrayList<user> arr;
ArrayList<user> arrcopy;
DatabaseReference dref;
MyAdapter myAdapter;
public MyAdapter(Context context, ArrayList<user> arrayList)
{
cxt = context;
arr = arrayList;
arrcopy=new ArrayList<>(arr);
Log.d("Very start arr",arr.toString());
notifyDataSetChanged();
dref = FirebaseDatabase.getInstance().getReference("users");
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(cxt).inflate(R.layout.item_chatroom,viewGroup,false);
myAdapter = new MyAdapter(cxt, arr);
Log.d("Inside MyHolder arr",arr.toString());
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final MyHolder myHolder,final int i) {
final String name = arr.get(i).getUsername();
String pic=arr.get(i).getPic();
final String mail=arr.get(i).getEmail();
myHolder.name.setText(name);
Glide.with(myHolder.profile.getContext())
.load(pic)
.into(myHolder.profile);
myHolder.name.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(cxt,MainActivity.class);
intent.putExtra("Id",arr.get(i).getId());
intent.putExtra("Name",arr.get(i).getUsername());
cxt.startActivity(intent);
}
});
myHolder.info.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final SweetAlertDialog pDialog = new SweetAlertDialog(cxt, SweetAlertDialog.SUCCESS_TYPE);
pDialog.setTitleText("User Information e-mail ID");
pDialog.setContentText("Name: "+name+"\n\n E-mail: "+mail);
pDialog.setConfirmText("Ok");
pDialog.show();
}
});
}
#Override
public int getItemCount() {
return arr.size();
}
class MyHolder extends RecyclerView.ViewHolder
{
TextView name;
ImageView profile,info;
public MyHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.txv);
profile=itemView.findViewById(R.id.profile);
info=itemView.findViewById(R.id.profileinfo);
}
}
public void filter(CharSequence sequence) {
ArrayList<user> temp = new ArrayList<>();
if (!TextUtils.isEmpty(sequence)) {
for (user s : arr) {
if (s.getName().toLowerCase().contains(sequence)) {
temp.add(s);
}
}
} else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
notifyDataSetChanged();
temp.clear();
}
}
I assume the arrcopy is the copy of arr like:
ArrayList<User> arrcopy = new ArrayList<>(arr);
If you modify arr, it also change the content of arrcopy. And when no result matches, the arr is empty, so is the arrcopy.
else {
temp.addAll(arrcopy);
}
arr.clear();
arr.addAll(temp);
Now temp is empty, the arr data you set for adapter is empty, so issues happens.
Please try:
In MyAdapter:
Context cxt;
ArrayList<user> arr;
public MyAdapter(Context context) {
cxt = context;
dref = FirebaseDatabase.getInstance().getReference("users");
}
public void setData(ArrayList<User> arrayList) {
arr = arrayList;
notifyDataSetChanged();
}
Also put the filter() in your activity/fragment:
protected void onCreate(final Bundle savedInstanceState) {
etSearch = (EditText) findViewById(R.id.edittext);
etSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
etSearch.requestFocus();
}
});
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) {
filter(etSearch.getText().toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
etSearch.clearFocus();
mAdapter = new MyAdapter(this);
mAdapter.setData(arrayList);
mRecyclerView.setAdapter(mAdapter);
...
}
public void filter(String input) {
if (!TextUtils.isEmpty(input)) {
ArrayList<User> temp = new ArrayList<>();
for (user s : arr) {
if (s.getName().toLowerCase().contains(input)) {
temp.add(s);
}
}
mAdapter.setData(temp);
} else {
mAdapter.setData(arr);
}
mAdapter.notifyDataSetChanged();
}
Implement Filterable in your MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyHolder>
implements Filterable {
// change MyObject to user class
//replace myObjects with arr and reservedList with arrcopy
Context cxt;
ArrayList<MyObject> myObjects;
ArrayList<MyObject> reservedList;
DatabaseReference dref;
public MyAdapter(Context context, ArrayList<MyObject> arrayList){
cxt = context;
myObjects = arrayList;
reservedList = arrayList
Log.d("Very start arr",myObjects.toString());
// notifyDataSetChanged();
dref = FirebaseDatabase.getInstance().getReference("users");
}
//...
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString().toLowerCase();
if (!charString.isEmpty()) {
List<MyObject> filteredList = new ArrayList<>();
for (MyObject row : reservedList) {
if (row.getName().toLowerCase().contains(charString)){
filteredList.add(row);
}
}
myObjects = filteredList;
} else {
myObjects = reservedList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = myObjects;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
myObjects = (ArrayList<MyObject>) filterResults.values;
notifyDataSetChanged();
}
};
}
and from your activity
etSearch = (EditText) findViewById(R.id.edittext);
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) {
myAdapter.getFilter().filter(s);
}
#Override
public void afterTextChanged(Editable s) {
}
});

How to access data in RecyclerView from a Fragment?

I know, this question asked many times but I am totally lost after reading some answers. I am new to Android development. I have created a Fragment and initialized and set the adapter from that fragment
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(ConfigDataloggerViewModel.class);
dataLoggerList = getResources().getStringArray(R.array.DataLoggerStringArray);
// TODO: Use the ViewModel
//for (int j=0; j< dataLoggerList.length; j++){ DummyArrayList.add(dataLoggerList[j]);}
RecyclerView recyclerView = getView().findViewById(R.id.config_datalogger_recycle_view);
ConfigDataloggerAdapter configDataloggerAdapter = new ConfigDataloggerAdapter(dataLoggerList, getActivity());
recyclerView.setAdapter(configDataloggerAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
I have list of EditText in my fragment and I am setting those EditText in the adapter and I am also saving the values from EditTexts into an Array which is defined in Adapter itself.
public class ConfigDataloggerAdapter extends RecyclerView.Adapter<ConfigDataloggerAdapter.ViewHolder>{
//private ArrayList<RFIDReader> readers = new ArrayList<>();
private String [] mDummyList ;
// private ArrayList<String> mDummyArrayList = new ArrayList<>();
public String [] mDummyArrayList;
//public ArrayList<String> mConfigDataloggerData ;
public String[] mConfigDataloggerData;
// private ConfigDataloggerViewModel mConfigDataModel;
public Map<String, String> tempDataModel = new HashMap<>();
private Context mContext;
public ConfigDataloggerAdapter( String [] mDummyArrayList, Context mContext) {
this.mDummyArrayList = mDummyArrayList;
this.mContext = mContext;
mConfigDataloggerData = new String[mDummyArrayList.length];
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.config_datalogger_list,viewGroup,false);
ConfigDataloggerAdapter.ViewHolder holder = new ConfigDataloggerAdapter.ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull ConfigDataloggerAdapter.ViewHolder holder, int i) {
String [] mConfigDataloggerText = null;
// for (int j=0; j< mDummyList.length; j++){ mDummyArrayList.add(mDummyList[j]);}
//ReaderDevice readerDevice = mDummyArrayList.get(i);
String temp = mDummyArrayList[i];
holder.mConfigDataloggerListText.setText(temp);
// tempDataModel.put(temp,mConfigDataloggerData.get(i) );
// mConfigDataModel.setConfigDataloggerVMData(tempDataModel);
//holder.reader_checkedTextView.setText(readerDevice.getName() );
}
#Override
public int getItemCount() {
return mDummyArrayList.length;
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView mConfigDataloggerListText;
public EditText mConfigDataloggarListEditText;
public LinearLayout configDataloggerLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mConfigDataloggerListText = itemView.findViewById(R.id.textView_config_datalogger);
mConfigDataloggarListEditText = itemView.findViewById(R.id.editText_config_datalogger);
mConfigDataloggarListEditText.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) {
mConfigDataloggerData[getAdapterPosition()] =
mConfigDataloggarListEditText.getText().toString();
//here I am storing data from editText to the array
}
#Override
public void afterTextChanged(Editable s) {
}
});
configDataloggerLayout = itemView.findViewById(R.id.config_datalogger_list_layout);
}
}
}
I have two questions, 1) how to access mConfigDataloggerData from adapter in the Fragment? 2) I have a button in same fragment. when I press the button, other fragment starts. Now, I want to save data from mConfigDataloggerData to ViewModel when press the button. So where exactly I write mViewModel = ViewModelProviders.of(this).get(xxxx.class); ?
For your reference, below code is of an activity where my Fragments are attached.
public class defaultActivity extends AppCompatActivity {
private String TAG = "default activity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datalogger_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ConfigDataloggerFragment configDataloggerFragment = new ConfigDataloggerFragment();
// getSupportFragmentManager().beginTransaction().add(R.id.default_datalogger_activity, datalogger).commit();
getSupportFragmentManager().beginTransaction().add(R.id.default_datalogger_activity, configDataloggerFragment).commit();
}
public void StartorStopInventory(View view) {
Button button = (Button) view;
if (application.mConnectedReader.isConnected()){
if (application.mIsInventoryRunning ){
application.mIsInventoryRunning = true;
button.setText("STOP");
try{
TriggerInfo triggerInfo = new TriggerInfo();
Log.d(TAG, "Start trigger setting when button is pressed" + triggerInfo.StartTrigger.getTriggerType());
Log.d(TAG, "Stop trigger setting when button is pressed" + triggerInfo.StartTrigger.getTriggerType());
application.mConnectedReader.Actions.Inventory.perform();
}catch (InvalidUsageException e){
Log.d(TAG, "StartorStopInventory: Inventory perform fail " + e);
} catch (final OperationFailureException op) {
op.printStackTrace();
Log.d(TAG, "StartorStopInventory: Operational failure " + op.getResults() + " " + op.getVendorMessage());
Toast.makeText(view.getContext(), op.getVendorMessage(), Toast.LENGTH_LONG);
}
}
}
}
public void start_data_logging_click(View view) {
Datalogger datalogger = new Datalogger();
// getSupportFragmentManager().beginTransaction().replace(R.id.default_datalogger_activity, datalogger);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.default_datalogger_activity, datalogger);
transaction.addToBackStack(null);
transaction.commit();
}
}
1) Create getters in Adapter for your fields, ex
public String[] getConfigDataloggerData(){
return mConfigDataloggerData;
}
...
To declare adapter globally;
public class YourFragment {
ConfigDataloggerAdapter configDataloggerAdapter,
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(this).get(ConfigDataloggerViewModel.class);
dataLoggerList = getResources().getStringArray(R.array.DataLoggerStringArray);
// TODO: Use the ViewModel
//for (int j=0; j< dataLoggerList.length; j++){ DummyArrayList.add(dataLoggerList[j]);}
RecyclerView recyclerView = getView().findViewById(R.id.config_datalogger_recycle_view);
configDataloggerAdapter = new ConfigDataloggerAdapter(dataLoggerList, getActivity());
recyclerView.setAdapter(configDataloggerAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
}
Then inside your Fragment, call configDataloggerAdapter.getConfigDataloggerData() and you will get your data. Same for other fields
2) I dont yet understand that part

Search in RecyclerView with EditText

I write this code for search in recyclerview with edit text but, when I run the application and input a text that I need to search about it on the edit text in the first letter the recycler content not changed and when I input the second Letter the RecyclerView become empty.
how can I filter the recycler? what is the wrong in my code ?
xml code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".FamilyActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<EditText
android:id="#+id/search"
android:layout_width="294dp"
android:layout_height="70dp"
android:layout_marginTop="-20dp"
android:hint="Search ..."
android:drawableLeft="#drawable/ic_search_black_24dp"
/>
<Button
android:id="#+id/add"
android:layout_width="54dp"
android:layout_height="match_parent"
android:layout_marginLeft="35dp"
android:drawableTop="#drawable/ic_person_add_black_24dp"
android:onClick="add_new_family"
tools:ignore="OnClick" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="50dp"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
code in main activity:
public class FamilyActivity extends AppCompatActivity {
RecyclerView recyclerView;
FamilyAdapter familyAdapter;
Button add_family;
EditText search;
List<Family> familyList;
String patientID = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_family);
add_family=(Button)findViewById(R.id.add);
search =(EditText)findViewById(R.id.search);
familyList = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Bundle extras = getIntent().getExtras();
if (extras != null) {
patientID = extras.getString("ID");
}
loadFamilyList();
//adding some items to our list
//creating recyclerView adapter
FamilyAdapter adapter = new FamilyAdapter(this, familyList);
//setting adapter to recyclerView
recyclerView.setAdapter(adapter);
addTextListener();
}
public void addTextListener(){
search.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase();
final List<Family> filteredList = new ArrayList<>();
for (int i = 0; i < familyList.size(); i++) {
final String text = familyList.get(i).toString().toLowerCase();
if (text.contains(query)) {
filteredList.add(familyList.get(i));
}
}
recyclerView.setLayoutManager(new LinearLayoutManager(FamilyActivity.this));
FamilyAdapter fadapter = new FamilyAdapter(FamilyActivity.this,filteredList);
recyclerView.setAdapter(fadapter);
fadapter.notifyDataSetChanged(); // data set changed
}
});
}
code in adapter:
public class FamilyAdapter extends RecyclerView.Adapter<FamilyAdapter.FamilyViewHolder> {
private Context context;
private List<Family> familyList;
private List<Family> familyListFull;
public FamilyAdapter(Context context, List<Family> familyList) {
this.context = context;
this.familyList = familyList;
familyListFull=new ArrayList<>(familyList);
}
#NonNull
#Override
public FamilyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.list_layout, null);
return new FamilyViewHolder(view);
}
#Override
public void onBindViewHolder(FamilyViewHolder familyViewHolder, final int position) {
Family family = familyList.get(position);
familyViewHolder.textViewTitle.setText(family.getName());
familyViewHolder.familyLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: clicked on : " + familyList.get(position));
String name = familyList.get(position).getName();
String num = familyList.get(position).getNum();
Intent intent = new Intent(context, Chatting.class);
intent.putExtra("num", num);
intent.putExtra("name", name);
context.startActivity(intent);
}
});
familyViewHolder.deleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context );
builder.setTitle("Delete");
builder.setMessage("Are you sure you want to delete this one ")
.setPositiveButton("YES", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
RemoveFamilyMember(position);
}
}).setNegativeButton("NO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
builder.setCancelable(true);
}
});
AlertDialog alert=builder.create();
alert.show();
}
});
}
you can try something like this I think this might work, I haven't tested it but I think that making a new adapter everytime that the edittext has something in it is a bad idea. and if you get to the point back to where the query is equal to "" empty string then you should make the fileterd list back into the whole list which I didn't put in there
public class FamilyActivity extends AppCompatActivity {
RecyclerView recyclerView;
FamilyAdapter familyAdapter;
Button add_family;
EditText search;
List<Family> familyList;
List<Family> filteredList;
String patientID = "";
FamilyAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_family);
add_family=(Button)findViewById(R.id.add);
search =(EditText)findViewById(R.id.search);
familyList = new ArrayList<>();
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
Bundle extras = getIntent().getExtras();
if (extras != null) {
patientID = extras.getString("ID");
}
loadFamilyList();
filteredList = new ArrayList<>(familyList);
//adding some items to our list
//creating recyclerView adapter
adapter = new FamilyAdapter(this, filteredList);
//setting adapter to recyclerView
recyclerView.setAdapter(adapter);
addTextListener();
}
public void addTextListener(){
search.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence query, int start, int before, int count) {
query = query.toString().toLowerCase();
filteredList = new ArrayList<>();
for (int i = 0; i < familyList.size(); i++) {
final String text = familyList.get(i).toString().toLowerCase();
if (text.contains(query)) {
filteredList.add(familyList.get(i));
}
}
recyclerView.removeAllViews();;
adapter.notifyDataSetChanged(); // data set changed
}
});
}
editTextSearch.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) {
}
#Override
public void afterTextChanged(Editable s) {
filter(s.toString());
}
});
private void filter(String text) {
ArrayList<Model> newList = new ArrayList<>();
for (Model item : mModelList) {
if (item.getTitle().contains(text)){
newList.add(item);
}
}
yourAdapter.setFilter(newList);
}

Pass arraylists from fragment to root activity

I am building a order receiving app for waiter in which half page is activity layout which contains listview and half is viewpager which contains json arraylist in fragment. I want to add the menu data from fragment when clicked on + button with number of quantity to be add on root activity's listview
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/My_Container_1_ID"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="140dp"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/app_name"
app:layout_collapseMode="parallax"
android:background="#mipmap/bgactionbar">
<ImageView
android:id="#+id/logo"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="30dp"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:background="#mipmap/logoapp"
/>
<ImageView
android:id="#+id/triangle"
android:layout_width="280dp"
android:layout_height="100dp"
android:layout_toRightOf="#+id/logo"
android:background="#mipmap/caley"
/>
<RelativeLayout
android:id="#+id/searchLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="#+id/triangle"
android:background="#F3EEE8"
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:src="#android:drawable/ic_menu_search"
android:layout_toRightOf="#+id/search_menu"
/>
<EditText
android:id="#+id/search_menu"
android:layout_width="350dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:hint="Search Menu..."
android:textColorHint="#color/tab_text"
android:textColor="#color/tab_text"
android:background="#android:color/transparent"
android:layout_alignParentLeft="true"
android:inputType="textVisiblePassword"/>
</RelativeLayout>
<ImageView
android:id="#+id/coffee"
android:layout_width="110dp"
android:layout_height="140dp"
android:layout_toRightOf="#+id/searchLayout"
android:background="#mipmap/coffee"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
style="#style/MyCustomTabLayout"
android:background="#mipmap/background"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
</FrameLayout>
<RelativeLayout
android:id="#+id/content"
android:layout_width="360dp"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:background="#mipmap/background"
android:layout_below="#id/My_Container_1_ID">
<TextView
android:id="#+id/txtorder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:text="Order"
android:textStyle="bold"
android:textColor="#color/tab_text"
android:textSize="20sp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/orderlist"
android:layout_width="340dp"
android:layout_height="match_parent"
android:layout_above="#+id/submit_order"
android:layout_below="#+id/txtorder"
android:background="#mipmap/background"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
<Button
android:id="#+id/submit_order"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="#+id/orderlist"
android:layout_alignParentBottom="true"
android:layout_alignRight="#+id/orderlist"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:background="#EE6426"
android:textColor="#android:color/white"
android:text="Submit" />
</RelativeLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentRight="true"
android:layout_below="#+id/My_Container_1_ID"
android:layout_toRightOf="#+id/content"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
public class Menu extends AppCompatActivity implements Coffee.OnMenuInteractionListener {
// private ArrayList<MenuDataModel> allOrders;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
ListView listView;
RecyclerView recyclerView;
RecyclerAdapter adapter;
// MenuTabAdapter adapter;
// ArrayList<MenuDataModel> allOrders;
private List<MenuDataModel> allOrders = new ArrayList<MenuDataModel>();
// private List<String> orderList = new ArrayList<>();
private String Quantity, Name;
EditText count, inputSearch;
TextView order;
String searchValue;
private ArrayList<String> stringArrayList;
CollapsingToolbarLayout collapsingToolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
collapsingToolbar= (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
// collapsingToolbar.setTitle(getString(R.string.app_name));
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
// listView = (ListView) findViewById(R.id.orderlist);
// adapter = new MenuTabAdapter(this, allOrders);
// listView.setAdapter(adapter);
TextView orddd = (TextView) findViewById(R.id.txtorder);
inputSearch = (EditText) findViewById(R.id.search_menu);
// inputSearch.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View v) {
//
// collapsingToolbar.setVisibility(View.GONE);
//
// }
// });
// recyclerView = (RecyclerView) findViewById(R.id.orderlist);
// recyclerView.setHasFixedSize(true);
// LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// recyclerView.setLayoutManager(layoutManager);
//
// adapter = new RecyclerAdapter(this, allOrders);
// recyclerView.setAdapter(adapter);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new Coffee(), "Coffee");
adapter.addFragment(new Coffee(), "BreakFast");
adapter.addFragment(new Coffee(), "Beverage");
viewPager.setAdapter(adapter);
}
#Override
public void onFragmentSetOrders(ArrayList<MenuDataModel> menuList) {
allOrders = menuList;
}
#Override
public void onMenuListItemClick(int position) {
//musicService.setSong(position);
MenuDataModel menuorder = allOrders.get(position);
// menuorder.setName(menuorder.getName());
// menuorder.setName(allOrders);
allOrders.add(menuorder);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
public class Coffee extends Fragment {
ListView listView;
MenusAdapter adapter;
// Movies json url
private static final String url = "url";
private ProgressDialog pDialog;
private List<MenuDataModel> menuList = new ArrayList<MenuDataModel>();
OnMenuInteractionListener menuItemClick;
private String searchData;
private EditText inputSearch;
// Activity activity;
//OnMenuInteractionListener mCallback;
public Coffee() {
// Required empty public constructor
}
public interface OnMenuInteractionListener {
public void onFragmentSetOrders(ArrayList<MenuDataModel> menuList);
public void onMenuListItemClick(int position);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
menuItemClick = (OnMenuInteractionListener) getActivity();
}
#Override
public void onDetach() {
super.onDetach();
menuItemClick = null;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// searchData = getArguments().getString("search");
inputSearch = (EditText) getActivity().findViewById(R.id.search_menu);
inputSearch.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// When user changed the Text
//adapter.getFilter().filter(cs.toString());
if (count < before) {
// We're deleting char so we need to reset the adapter data
adapter.resetData();
}
Coffee.this.adapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
View view = inflater.inflate(R.layout.fragment_coffee, container, false);
listView = (ListView) view.findViewById(R.id.list);
adapter = new MenusAdapter(getActivity(), menuList);
listView.setAdapter(adapter);
pDialog = new ProgressDialog(getActivity());
// Showing progress dialog before making http request
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
showpDialog();
// Creating volley request obj
JsonObjectRequest bookingReq = new JsonObjectRequest(Request.Method.GET, "" + url + "?", null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("bsd", response.toString());
// Parsing json
try {
JSONArray menu = response.getJSONArray("menus");
int length = menu.length();
for (int i = 0; i < menu.length(); i++) {
JSONObject obj = menu.getJSONObject(i);
MenuDataModel dm = new MenuDataModel();
// Log.d("vdata", String.valueOf(menu.length()));
dm.setID(obj.getString("id"));
dm.setName(obj.getString("name"));
dm.setThumbnailUrl(obj.getString("photo"));
Log.d("image", String.valueOf(obj.getString("photo")));
dm.setDescription(obj.getString("description"));
dm.setRate(obj.getString("price"));
dm.setStatus(obj.getString("status"));
// adding movie to movies array
menuList.add(dm);
// Log.d("nth", String.valueOf(i));
}
} catch (JSONException e) {
e.printStackTrace();
}
hidepDialog();
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#SuppressWarnings("deprecation")
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("b", "Error: " + error.getMessage());
hidepDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(bookingReq);
return view;
}
private void showpDialog() {
if (!pDialog.isShowing())
pDialog.setMessage("Please wait...");
pDialog.show();
}
private void hidepDialog() {
if (pDialog != null) {
pDialog.dismiss();
pDialog = null;
}
}
}
public class MenusAdapter extends BaseAdapter implements Filterable {
private static final String TAG = MenusAdapter.class.getSimpleName();
List<MenuDataModel> MenuItems;
List<MenuDataModel> mSearchValues;
private android.widget.Filter menufilter;
Coffee.OnMenuInteractionListener mCallback;
//private Activity activity;
ImageLoader imageLoader = AppController.getInstance().getImageLoader();
public MenusAdapter(Activity activity, List<MenuDataModel> MenuItems) {
//this.activity = activity;
this.MenuItems = MenuItems;
this.mSearchValues = MenuItems;
}
#Override
public int getCount() {
return MenuItems.size(); // total number of elements in the list
}
#Override
public Object getItem(int i) {
return MenuItems.get(i); // single item in the list
}
#Override
public long getItemId(int i) {
return i; // index number
}
#Override
public View getView(final int index, View view, final ViewGroup parent) {
if (view == null) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
view = inflater.inflate(R.layout.menu_item, parent, false);
}
// if (imageLoader == null)
// imageLoader = AppController.getInstance().getImageLoader();
final ImageView increase = (ImageView) view.findViewById(R.id.icon_increase);
ImageView decrease = (ImageView) view.findViewById(R.id.icon_decrease);
final EditText count = (EditText) view.findViewById(R.id.count_menu);
NetworkImageView thumbnailUrl = (NetworkImageView) view.findViewById(R.id.menu_image);
TextView name = (TextView) view.findViewById(R.id.menu_items);
// TextView description = (TextView) view.findViewById(R.id.description);
// TextView rate = (TextView) view.findViewById(R.id.price);
final MenuDataModel data = MenuItems.get(index);
name.setText(String.valueOf(data.getName()));
thumbnailUrl.setImageUrl(data.getThumbnailUrl(), imageLoader);
thumbnailUrl.setDefaultImageResId(R.mipmap.logoapp);
thumbnailUrl.setErrorImageResId(R.mipmap.logoapp);
// description.setText(String.valueOf(data.getDescription()));
// title.setText(data.getTitle());
// rate.setText(String.valueOf(data.getRate()));
// final double dis = Double.valueOf(data.getRate());
final int[] quantity = {MenuItems.get(index).getAnInt()};
increase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Toast.makeText(parent.getContext(), "Button Clicked"+ dataModel.getName(),Toast.LENGTH_LONG).show();
//Intent yes= new Intent(parent.getContext(), yes(dataModel.getName().class));
quantity[0]++;
count.setText(quantity[0] + "");
count.setTag(quantity[0] + "");
// mCallback.onFragmentSetOrders(all);
mCallback.onMenuListItemClick(MenuItems.get(index).getAnInt());
// Coffee.OnMenuInteractionListener listener = (Coffee.OnMenuInteractionListener) activit;
// mCallback.onFragmentSetOrders(menu);
// Bundle bundle = new Bundle();
// bundle.putString("quantity", quantity[0] + "");
// bundle.putString("name", String.valueOf(data.getName()));
// q.putExtra("bookingid", dataModel.getbkid());
// parent.getContext().startActivity(q);
}
});
decrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
count.getTag();
count.setTag(quantity[0] + "");
quantity[0]--;
count.setText(quantity[0] + "");
}
});
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
});
return view;
}
#Override
public Filter getFilter() {
if (menufilter == null)
menufilter = new MenuFilter();
return menufilter;
}
public void resetData() {
MenuItems = mSearchValues;
}
private class MenuFilter extends android.widget.Filter {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
results.values = mSearchValues;
results.count = mSearchValues.size();
} else {
// We perform filtering operation
List<MenuDataModel> nDriverList = new ArrayList<MenuDataModel>();
for (MenuDataModel p : MenuItems) {
if (p.getName().toUpperCase().startsWith(constraint.toString().toUpperCase()))
nDriverList.add(p);
}
results.values = nDriverList;
results.count = nDriverList.size();
}
return results;
}
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// Now we have to inform the adapter about the new list filtered
if (results.count == 0)
notifyDataSetInvalidated();
else {
MenuItems = (List<MenuDataModel>) results.values;
notifyDataSetChanged();
}
}
}
;
}
i am getting null pointer exception on mCallback.onMenuListItemClick(MenuItems.get(index).getAnInt());
Step 1: Create Interface
public interface ActivityCommunicator{
public void passDataToActivity(ArrayList<string> arrayList);
}
Step 2:Initialize interface object in fragment class
private ActivityCommunicator activityCommunicator;;
public void onAttach(Activity activity)
{
super.onAttach(activity);
context = getActivity();
activityCommunicator =(ActivityCommunicator)context;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
init();
}
public void init() {
activityButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
activityCommunicator.passDataToActivity("Your Array List");
}
});
}
step 3: Access Your arraylist from fragment in your activity class.
public class MainActivity extends FragmentActivity implements ActivityCommunicator{
public static ArrayList<String> aList;
#Override
public void passDataToActivity(ArrayList<String> arrayList){
aList = arrayList;
}
}

How can I filter ListView data when typing on EditText in android

I have a ListView and a EditText. How can I filter ListView data when typing on EditText?
Add TextWatcher to EditText#addTextChangedListener
In onTextChanged add or remove items from your ListView's adapter. If you are subclassing ArrayAdapter it would have add and remove methods
Yes you can, just implement this code. Use the following code to implement search and filter list in android:
SearchAndFilterList.java
public class SearchAndFilterList extends Activity {
private ListView mSearchNFilterLv;
private EditText mSearchEdt;
private ArrayList<String> mStringList;
private ValueAdapter valueAdapter;
private TextWatcher mSearchTw;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_and_filter_list);
initUI();
initData();
valueAdapter=new ValueAdapter(mStringList,this);
mSearchNFilterLv.setAdapter(valueAdapter);
mSearchEdt.addTextChangedListener(mSearchTw);
}
private void initData() {
mStringList=new ArrayList<String>();
mStringList.add("one");
mStringList.add("two");
mStringList.add("three");
mStringList.add("four");
mStringList.add("five");
mStringList.add("six");
mStringList.add("seven");
mStringList.add("eight");
mStringList.add("nine");
mStringList.add("ten");
mStringList.add("eleven");
mStringList.add("twelve");
mStringList.add("thirteen");
mStringList.add("fourteen");
mSearchTw=new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
valueAdapter.getFilter().filter(s);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
};
}
private void initUI() {
mSearchNFilterLv=(ListView) findViewById(R.id.list_view);
mSearchEdt=(EditText) findViewById(R.id.txt_search);
}
}
Custom Value adapter:
ValueAdapter.java
public class ValueAdapter extends BaseAdapter implements Filterable{
private ArrayList<String> mStringList;
private ArrayList<String> mStringFilterList;
private LayoutInflater mInflater;
private ValueFilter valueFilter;
public ValueAdapter(ArrayList<String> mStringList,Context context) {
this.mStringList=mStringList;
this.mStringFilterList=mStringList;
mInflater=LayoutInflater.from(context);
getFilter();
}
//How many items are in the data set represented by this Adapter.
#Override
public int getCount() {
return mStringList.size();
}
//Get the data item associated with the specified position in the data set.
#Override
public Object getItem(int position) {
return mStringList.get(position);
}
//Get the row id associated with the specified position in the list.
#Override
public long getItemId(int position) {
return position;
}
//Get a View that displays the data at the specified position in the data set.
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder viewHolder;
if(convertView==null) {
viewHolder=new Holder();
convertView=mInflater.inflate(R.layout.list_item,null);
viewHolder.nameTv=(TextView)convertView.findViewById(R.id.txt_listitem);
convertView.setTag(viewHolder);
}else{
viewHolder=(Holder)convertView.getTag();
}
viewHolder.nameTv.setText(mStringList.get(position).toString());
return convertView;
}
private class Holder{
TextView nameTv;
}
//Returns a filter that can be used to constrain data with a filtering pattern.
#Override
public Filter getFilter() {
if(valueFilter==null) {
valueFilter=new ValueFilter();
}
return valueFilter;
}
private class ValueFilter extends Filter {
//Invoked in a worker thread to filter the data according to the constraint.
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results=new FilterResults();
if(constraint!=null && constraint.length()>0){
ArrayList<String> filterList=new ArrayList<String>();
for(int i=0;i<mStringFilterList.size();i++){
if(mStringFilterList.get(i).contains(constraint)) {
filterList.add(mStringFilterList.get(i));
}
}
results.count=filterList.size();
results.values=filterList;
}else{
results.count=mStringFilterList.size();
results.values=mStringFilterList;
}
return results;
}
//Invoked in the UI thread to publish the filtering results in the user interface.
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
mStringList=(ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
activity_search_and_filter_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="#+id/txt_search"
tools:context=".SearchAndFilterList"
android:hint="Enter text to search" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/list_view"
android:layout_below="#+id/txt_search"></ListView>
</RelativeLayout>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/txt_listitem"/>
</RelativeLayout>
AndroidManifext.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.searchandfilterlistview"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".SearchAndFilterList"
android:label="#string/title_activity_search_and_filter_list" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I hope this code will will helpful to implement custom search and filter listview.
You can use:
http://developer.android.com/reference/android/widget/TextView.html
addTextChangedListener( TextWatcher watcher )
to figure out when the textview was changed. I believe it should be called everytime a letter is added or removed.
Then update your list adapter to dislplay the new items by either:
creating a new list adapter and populating it with the items that satisfy the filter or
having a subclass of the BaseAdapter to accept your filter and call notifyDataSetChanged() after it has finished removing the items you no longer want
http://developer.android.com/reference/android/widget/BaseAdapter.html
Search a listview based on input in EditText
public class MainActivity extends Activity {
private ListView lv,lv2;
private EditText et;
String listview_array[]={"01634 ABOHAR","080 Bangalore","011 Delhi","Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "1234", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air", "Mac Mini", "MacBook Pro"};
private ArrayList<String> array_sort = new ArrayList<String>();
int textlength = 0;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.ListView01);
lv2 = (ListView) findViewById(R.id.ListView02);
et = (EditText) findViewById(R.id.EditText01);
lv.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, listview_array));
int x= lv.getHeaderViewsCount ();
System.out.println("x========"+x);
lv.setAdapter(new ArrayAdapter<String>
(MainActivity.this,
android.R.layout.simple_list_item_1, listview_array));
et.addTextChangedListener(new TextWatcher()
{
public void afterTextChanged(Editable s)
{
// Abstract Method of TextWatcher Interface.
}
public void beforeTextChanged(CharSequence s,
int start, int count, int after)
{
// Abstract Method of TextWatcher Interface.
}
public void onTextChanged(CharSequence s,
int start, int before, int count)
{
textlength = et.getText().length();
array_sort.clear();
for (int i = 0; i < listview_array.length; i++)
{
if (textlength <= listview_array[i].length())
{
String s2= et.getText().toString();
if(listview_array[i].toString().contains(et.getText().toString()))
{
array_sort.add(listview_array[i]);
}
}
}
lv.setAdapter(new ArrayAdapter<String>
(MainActivity.this,
android.R.layout.simple_list_item_1, array_sort));
}
});
}
}
For search in custom listview based on class item refer the link implement search on a custom listview. Modify it according to your needs.
when you use custom listView
Adapter :
public class Adapter extends ArrayAdapter {
ArrayList<String> list = new ArrayList<>();
ArrayList<String> filteredData = new ArrayList<>();
public Adapter(#NonNull Context context, int resource) {
super(context, resource);
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflate = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
#SuppressLint("ViewHolder") View vi = inflate.inflate(R.layout.ly_items, null);
try {
JSONObject js = new JSONObject(list.get(position));
TextView txtItem = vi.findViewById(R.id.txtItem);
ImageView imgItem = vi.findViewById(R.id.imgItem);
txtItem.setText(js.getString("name") + " - " + js.getInt("number"));
Picasso.get().load(js.getString("logo_url")).into(imgItem);
} catch (JSONException e) {
e.printStackTrace();
}
return vi;
}
#Override
public void add(#Nullable Object object) {
super.add(object);
list.add(object.toString());
filteredData.add(object.toString());
}
#Override
public int getCount() {
return list.size();
}
#Nullable
#Override
public Object getItem(int position) {
return list.get(position);
}
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
list.clear();
if (charText.length() == 0) {
list.addAll(filteredData);
} else {
for (String wp : filteredData) {
try {
JSONObject json = new JSONObject(wp);
if (json.getString("name").toLowerCase().contains(charText) || json.getString("number").contains(charText)) {
list.add(wp);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
notifyDataSetChanged();
}
}
And your class:
Adapter adapter;
ListView list;
EditText edtSearch;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
list = findViewById(R.id.list);
edtSearch = findViewById(R.id.edtSearch);
adapter = new Adapter(this, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
edtSearch.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) {
adapter.filter(s.toString());
}
#Override
public void afterTextChanged(Editable s) {
}
});
}
1) create a custom adapter for your list view and create a removeIfMatch(String s) method:
public void removeIfMatch(String s) {
for item in adapter:
if item.matches(s) {
data.removeItem(item);
notifyDataSetChanged();
break
}
}
2) create a callback for when the EditText contents change
3) invoke adapter.removeIfMatch(editText.getText())

Categories

Resources