I'm currently developing an Android application which can either load information from my website or use the information stored in an SQLite database. I'm trying to implement a search feature into it but I ran into a problem.
The data in my recyclerview doesn't update when a search is made. I've looked it up on Google many times but I still haven't found a solution. Is there a bright person here willing to help me?
MainActivity.java
public class MainActivity extends AppCompatActivity implements DienstAdapter.ListItemClickListener, NavigationView.OnNavigationItemSelectedListener {
private static final String DIENST_URL = "https://mywebsite.com/apps/test/dienstenapi.php";
private RecyclerView recyclerView;
private DienstAdapter adapter;
private List<Dienst> dienstList;
private SQLiteDatabase mDb;
private Cursor cursor;
private SharedPreferences sharedPreferences;
private NavigationView navigationView;
private View headerView;
private TextView gebruikersnaam;
private Resources res;
private SwipeRefreshLayout swiper;
private static Toast mToast = null;
private SearchView searchView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = this.getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(R.string.app_name);
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
headerView = navigationView.getHeaderView(0);
gebruikersnaam = headerView.findViewById(R.id.gebruikersnaam);
res = getResources();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
setupPreferenceGebruikersnaam();
swiper = findViewById(R.id.swiper);
swiper.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
dienstList.clear();
loadDiensten();
}
});
dienstList = new ArrayList<>();
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
DienstDbHelper dbHelper = new DienstDbHelper(this);
mDb = dbHelper.getWritableDatabase();
loadDiensten();
}
#Override
protected void onDestroy() {
sharedPreferences.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
super.onDestroy();
}
SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("example_text")){
setupPreferenceGebruikersnaam();
}
}
};
private void loadDienstenOnline() {
String moetInfoOphalen = sharedPreferences.getString("example_list", "1");
if (moetInfoOphalen.equals("1") || moetInfoOphalen.equals("0")) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, DIENST_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray diensten = new JSONArray(response);
for (int i = 0; i < diensten.length(); i++) {
JSONObject dienstObject = diensten.getJSONObject(i);
int id = dienstObject.getInt("id");
String naam = dienstObject.getString("naam");
String beschrijving = dienstObject.getString("beschrijving");
String categorie = dienstObject.getString("categorie");
double prijs = dienstObject.getDouble("prijs");
String afbeelding = dienstObject.getString("afbeelding");
dienstList.add(new Dienst(id, naam, beschrijving, categorie, prijs, afbeelding));
}
voegDienstenToeAanDb(mDb, dienstList);
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
Volley.newRequestQueue(this).add(stringRequest);
} else {
loadDienstenOffline();
Toast.makeText(MainActivity.this, R.string.instelling_blokkeert_ophalen_diensten, Toast.LENGTH_LONG).show();
}
}
private void loadDienstenOffline() {
cursor = getAlleDiensten();
if ((cursor != null) && (cursor.getCount() > 0)) {
omzettenCursorNaarDiensten(cursor);
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
} else {
dienstList.add(new Dienst(0, "", "", "", 0, ""));
adapter = new DienstAdapter(MainActivity.this, dienstList, MainActivity.this);
recyclerView.setAdapter(adapter);
recyclerView.setVisibility(View.GONE);
if (mToast != null)
mToast.cancel();
mToast.makeText(this, R.string.internet_werkt_niet, Toast.LENGTH_LONG).show();
}
}
private boolean internetIsBeschikbaar() {
ConnectivityManager cm =(ConnectivityManager) this.getSystemService(CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
private void loadDiensten() {
recyclerView.setVisibility(View.VISIBLE);
if (internetIsBeschikbaar()) {
loadDienstenOnline();
} else {
loadDienstenOffline();
}
swiper.setRefreshing(false);
}
#Override
public void onListItemClick(String url, String naam) {
Intent intent = new Intent(MainActivity.this, DienstActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, url);
intent.putExtra("DienstNaam", naam);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
inflater.inflate(R.menu.search_menu, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
searchView.setSearchableInfo(searchManager != null ? searchManager.getSearchableInfo(getComponentName()) : null);
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
adapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
adapter.getFilter().filter(query);
return false;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Intent startSettingsActivity = new Intent(this, SettingsActivity.class);
startActivity(startSettingsActivity);
return true;
} else if (id == R.id.action_search) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
return;
}
if (!searchView.isIconified()) {
searchView.setIconified(true);
return;
}
super.onBackPressed();
}
private static void voegDienstenToeAanDb(SQLiteDatabase db, List<Dienst> diensten){
if(db == null){
return;
}
List<ContentValues> list = new ArrayList<>();
ContentValues cv;
for (Dienst d : diensten) {
cv = new ContentValues();
cv.put(DienstContract.DienstEntry.COLUMN_NAAM, d.getNaam());
cv.put(DienstContract.DienstEntry.COLUMN_BESCHRIJVING, d.getBeschrijving());
cv.put(DienstContract.DienstEntry.COLUMN_CATEGORIE, d.getCategorie());
cv.put(DienstContract.DienstEntry.COLUMN_PRIJS, d.getPrice());
cv.put(DienstContract.DienstEntry.COLUMN_AFBEELDING, d.getAfbeelding());
list.add(cv);
}
try
{
db.beginTransaction();
//clear the table first
db.delete (DienstContract.DienstEntry.TABLE_NAME,null,null);
//go through the list and add one by one
for(ContentValues c : list){
db.insert(DienstContract.DienstEntry.TABLE_NAME, null, c);
}
db.setTransactionSuccessful();
}
catch (SQLException e) {
//too bad :(
}
finally
{
db.endTransaction();
}
}
private Cursor getAlleDiensten() {
return mDb.query(
DienstContract.DienstEntry.TABLE_NAME,
null,
null,
null,
null,
null,
DienstContract.DienstEntry._ID
);
}
private void omzettenCursorNaarDiensten(Cursor c) {
int teller = 0, id;
String naam, beschrijving, categorie, afbeelding;
double prijs;
while (c.moveToPosition(teller)) {
id = Integer.parseInt(c.getString(c.getColumnIndex(DienstContract.DienstEntry._ID)));
naam = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_NAAM));
beschrijving = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_BESCHRIJVING));
categorie = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_CATEGORIE));
prijs = c.getDouble(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_PRIJS));
afbeelding = c.getString(c.getColumnIndex(DienstContract.DienstEntry.COLUMN_AFBEELDING));
dienstList.add(new Dienst(id, naam, beschrijving, categorie, prijs, afbeelding));
teller++;
}
}
private void setupPreferenceGebruikersnaam() {
String text = String.format(res.getString(R.string.welkomsbericht), sharedPreferences.getString("example_text", "gebruiker"));
gebruikersnaam.setText(text);
}
}
DienstAdapter.java
public class DienstAdapter extends RecyclerView.Adapter<DienstAdapter.DienstViewHolder> implements Filterable {
private Context mContext;
private List<Dienst> dienstList;
private List<Dienst> dienstListFiltered;
private final ListItemClickListener mOnClickListener;
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
dienstListFiltered = dienstList;
} else {
List<Dienst> filteredList = new ArrayList<>();
for (Dienst row : dienstList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getNaam().toLowerCase().contains(charString.toLowerCase()) || row.getBeschrijving().contains(charSequence)) {
filteredList.add(row);
}
}
dienstListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = dienstListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
dienstListFiltered = (ArrayList<Dienst>) filterResults.values;
notifyDataSetChanged();
}
};
}
public interface ListItemClickListener {
void onListItemClick(String url, String naam);
}
DienstAdapter(Context mContext, List<Dienst> dienstList, ListItemClickListener listener) {
this.mContext = mContext;
this.dienstList = dienstList;
this.dienstListFiltered = dienstList;
mOnClickListener = listener;
}
#Override
public DienstViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.list_layout, null);
return new DienstViewHolder(view);
}
#Override
public void onBindViewHolder(DienstViewHolder holder, int position) {
Dienst dienst = dienstList.get(position);
holder.tv_naam.setText(dienst.getNaam());
holder.tv_beschrijving.setText(dienst.getBeschrijving());
holder.tv_categorie.setText(String.valueOf(dienst.getCategorie()));
holder.tv_prijs.setText(String.valueOf(dienst.getPrice()));
if (dienst.getPrice() != 0)
holder.tv_prijs.setText(String.format("€ %.2f", dienst.getPrice()));
else
holder.tv_prijs.setText("");
Glide.with(mContext).load(dienst.getAfbeelding()).into(holder.iv_afbeelding);
}
#Override
public int getItemCount() {
return dienstList.size();
}
public class DienstViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ImageView iv_afbeelding;
TextView tv_naam, tv_beschrijving, tv_categorie, tv_prijs;
DienstViewHolder(View itemView) {
super(itemView);
iv_afbeelding = itemView.findViewById(R.id.iv_afbeelding);
tv_naam = itemView.findViewById(R.id.tv_naam);
tv_beschrijving = itemView.findViewById(R.id.tv_beschrijving);
tv_categorie = itemView.findViewById(R.id.tv_categorie);
tv_prijs = itemView.findViewById(R.id.tv_prijs);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int clickedPosition = getAdapterPosition();
String url = dienstList.get(clickedPosition).getAfbeelding().replace(".png", ".html");
String naam = dienstList.get(clickedPosition).getNaam();
mOnClickListener.onListItemClick(url, naam);
}
}
}
Firstly, getItemCount() and onBindViewHolder() should use the filtered list dienstListFiltered.
And You forgot to update the count of the FilterResults.
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
// Filter data ...
// ...
FilterResults filterResults = new FilterResults();
filterResults.values = dienstListFiltered;
filterResults.count = dienstListFiltered.size();
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
dienstListFiltered = (ArrayList<Dienst>) filterResults.values;
notifyDataSetChanged();
}
};
}
See: Custom Listview Adapter with filter Android
Can you add
notifyDataSetChanged();
immediately after
filteredList.add(row);
?
Related
I made an app with listView and I want to use search in top bar but it doesn't work.
In this program, I get the data from the firebase.
These are the codes below:
This is MainActivity code:
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
private static final int List_APP_LOADER = 0;
ArrayList<Informatin> listItem;
ListView listView;
listAdapter adapter;
DatabaseReference reference;
ArrayList<Informatin> mInformation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItem = new ArrayList<>();
listView = findViewById(R.id.list);
LoaderManager.getInstance(this).initLoader(LIST_APP_LOADER, null, this);
mInformation = new ArrayList<>();
adapter = new listAdapter(this, mInformation);
listView.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main_screen, menu);
MenuItem searchItem = menu.findItem(R.id.search_item);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
listView.getFilter().filter(newText);
return true;
}
});
return true;
}
}
This is listAdapter code
public class listAdapter extends ArrayAdapter<Informatin> implements Filterable {
List<Informatin> arrayList;
Context context;
public listAdapter(Context context, ArrayList<Informatin> informatins) {
super(context, 0, informatins);
this.context=context;
arrayList = informatins;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItemView = convertView;
if (listItemView == null) {
listItemView = LayoutInflater.from(getContext()).inflate(
R.layout.list_item, parent, false);
}
Informatin currentList = getItem(position);
TextView nameTextView = listItemView.findViewById(R.id.name);
TextView descriptionTextView = listItemView.findViewById(R.id.description);
TextView ageTextView = listItemView.findViewById(R.id.age);
ImageView imageView = listItemView.findViewById(R.id.image);
String firstName = currentList.getFirstName();
String lastName = currentList.getLastName();
String name = firstName + " " + lastName;
nameTextView.setText(name);
descriptionTextView.setText(currentList.getDescription());
ageTextView.setText(currentList.getAge());
return listItemView;
}
List<Informatin> informatins;
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Informatin> results = new ArrayList<>();
if (informatins == null)
informatins = arrayList;
if (constraint != null) {
if (informatins != null && informatins.size() > 0) {
for (final Informatin g : informatins) {
if (g.getFirstName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
arrayList = (ArrayList<Informatin>) results.values;
notifyDataSetChanged();
}
};
}
}
this is the picture of the problem
this is a screenshot for the problem from the device
Add this to your listadapter code:
Context context;
public listAdapter(Context context, List<Informatin> informatins) {
super();
this.context=context;
arraylist=informatins;
}
ArrayList<Informatin> informatins;
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
final FilterResults oReturn = new FilterResults();
final ArrayList<Informatin> results = new ArrayList<Informatin>();
if (informatins == null)
informatins = arraylist;
if (constraint != null) {
if (informatins != null && informatins.size() > 0) {
for (final Information g : informatins) {
if (g.getName().toLowerCase()
.contains(constraint.toString()))
results.add(g);
}
}
oReturn.values = results;
}
return oReturn;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
arraylist = (ArrayList<Informatin>) results.values;
notifyDataSetChanged();
}
};
}
Add this in your onquerytextchaged:
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);//replace adapter with listview name which in your case is listview as informed by you in comment
return true;
}
});
return true;
Modified MainActivity onCreate() code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listItem = new ArrayList<>();
listView = findViewById(R.id.list);
LoaderManager.getInstance(this).initLoader(LIST_APP_LOADER, null, this);
mInformation = new ArrayList<>();
adapter = new listAdapter(this, mInformation);
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true)//add this line
}
I m currently working on a android apps which fetch data from parse server. I wanted to filter my recyclerView by using searchview. But it shows me nothing while search. It gives me error in this line*for (ParseObject parseObject : mRooms){ * Please help me to edit my code regarding this issues.
roomcardrecyclerviewadapter
private List<ParseObject> mRooms = new ArrayList<>();
private ArrayList<ParseObject> filterlist;
private ParseObject room;
private String mSection;
private Context context;
public RoomCardRecyclerViewAdapter(){
super(DIFF_CALLBACK);
}
public static final DiffUtil.ItemCallback<ParseObject> DIFF_CALLBACK = new
DiffUtil.ItemCallback<ParseObject>() {
#Override
public boolean areItemsTheSame(#NonNull ParseObject oldItem, #NonNull ParseObject newItem) {
return oldItem.getObjectId() == newItem.getObjectId();
}
#Override
public boolean areContentsTheSame(#NonNull ParseObject oldItem, #NonNull ParseObject newItem) {
return (oldItem.getUpdatedAt().equals(newItem.getUpdatedAt()) &&
oldItem.getCreatedAt().equals(newItem.getCreatedAt()));
}
};
public RoomCardRecyclerViewAdapter(String section) {
this();
this.mSection = section;
}
public RoomCardRecyclerViewAdapter(Context context, List<ParseObject>arrayList) {
this();
this.context = context;
mRooms = arrayList;
filterlist = (ArrayList<ParseObject>) arrayList;
}
public class RoomViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
protected ImageView mRoomImage;
protected TextView mRoomPrice;
protected TextView mInclusiveOrNot;
protected TextView mPropertyType;
protected TextView mNumOfBeds;
protected TextView mNumOfBaths;
protected TextView mRoomLocation;
private Context context;
public RoomViewHolder(Context context, View itemView) {
super(itemView);
mRoomImage = itemView.findViewById(R.id.room_image);
mRoomPrice = itemView.findViewById(R.id.price_label);
mInclusiveOrNot = itemView.findViewById(R.id.incl_excl_label);
mPropertyType = itemView.findViewById(R.id.propertyType_label);
mNumOfBeds = itemView.findViewById(R.id.num_beds_label);
mNumOfBaths = itemView.findViewById(R.id.details_num_baths_label);
mRoomLocation = itemView.findViewById(R.id.location_label);
this.context = context;
//set onclick listener
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
Log.i("Click event: ", "My room has been clicked.");
int pos = getAdapterPosition();
Intent intent;
ParseObject room = getCurrentList().get(pos);
//create the ParseObject proxy
ParseProxyObject roomProxy = new ParseProxyObject(room);
Toast.makeText(context, room.getString("roomSuburb"), Toast.LENGTH_LONG).show();
//fork to corresponding activity
if(mSection != null) {
Log.i("mSection text: ", "mSection text is: " + mSection);
if (mSection.equals("My Rooms")) {
//start my rooms detail activity
Log.i("My room: ", "Room selected " + roomProxy.getObjectId());
intent = new Intent(context, MyRoomDetailActivity.class);
//add the room to the intent
intent.putExtra("currentSelectedRoomObject", room);
Log.i("Selected room", "Put Extra, " + room);
intent.putExtra("roomObject", roomProxy);
context.startActivity(intent);
}
}else {
Log.i("My room:", "RoomDetailActivity loaded for MyRoomDetail Activity instead");
intent = new Intent(context, RoomDetailActivity.class);
//add the proxy to the intent
intent.putExtra("roomObject", roomProxy);
context.startActivity(intent);
}
}
}
#Override
public RoomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//inflating the viewholder with the appropriate views
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.room_cardview, parent,
false);
return new RoomViewHolder(parent.getContext(), view);
}
#Override
public void onBindViewHolder(#NonNull RoomViewHolder holder, int position) {
room = getItem(position);
holder.mRoomLocation.setText(room.getString("roomSuburb"));
holder.mRoomPrice.setText(Integer.toString(room.getInt("roomMonthlyRent")));
holder.mInclusiveOrNot.setText(room.getString("roomRentInclusiveOfBills"));
holder.mPropertyType.setText(room.getString("roomPropertyType"));
holder.mNumOfBeds.setText(Integer.toString(room.getInt("roomBedrooms")));
holder.mNumOfBaths.setText(Integer.toString(room.getInt("roomBathrooms")));
#Override
public Filter getFilter(){
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()){
room = (ParseObject) mRooms;
}else {
List<ParseObject> filteredList = new ArrayList<>();
for (ParseObject parseObject : mRooms){
if (parseObject.getString("roomSuburb").toLowerCase().contains(charString.toLowerCase())){
filteredList.add(parseObject);
}
}
room = (ParseObject) filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = room;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
room = (ParseObject) filterResults.values;
notifyDataSetChanged();
}
};
}
mainActivity
mHomeSectionsPagerAdapter = new
HomeSectionsPagerAdapter(getSupportFragmentManager());
roomCardRecyclerViewAdapter = new RoomCardRecyclerViewAdapter(this,
mRooms);
mRooms = new ArrayList<>();
// Set up the ViewPager with the sections adapter.
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mHomeSectionsPagerAdapter);
#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 ParseQuery<ParseUser> query = ParseUser.getQuery();
//get the search view and set the searchable configuration
SearchManager searchManager = (SearchManager)
getSystemService(Context.SEARCH_SERVICE);
MenuItem item = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(item);
//assumes the current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo
(getComponentName());
searchView.setSubmitButtonEnabled(true);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
roomCardRecyclerViewAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
roomCardRecyclerViewAdapter.getFilter().filter(newText);
return false;
}
});
return true;
}
#Override
public boolean onSearchRequested() {
//pauseSomeStuff();
//roomCardRecyclerViewAdapter.getFilter().filter(query);
return super.onSearchRequested();
}
I think problem is here:
You haven't shared first lines of MainActivity where you declare your variables. So, I assume that you have some code like this:
List mRooms;
Then I assume that, before assigning value to this mRooms you have passed it to RoomCardRecyclerViewAdapter:
roomCardRecyclerViewAdapter = new RoomCardRecyclerViewAdapter(this, mRooms);
mRooms = new ArrayList<>();
Then you have assigned value to mRooms. That's why you get NPE. You can solve this problem just like this:
mRooms = new ArrayList<>();
roomCardRecyclerViewAdapter = new RoomCardRecyclerViewAdapter(this, mRooms);
I'm currently building an app which use a RealmRecyclerViewAdapter for displaying the elements inside Realm.
I was looking into implementing the Filterable interface, which I managed to do (thanks to those answers: Link 1 Link 2) but now I have a side effect: when I'm filtering, the Adapter shows all the elements, even if they doesn't match with the filter. Also, the excluded element does show incorrect information. When I close the SearchView, everything is back to normal.
Here is the Activity when I call the Adapter:
public class MainActivity extends AppCompatActivity {
private Realm realm;
HabitCardAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
setUIMode();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set the title inside the top bar for this activity.
// I'm not doing it inside the Manifest because it changes the app's name
setTitle(R.string.MainActivityTitle);
// Bottom App Bar setup
BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar);
cutBottomAppEdge(bottomAppBar); // Diamond shape
// Add listener to Stats button inside the bottom app bar
MenuItem statsMenuItem = bottomAppBar.getMenu().findItem(R.id.statsMenuItem);
statsMenuItem.setOnMenuItemClickListener(item -> {
if(item.getItemId() == R.id.statsMenuItem){
Intent i = new Intent(getApplicationContext(), StatsActivity.class);
startActivity(i);
return true;
}
return false;
});
// FAB button setup
FloatingActionButton fab = findViewById(R.id.fabAddButton);
fab.setOnClickListener(view -> {
Intent intent = new Intent(getBaseContext(), CreateHabitActivity.class);
startActivity(intent);
});
RecyclerView rv = findViewById(R.id.habitCardRecyclerView);
TextView emptyMessage = findViewById(R.id.mainEmptyHabitListMessage);
realm = Realm.getDefaultInstance();
RealmResults<Habit> results = realm.where(Habit.class).sort("id").findAll();
results.addChangeListener(habits -> {
if (habits.size() > 0) {
rv.setVisibility(View.VISIBLE);
emptyMessage.setVisibility(View.GONE);
} else {
emptyMessage.setVisibility(View.VISIBLE);
rv.setVisibility(View.GONE);
}
});
//this is necessarily because it is not changed yet
if (results.size() > 0) {
rv.setVisibility(View.VISIBLE);
emptyMessage.setVisibility(View.GONE);
} else {
emptyMessage.setVisibility(View.VISIBLE);
rv.setVisibility(View.GONE);
}
final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
rv.setLayoutManager(layoutManager);
adapter = new HabitCardAdapter(results, true, this, realm);
rv.setAdapter(adapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.top_app_bar_menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.searchMenuItem).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
adapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
if (adapter != null) {
adapter.getFilter().filter(newText);
return true;
}
return false;
}
});
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.searchMenuItem:
return true;
case R.id.settingMenuItem:
Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(intent); //FIXME: animazione
return true;
case R.id.aboutMenuItem:
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this);
builder.setTitle(getString(R.string.about_us_title));
builder.setMessage(getString(R.string.about_us_message));
builder.setIcon(R.drawable.ic_sprout_fg_small);
builder.setPositiveButton("OK", (dialogInterface, i) -> {
dialogInterface.dismiss();
});
builder.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Set the Night/Light UI. On the first run of the app, the user get the Light UI.
*/
private void setUIMode() {
SharedPreferences preferences = getSharedPreferences(SettingsActivity.SHARED_PREFS_FILE, MODE_PRIVATE);
int pref = preferences.getInt(SettingsActivity.SHARED_PREFS_DARK_MODE, AppCompatDelegate.MODE_NIGHT_NO);
AppCompatDelegate.setDefaultNightMode(pref);
}
private void cutBottomAppEdge(BottomAppBar bar) {
BottomAppBarTopEdgeTreatment topEdge = new SproutBottomAppBarCutCornersTopEdge(
bar.getFabCradleMargin(),
bar.getFabCradleRoundedCornerRadius(),
bar.getCradleVerticalOffset());
MaterialShapeDrawable babBackground = (MaterialShapeDrawable) bar.getBackground();
//It requires 1.1.0-alpha10
babBackground.setShapeAppearanceModel(
babBackground.getShapeAppearanceModel()
.toBuilder()
.setTopEdge(topEdge)
.build());
}
#Override
protected void onDestroy() {
super.onDestroy();
realm.removeAllChangeListeners();
realm.close();
}
}
Here is the HabitCardAdapter which extends RealmRecyclerViewAdapter:
public class HabitCardAdapter extends RealmRecyclerViewAdapter<Habit, HabitCardAdapter.ViewHolder> implements Filterable {
Context ct;
OrderedRealmCollection<Habit> list;
Realm mRealm;
public HabitCardAdapter(#Nullable OrderedRealmCollection<Habit> data, boolean autoUpdate, Context context, Realm realm) {
super(data, autoUpdate); //autoUpdate to true
ct = context;
list = data;
mRealm = realm;
}
#Override
public int getItemCount() {
return this.list.size();
}
#NonNull
#Override
public HabitCardAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
//TODO: inflatare diversi tipi di carte a seconda del habitType
View view = inflater.inflate(R.layout.fragment_habit_counter_card, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull HabitCardAdapter.ViewHolder holder, int position) {
final Habit habit = getItem(position);
if (habit != null) {
holder.setHabit(habit);
holder.editHabitButton.setOnClickListener(view -> {
Intent intent = new Intent(ct, EditHabitActivity.class);
intent.putExtra("HABIT_ID", habit.getId());
//TODO: Aggiungere l'animazione
ct.startActivity(intent);
});
holder.checkButton.setOnClickListener(view -> {
int habitId = habit.getId();
int newRepValue = habit.getRepetitions() + 1;
int maxReps = habit.getMaxRepetitions();
Log.d("Testing", newRepValue + " - " + maxReps);
if (newRepValue <= habit.getMaxRepetitions()) {
habit.getRealm().executeTransaction(realm -> {
Habit result = realm.where(Habit.class).equalTo("id", habitId).findFirst();
if (result != null) {
result.setRepetitions(newRepValue);
String newLabel = "Completato " + newRepValue + " volte su " + maxReps;
holder.progressLabel.setText(newLabel);
}
});
}
});
}
}
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
if (text == null || "".equals(text)) {
updateData(mRealm.where(Habit.class).sort("id").findAllAsync());
} else {
updateData(mRealm.where(Habit.class).contains("title", text).sort("id").findAllAsync());
}
}
public Filter getFilter() {
HabitFilter filter = new HabitFilter(this);
return filter;
}
private class HabitFilter extends Filter {
private final HabitCardAdapter adapter;
private HabitFilter(HabitCardAdapter adapter) {
this.adapter = adapter;
}
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
return new FilterResults();
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
adapter.filterResults(charSequence.toString());
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView habitTitle;
ProgressBar progressBar;
TextView progressLabel;
ImageButton editHabitButton;
Button checkButton;
public ViewHolder(#NonNull View itemView) {
super(itemView);
habitTitle = itemView.findViewById(R.id.habitCardTitle);
editHabitButton = itemView.findViewById(R.id.counterHabitEditButton);
progressBar = itemView.findViewById(R.id.counterHabitProgressBar);
checkButton = itemView.findViewById(R.id.checkButton);
progressLabel = itemView.findViewById(R.id.counterHabitProgressLabel);
}
void setHabit(Habit habit) {
this.habitTitle.setText(habit.getTitle());
this.progressBar.setProgress(habit.getRepetitions());
this.progressBar.setMax(habit.getMaxRepetitions());
this.progressLabel.setText("Completato " + habit.getRepetitions() + " volte su " + habit.getMaxRepetitions()); //FIXME: sposta la stringa
}
}
}
I don't really know if this is the way to go for this problem, but it's now behaving as expected so I'll share the solution here.
Inside the HabitCardAdapter I added another OrderedRealmCollection<Habit> member, called filteredList, while list holds the whole data. In the costructor both of filteredList and list are tied to the data passed to the constructor, but while filteredList will be modified by the query, list will not (probably putting it to final is the best practice). Then everything in the Adapter will now reference to filteredList instead of list, and when the SearchView is selected and the query is up, filteredList will get the data, and then updateData(filteredList) will be called.
Here is what I changed:
public class HabitCardAdapter extends RealmRecyclerViewAdapter<Habit, HabitCardAdapter.ViewHolder> implements Filterable {
Context ct;
OrderedRealmCollection<Habit> list;
OrderedRealmCollection<Habit> filteredList;
Realm mRealm;
...
}
public HabitCardAdapter(#Nullable OrderedRealmCollection<Habit> data, Context context, Realm realm) {
super(data, true, true);
ct = context;
list = data;
filteredList = data;
mRealm = realm;
setHasStableIds(true);
}
Probably the error was here in getItemCount(), when the filteredListsize was smaller than the list one, but since I didn't have any reference to filteredList, I didn't have any way to change that size, and so the Adapter would continue to show - for example - 6 views while I was querying for 3. Having it as a properly class member it let me make this:
#Override
public int getItemCount() {
return this.filteredList.size();
}
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
if (text == null || "".equals(text)) {
filteredList = list;
} else {
filteredList = mRealm.where(Habit.class).beginsWith("title", text, Case.INSENSITIVE).sort("id").findAll();
}
updateData(filteredList);
}
i am implementing search filter using search view i loaded list
successfully and when i clicked on searchview and type word
application crash below is error is Here's the code :
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
// private static final String url = "http://example.com/OnlineDoctor/mobileapp/doctors_list.php?";
private List<ListItems> listItemses;
private RecyclerView recyclerView;
private MainFilteredAdapter mrecyclerViewAdapter;
private LinearLayoutManager linearLayoutManager;
private static final String TAG = MainActivity.class.getSimpleName();
private RelativeLayout ownerlayout;
private SearchView searchView;
private String logintype, property_id;
private String userid;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = findViewById(R.id.recyclerview);
listItemses = new ArrayList<>();
mrecyclerViewAdapter = new
MainFilteredAdapter(listItemses,getApplicationContext());
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mrecyclerViewAdapter);
loadRenterList();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
mrecyclerViewAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
mrecyclerViewAdapter.getFilter().filter(query);
return false;
}
});
return true;
}
public void loadRenterList() {
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
JSONArray jsonArray = null;
JSONObject jsonObject = null;
try {
jsonArray = response.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject mjsonObject = (JSONObject) jsonArray.get(i);
ListItems newslist = new ListItems();
newslist.setId(mjsonObject.getString("id"));
listItemses.add(newslist);
mrecyclerViewAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
// adapter.notifyDataSetChanged();
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(jsonObjReq);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search)
.getActionView();
searchView.setSearchableInfo(searchManager
.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
mrecyclerViewAdapter.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
mrecyclerViewAdapter.getFilter().filter(query);
return false;
}
});
return true;
}
public class MainFilteredAdapter extends RecyclerView.Adapter<MainFilteredAdapter.MyViewHolder> implements Filterable {
private List<ListItems> doctorlist;
private List<ListItems> doctorlistFiltered;
Context context;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
public TextView spec_name,placeName,property_status;
public ImageView imageView;
LinearLayout lllistrow;
public MyViewHolder(View itemView) {
super(itemView);
property_status = itemView.findViewById(R.id.duration);
spec_name = itemView.findViewById(R.id.spec_name);
placeName = itemView.findViewById(R.id.placeName);
imageView = itemView.findViewById(R.id.placeImage);
lllistrow= itemView.findViewById(R.id.mainHolder);
lllistrow.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getLayoutPosition();
switch (v.getId()) {
case R.id.mainHolder:
break;
}
}
}
public MainFilteredAdapter(List<ListItems> boardList, Context context) {
this.doctorlist = boardList;
this.doctorlistFiltered=boardList;
this.context = context;
}
#Override
public MainFilteredAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listitem, parent, false);
return new MainFilteredAdapter.MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MainFilteredAdapter.MyViewHolder holder, int position) {
ListItems listItems = doctorlistFiltered.get(position);
/*Picasso.with(context).load("http://neweraprime.com/SFDS/faculty/Upload/Books/" + newslist.get(position).getThumbnailUrl())
.placeholder(R.drawable.ic_pdffile).error(R.drawable.ic_pdffile).resize(256, 256).onlyScaleDown() //Url of the image to load.
.into(holder.thumbNail);*/
holder.property_status.setText(listItems.getPayment_status());
holder.spec_name.setText(listItems.getAddress());
holder.placeName.setText(listItems.getTitle());
}
#Override
public Filter getFilter()
{
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
doctorlistFiltered = doctorlist;
} else {
List<ListItems> filteredList = new ArrayList<>();
for (ListItems row : doctorlist) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getCity().toLowerCase().contains(charString.toLowerCase()) || row.getAddress().contains(charSequence)) {
filteredList.add(row);
}
}
doctorlistFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = doctorlistFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
doctorlistFiltered = (ArrayList<ListItems>) filterResults.values;
notifyDataSetChanged();
}
};
}
#Override
public int getItemCount() {
if(doctorlist != null){
return doctorlistFiltered.size();
} else {
return 0;
}
}
and here is the error
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.www.homerent.MainFilteredAdapter.getItemCount(MainFilteredAdapter.java:129)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4025)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3830)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4385)
at android.view.View.layout(View.java:19659)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1083)
at android.view.View.layout(View.java:19659)
at android.view.ViewGroup.layout(ViewGroup.java:6075)
I'd suspect your problem is here:
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
doctorlistFiltered = (ArrayList<ListItems>) filterResults.values;
notifyDataSetChanged();
}
Try using this instead:
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
doctorlistFiltered = new ArrayList<ListItems>();
if (filterResults.values != null) {
doctorlistFiltered.addAll((ArrayList<ListItems>) filterResults.values);
}
notifyDataSetChanged();
}
I haven't seen anything that guarantees that filterResults.values does contain a non null value(e.g. in case of an error during filtering).
Ps.:
Adjusting the getItemCount() as metionend in the comments should be a given.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I have problem:
There is three part of data that displayed in one RecyclerView. As you know, all of data are displayed in favourite page, which mean, they are not constant. If user press the favourite button, the data will be displayed in favourite page, otherwise it's won't. So, all of data are change every time, it depends on user activity. Because of this, I get trouble in getting item's ID when user click certain item.
I've already tried to solve this problem, but still stuck many days...
ShowFavouriteList.java
public class ShowFavouriteList extends AppCompatActivity implements AdapterFavList.FavListener {
private RecyclerView recyclerView;
private TextView noFavtsTV;
AppPreferences appPreferences;
private SearchView searchView;
private AdapterFavList yAdapterFavlist;
private AdapterFavList mAdapterFavlist;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_favourite_list);
SwipeRefreshLayout pullToRefresh = findViewById(R.id.pullToRefresh);
pullToRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
finish();
startActivity(getIntent());
}
});
//toolbar logo and desc
Toolbar topToolBar = (Toolbar) findViewById(R.id.toolbarTidur);
setSupportActionBar(topToolBar); //munculkan menu ke toolbar
getSupportActionBar().setDisplayHomeAsUpEnabled(true); //this line shows back button
recyclerView = findViewById(R.id.recycler_view);
noFavtsTV = findViewById(R.id.no_favt_text);
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("MyPref", 0);
SharedPreferences sPTuru = getApplicationContext().getSharedPreferences("MyTuru", 0);
SharedPreferences sPHome = getApplicationContext().getSharedPreferences("MyHome", 0);
PreferenceMenejer preferenceMenejer = new PreferenceMenejer(sharedPreferences, sPTuru, sPHome);
appPreferences = new AppPreferences(preferenceMenejer);
fetchData();
} // Oncreate
private void fetchData() {
List<Story> storyList = appPreferences.getFavouriteCardList();
List<YukulModel> yukulList = appPreferences.getFavouriteYukul();
List<HomeModel> modelList = appPreferences.getFavouriteHome();
if(storyList != null && storyList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
recyclerView.setAdapter(new AdapterFavList(this, storyList, yukulList, modelList, this, appPreferences));
}
if(yukulList != null && yukulList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
yAdapterFavlist = new AdapterFavList(this, storyList, yukulList, modelList, this, appPreferences);
recyclerView.setAdapter(yAdapterFavlist);
}
if(modelList != null && modelList.size() > 0) {
showNoFavtText(false);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
mAdapterFavlist = new AdapterFavList(this, storyList, yukulList, modelList, this, appPreferences);
recyclerView.setAdapter(mAdapterFavlist);
}
}
#Override
public void onItemKlik(int pos) {
// Tidur List
List<HomeModel> modelList = appPreferences.getFavouriteHome();
HomeModel click = modelList.get(pos);
Toast.makeText(getApplicationContext(), "Selected: " + click.getName(), Toast.LENGTH_LONG).show();
int id = Integer.parseInt(click.getIdStory());
if(modelList != null && modelList.size() > 0) {
if (id == 0) {
startActivity(new Intent(this, DoaPagi.class));
} else if (id == 1) {
startActivity(new Intent(this, DoaSore.class));
} else if (id == 2) {
startActivity(new Intent(this, DoaWc.class));
} else if (id == 3) {
startActivity(new Intent(this, DoaMasjid.class));
} else if (id == 4) {
startActivity(new Intent(this, DzikirShalat.class));
} else if (id == 5) {
startActivity(new Intent(this, ChildYukul.class));
} else if (id == 6) {
startActivity(new Intent(this, DoaPakaian.class));
} else if (id == 7) {
startActivity(new Intent(this, ChildTidur.class));
}
}
}
private void showNoFavtText(boolean show) {
noFavtsTV.setVisibility(show ? View.VISIBLE : View.GONE); //jika data yang ditampilkan tidak ada, maka show noFavsTv
recyclerView.setVisibility(show ? View.GONE : View.VISIBLE); //jika data yang ditampilkan tidak ada, maka don't show rV
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.search_fav, menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
// Associate searchable_tidur configuration with the SearchView
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView = (SearchView) menu.findItem(R.id.action_search_fav).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setMaxWidth(Integer.MAX_VALUE);
// listening to search query text change
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
// filter recycler view when query submitted
mAdapterFavlist.getFilter().filter(query);
return false;
}
#Override
public boolean onQueryTextChange(String query) {
// filter recycler view when text is changed
mAdapterFavlist.getFilter().filter(query);
return false;
}
});
return true;
}
// Agar back button pada halaman induk settings berfungsi
#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();
//noinspection SimplifiableIfStatement
if (id == R.id.search_fav) {
return true;
}
switch (item.getItemId()) {
case android.R.id.home:
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
AdapterFavList.java
public class AdapterFavList extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements Filterable {
public static final String ACTION_LIKE_IMAGE_CLICKED = "action_like_image_button";
final int VIEW_TYPE_TIDUR = 0;
final int VIEW_TYPE_YUKUL = 1;
final int VIEW_TYPE_HOME = 2;
private Context context;
private AppPreferences appPreferences;
private List<Story> storyList;
private List<YukulModel> yukulList;
private List<HomeModel> homeList;
private List<HomeModel> homeListFiltered;
private List<Object> collection = new ArrayList<Object>();
private FavListener listener;
private int changedItemPosition;
private int posisiItemYukul;
private int posisiItemHome;
private boolean isLiked;
public AdapterFavList(Context context, List<Story> storyList, List<YukulModel> yukulList, List<HomeModel> homeList, FavListener listener, AppPreferences appPreferences) {
this.context = context;
this.storyList = storyList;
this.yukulList = yukulList;
this.homeListFiltered = homeList;
this.listener = listener;
this.appPreferences = appPreferences;
addData();
}
public interface FavListener {
void onItemKlik(int pos);
// void onTidurKlik(int pos);
// void onYukulKlik(int pos);
}
public void addData() {
storyList = appPreferences.getFavouriteCardList();
yukulList = appPreferences.getFavouriteYukul();
homeList = appPreferences.getFavouriteHome();
if(storyList != null && storyList.size() > 0) {
collection.addAll(storyList);
}
if(yukulList != null && yukulList.size() > 0) {
collection.addAll(yukulList);
}
if(homeList != null && homeList.size() > 0) {
collection.addAll(homeListFiltered);
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_TIDUR) {
return new tidurViewHolder(LayoutInflater.from(context).inflate(R.layout.item_story_favourite_list, parent, false));
}
if(viewType == VIEW_TYPE_YUKUL) {
return new yukulViewHolder(LayoutInflater.from(context).inflate(R.layout.item_favourite_yukul, parent, false));
}
if(viewType == VIEW_TYPE_HOME) {
return new homeViewHolder(LayoutInflater.from(context).inflate(R.layout.item_fav_home, parent, false));
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Object item = collection.get(position);
if(holder instanceof tidurViewHolder){
((tidurViewHolder) holder).setViewData((Story) item, holder.getAdapterPosition());
}
if(holder instanceof yukulViewHolder){
((yukulViewHolder) holder).viewDataYukul((YukulModel) item, holder.getAdapterPosition());
}
if(holder instanceof homeViewHolder){
((homeViewHolder) holder).viewDataHome((HomeModel) item, holder.getAdapterPosition());
}
}
#Override
public int getItemCount() {
return collection.size();
}
#Override
public int getItemViewType(int position){
Object item = collection.get(position);
if(item instanceof Story) {
return VIEW_TYPE_TIDUR;
}
if(item instanceof YukulModel){
return VIEW_TYPE_YUKUL;
}
if(item instanceof HomeModel){
return VIEW_TYPE_HOME;
}
return -1;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
List<HomeModel> homeList = appPreferences.getFavouriteHome();
if (charString.isEmpty()) {
homeListFiltered = homeList;
}
else {
List<HomeModel> filteredList = new ArrayList<>();
for (HomeModel row : homeList) {
if ( row.getName().toLowerCase().contains(charString.toLowerCase()) ) {
filteredList.add(row);
}
}
homeListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = homeListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
homeListFiltered = (ArrayList<HomeModel>) filterResults.values;
notifyDataSetChanged();
}
};
} //Filter
public void tidurPutHeart(boolean isChecked, Story tidurstory) {
SharedPreferences tidursharedPreferences = context.getSharedPreferences("Turu", Activity.MODE_PRIVATE);
SharedPreferences.Editor tidureditor = tidursharedPreferences.edit();
tidureditor.putBoolean(tidurstory.getIdStory(), isChecked);
tidureditor.commit();
}
public void yukulPutHeart(boolean isChecked, YukulModel yukulstory) {
SharedPreferences yukulsharedPreferences = context.getSharedPreferences("Yukul", Activity.MODE_PRIVATE);
SharedPreferences.Editor yukuleditor = yukulsharedPreferences.edit();
yukuleditor.putBoolean(yukulstory.getIdStory(), isChecked);
yukuleditor.commit();
}
public void homePutHeart(boolean isChecked, HomeModel homestory) {
SharedPreferences homesharedPreferences = context.getSharedPreferences("Home", Activity.MODE_PRIVATE);
SharedPreferences.Editor homeeditor = homesharedPreferences.edit();
homeeditor.putBoolean(homestory.getIdStory(), isChecked);
homeeditor.commit();
}
//ViewHolder
public class tidurViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private CheckBox likeCheckBox;
public tidurViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
likeCheckBox = itemView.findViewById(R.id.like_button_cb);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// send selected contact in callback
}
});
} // itemView
public void setViewData(final Story story, final int adapterPosition) {
textView.setText(story.getName());
if (story.getIsLiked() == 1) {
likeCheckBox.setChecked(false);
}
else {
likeCheckBox.setChecked(true);
}
likeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changedItemPosition = adapterPosition;
if (buttonView.isPressed()) {
if (isChecked) {
tidurPutHeart(isChecked, story);
appPreferences.saveFavouriteCard(story);
}
else {
isLiked = false;
tidurPutHeart(isChecked, story);
appPreferences.deleteCard(story.getIdStory());
// updateLikes();
Toast.makeText(context, "Removed", Toast.LENGTH_SHORT).show();
if(collection.size() == 0) {
((Activity)context).finish();
context.startActivity(((Activity) context).getIntent());
}
}
}
}
});
} //setviewdata
public void updateLikes() {
if (!isLiked && storyList.get(changedItemPosition).getIsLiked() == 0) { //jika like dicabut (pada posisi hati yang sedang merah) di halaman favourite list
storyList.get(changedItemPosition).setIsLiked(0); //maka cabut juga warna merah di halaman favourite list
notifyItemRangeChanged(getAdapterPosition(), collection.size());
collection.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
} //updateLikes
} //tidurViewholder
//homeViewHolder
public class homeViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private CheckBox likeCheckBox;
public homeViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
likeCheckBox = itemView.findViewById(R.id.like_button_cb);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// send selected contact in callback
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
listener.onItemKlik(position);
}
}
}
});
} // itemView
public void viewDataHome(final HomeModel story, final int adapterPosition) {
textView.setText(story.getName());
if (story.getIsLiked() == 1) {
likeCheckBox.setChecked(false);
}
else {
likeCheckBox.setChecked(true);
}
likeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
changedItemPosition = adapterPosition;
if (buttonView.isPressed()) {
if (isChecked) {
homePutHeart(isChecked, story);
appPreferences.saveFavouriteHome(story);
}
else {
isLiked = false;
homePutHeart(isChecked, story);
appPreferences.deleteCardHome(story.getIdStory());
// updateLikesHome();
Toast.makeText(context, "Removed", Toast.LENGTH_SHORT).show();
if(collection.size() == 0) {
((Activity)context).finish();
context.startActivity(((Activity) context).getIntent());
}
}
}
}
});
} //setviewdata
public void updateLikesHome() {
if (!isLiked && homeList.get(changedItemPosition).getIsLiked() == 0) { //jika like dicabut (pada posisi hati yang sedang merah) di halaman favourite list
homeList.get(changedItemPosition).setIsLiked(0); //maka cabut juga warna merah di halaman favourite list
notifyItemRangeChanged(getAdapterPosition(), collection.size());
collection.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
} //updateLikes
} //homeviewholder
public class yukulViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
private CheckBox likeCheckBox;
public yukulViewHolder(View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_view);
likeCheckBox = itemView.findViewById(R.id.like_button_cb);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// send selected contact in callback
}
});
} //itemview
public void viewDataYukul(final YukulModel yukulId, final int adapterPosition) {
textView.setText(yukulId.getName());
if (yukulId.getIsLiked() == 1) {
likeCheckBox.setChecked(false);
}
else {
likeCheckBox.setChecked(true);
}
likeCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
posisiItemYukul = adapterPosition;
if (buttonView.isPressed()) {
if (isChecked) {
yukulPutHeart(isChecked, yukulId);
appPreferences.saveFavouriteYukul(yukulId);
}
else {
isLiked = false;
yukulPutHeart(isChecked, yukulId);
appPreferences.deleteCardYukul(yukulId.getIdStory());
// updateLikeYukul();
Toast.makeText(context, "Removed", Toast.LENGTH_SHORT).show();
if(collection.size() == 0) {
((Activity)context).finish();
context.startActivity(((Activity) context).getIntent());
}
}
}
}
});
} //viewdatayukul
public void updateLikeYukul() {
if (!isLiked && yukulList.get(changedItemPosition).getIsLiked() == 0) { //jika like dicabut (pada posisi hati yang sedang merah) di halaman favourite list
yukulList.get(changedItemPosition).setIsLiked(0); //maka cabut juga warna merah di halaman favourite list
notifyItemRangeChanged(getAdapterPosition(), collection.size());
collection.remove(getAdapterPosition());
notifyItemRemoved(getAdapterPosition());
}
} //updateLikes
} //yukulviewholder
} //HomeAdapter
try it adapter
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
ClickItem clickItem;
Context context;
//your data model
ArrayList<ModelField> modelFields;
public RecyclerviewAdapter(Context context, ArrayList<ModelField> modelField, ClickItem clickItem) {
this.context = context;
this.modelFields = modelField;
this.clickItem = clickItem;
}
#Override
public int getItemViewType(int position) {
//get view type
return super.getItemViewType(position);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
// get view create
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
// set bind view
if (holder instanceof viewHolder_1) {
((viewHolder_1) holder).bind(modelFields.get(position));
} else if (holder instanceof viewHolder_2) {
((viewHolder_2) holder).bind(modelFields.get(position));
} else if (holder instanceof viewHolder_3) {
((viewHolder_3) holder).bind(modelFields.get(position));
}
}
#Override
public int getItemCount() {
//arraylist size
return modelFields.size();
}
interface ClickItem {
void onClick(RecyclerView.ViewHolder viewHolder, ModelField modelField, int position);
}
public class viewHolder_1 extends RecyclerView.ViewHolder {
public viewHolder_1(#NonNull View itemView) {
super(itemView);
//casting views
}
public void bind(final ModelField item) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickItem.onClick(viewHolder_1.this, item, getAdapterPosition());
}
});
}
}
public class viewHolder_2 extends RecyclerView.ViewHolder {
public viewHolder_2(#NonNull View itemView) {
super(itemView);
//casting views
}
public void bind(final ModelField item) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickItem.onClick(viewHolder_2.this, item, getAdapterPosition());
}
});
}
}
public class viewHolder_3 extends RecyclerView.ViewHolder {
public viewHolder_3(#NonNull View itemView) {
super(itemView);
//casting views
}
public void bind(final ModelField item) {
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clickItem.onClick(viewHolder_3.this, item, getAdapterPosition());
}
});
}
}
}
and using
RecyclerviewAdapter recyclerviewAdapter = new RecyclerviewAdapter(this, your data arraylist, new RecyclerviewAdapter.ClickItem() {
#Override
public void onClick(RecyclerView.ViewHolder viewHolder, ModelField modelField, int position) {
}
});
recyclerview.setAdapter(recyclerviewAdapter);