I am working with a Fragment that handles a RecyclerView with different adapters, but when I try to show my emptyView TextView in the RecyclerView it simply stops the RecyclerView from working properly.
I created the following filter in my adapter:
/**
* Method that filters the data using the onQueryTextSubmit and onQueryTextChange.
*
* @return a Filter class that calls the method performFiltering of the FilterResults class
* and this method applies the filter and returns a list with the resulting data filtered.
*/
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence querySample) {
if (emptyView.getVisibility() == View.VISIBLE) {
emptyView.setVisibility(View.GONE);
}
/*
* Verifies the value of the sampleNameSearched and compares the data.
*/
if (querySample == null) {
// Updates the recyclerView with the sampleList.
sampleListFiltered.submitList(sampleList);
// holder.sampleView.setTextColor(ContextCompat.getColor(inflater.getContext(), R.color.BaseColor_1));
} else {
// Cleans the accentuation, letter case and other symbols of the querySample.
sampleNameSearched = Normalizer.normalize(querySample.toString(), Normalizer.Form.NFD)
.replaceAll("[^\\p{ASCII}]", "").toLowerCase();
// Creates the list that will save the filtered samples.
List<Sample> filteredSampleList = new LinkedList<>();
// Gets the data filtered in the for loop.
for (Sample sample : sampleList) {
// Cleans the accentuation, letter case and other symbols.
String sampleName = Normalizer.normalize(sample.getName(), Normalizer.Form.NFD)
.replaceAll("[^\\p{ASCII}]", "").toLowerCase();
// Adds the sample that matches the filter in the filteredSampleList.
if (sampleName.contains(sampleNameSearched)) {
filteredSampleList.add(sample);
}
}
// Updates the RecyclerView.
sampleListFiltered.submitList(filteredSampleList);
// TODO: Find a solution for not showing the emptyView instantly (not entering the onBindViewHolder).
/*
* if filteredSampleList is empty, shows the emptyView with the proper message.
*/
if (filteredSampleList.isEmpty()) {
// Updates the RecyclerView.
emptyView.setVisibility(View.VISIBLE);
} else {
if (emptyView.getVisibility() == View.VISIBLE) {
emptyView.setVisibility(View.GONE);
}
}
}
// Returns the filterResults.
FilterResults filterResults = new FilterResults();
filterResults.values = sampleListFiltered;
return filterResults;
}
// Publish the results on the RecyclerView.
@Override
protected void publishResults(CharSequence constraint, FilterResults filterResults) {
notifyDataSetChanged();
}
};
}
I cannot find out why my emptyView.setVisibility() sometimes works and others simply doesn't.
My layout is the following:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@id/search_sample_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
android:layout_marginTop="25dp"
android:layout_marginEnd="25dp"
app:layout_constraintTop_toBottomOf="@+id/sample_folder_selector">
<SearchView
android:id="@+id/sample_search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:background="@drawable/search_box_border"
android:clickable="true"
android:iconifiedByDefault="false"
android:layoutDirection="rtl"
android:queryHint="@string/sample_search" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ListNavigatorRecyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="25dp"
android:layout_marginTop="25dp"
android:layout_marginEnd="25dp"
app:layout_constraintBottom_toTopOf="@+id/ButtonPanel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_sample_field"
app:layout_constraintVertical_bias="1.0" />
<TextView
android:id="@+id/emptyListNavigatorView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="25dp"
android:layout_marginEnd="25dp"
android:layout_marginBottom="100dp"
android:gravity="center"
android:text=""
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/ButtonPanel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_sample_field"
app:layout_constraintVertical_bias="1.0" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/ButtonPanel"
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="@color/BaseColor_4"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent">
<ImageButton
android:id="@+id/remove_sample_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="25dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:src="@drawable/btn_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
style="@style/IconButton" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Just to make sure that you understand the problem you can see some prints of the problem below:
What was supposed to happen:
Step 1 - Filter: Filtering
Step 2 - Writing a sample that doesn't exist: Sample that doesn't exist
Step 3 - Removing the wrong character: The wrong character removed
What is happening right now (not supposed to happen):
Step 1 - Filter (working): Filtering
Step 2 - Writing a sample that doesn't exist (not showing the emptyView): Not showing the emptyView
Step 3 - Removing the wrong character (not showing the sample nor the bold character): Not showing the sample
If I press the search button on the keyboard it works, but it was intended to work without pressing the search button...
Can someone help me with this problem?
I used a toast, and the toast works, but when it comes to using any kind of set method in the performFiltering or layout that requires a set method it seems that Android somehow losses its working flow.
I tried the following implementations:
How to show an empty view with a RecyclerView?
https://alexzh.com/how-to-setemptyview-to-recyclerview/
https://www.reddit.com/r/androiddev/comments/3bjnxi/best_way_to_handle_recyclerview_empty_state/