如何在 RecyclerView 中创建一个空视图?
How to create an empty view in a RecyclerView?
我正在使用处理具有不同适配器的 RecyclerView 的 Fragment,但是当我尝试在 RecyclerView 中显示我的 emptyView TextView 时,它只会阻止 RecyclerView 正常工作。
我在适配器中创建了以下过滤器:
/**
* 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();
}
};
}
我无法找出为什么我的 emptyView.setVisibility() 有时有效而其他的根本无效。
我的布局如下:
<?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>
为了确保您理解问题,您可以在下面查看问题的一些打印件:
应该发生什么:
第 1 步 - 过滤器:
Filtering
第 2 步 - 编写一个不存在的示例:
Sample that doesn't exist
第 3 步 - 删除错误字符:
The wrong character removed
现在正在发生的事情(不应该发生的):
第 1 步 - 过滤器(工作):
Filtering
第 2 步 - 编写一个不存在的示例(不显示 emptyView):
Not showing the emptyView
第 3 步 - 删除错误字符(不显示样本或粗体字符):
Not showing the sample
如果我按下键盘上的搜索按钮,它就可以工作,但它本应在不按下搜索按钮的情况下工作...
有人可以帮我解决这个问题吗?
我使用了 toast,并且 toast 有效,但是当涉及到在 performFiltering 或需要 set 方法的布局中使用任何类型的 set 方法时,Android 似乎以某种方式失去了它的工作流程。
我尝试了以下实现:
https://alexzh.com/how-to-setemptyview-to-recyclerview/
https://www.reddit.com/r/androiddev/comments/3bjnxi/best_way_to_handle_recyclerview_empty_state/
如何解决这个问题?
我创建了一个扩展 RecyclerView 行为的 EmptyRecyclerView 并添加了一个 updateEmptyView() 方法来验证我的 RecyclerView 中有多少项目并相应地更新视图。我的解决方案基于此 . And another source that helped me solve the problem is this Google Application,它创建了一条我需要的 EmptyView 消息。
感谢 maff91 和具有相同行为的 Google 应用程序。
我正在使用处理具有不同适配器的 RecyclerView 的 Fragment,但是当我尝试在 RecyclerView 中显示我的 emptyView TextView 时,它只会阻止 RecyclerView 正常工作。
我在适配器中创建了以下过滤器:
/**
* 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();
}
};
}
我无法找出为什么我的 emptyView.setVisibility() 有时有效而其他的根本无效。
我的布局如下:
<?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>
为了确保您理解问题,您可以在下面查看问题的一些打印件:
应该发生什么:
第 1 步 - 过滤器: Filtering
第 2 步 - 编写一个不存在的示例: Sample that doesn't exist
第 3 步 - 删除错误字符: The wrong character removed
现在正在发生的事情(不应该发生的):
第 1 步 - 过滤器(工作): Filtering
第 2 步 - 编写一个不存在的示例(不显示 emptyView): Not showing the emptyView
第 3 步 - 删除错误字符(不显示样本或粗体字符): Not showing the sample
如果我按下键盘上的搜索按钮,它就可以工作,但它本应在不按下搜索按钮的情况下工作...
有人可以帮我解决这个问题吗?
我使用了 toast,并且 toast 有效,但是当涉及到在 performFiltering 或需要 set 方法的布局中使用任何类型的 set 方法时,Android 似乎以某种方式失去了它的工作流程。
我尝试了以下实现:
https://alexzh.com/how-to-setemptyview-to-recyclerview/
https://www.reddit.com/r/androiddev/comments/3bjnxi/best_way_to_handle_recyclerview_empty_state/
如何解决这个问题?
我创建了一个扩展 RecyclerView 行为的 EmptyRecyclerView 并添加了一个 updateEmptyView() 方法来验证我的 RecyclerView 中有多少项目并相应地更新视图。我的解决方案基于此
感谢 maff91 和具有相同行为的 Google 应用程序。