android - 在回收站视图中过滤结果为 0 时显示空状态
问题描述
我得到了searchView
我用来过滤recyclerView的这个。因此,当某些搜索查询没有结果时,我想textView
通过将其可见性设置为VISIBLE
. 所以在 searchView 监听器中,我这样做:
@Override
public boolean onQueryTextChange(String s) {
adapter.getFilter().filter(s);
if (adapter.getItemCount()<=0){
emptyStateConatiner.setVisibility(View.VISIBLE);
}
else emptyStateConatiner.setVisibility(View.GONE);
return false;
}
但这并不像我期望的那样工作,因为当我输入不存在的搜索查询时,它首先显示为空recyclerView
,然后只有在此之后,如果我在该查询中输入额外的字母,我就会得到emptyStateContainer
显示。
有谁知道是什么导致了这种行为?
这是适配器代码:package com.app.userprofile;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.Filter;
import android.widget.Filterable;
import com.app.R;
import com.app.data.webservice.collection_response.Datum;
import java.util.ArrayList;
import java.util.List;
public class BasicUserProfileInfoListAdapter extends RecyclerView.Adapter<BasicUserProfileInfoListAdapter.BasicInfoViewHolder> implements Filterable {
private List<Datum> offeredChoices = new ArrayList<>();
private List<Datum> offeredChoicesFiltered = new ArrayList<>();
private List<Datum> previouslySelectedChoices = new ArrayList<>();
private Resources resources;
private ItemClickCallback clickCallback;
//for single choices
int mCheckedPostion=-1;
public BasicUserProfileInfoListAdapter(ItemClickCallback clickCallback){
this.clickCallback = clickCallback;
}
public void setList(List<Datum> datumList) {
this.offeredChoices = datumList;
this.offeredChoicesFiltered = datumList;
notifyDataSetChanged();
}
@NonNull
@Override
public BasicInfoViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.basic_choice_item, viewGroup, false);
if (resources == null) {
resources = itemView.getContext().getApplicationContext().getResources();
}
return new BasicInfoViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull final BasicInfoViewHolder basicInfoViewHolder, final int i) {
final Datum currentData = offeredChoicesFiltered.get(i);
basicInfoViewHolder.basicInfoCheckBox.setText(currentData.getDesc());
//TODO if currentData equals some choice in previouslySelectedChoices, than mark it checked and add it to selected choices via interface
if (clickCallback instanceof MultipleChoiceItemClickCallback && previouslySelectedChoices!=null && !previouslySelectedChoices.isEmpty()){
boolean shouldCheck=false;
for (Datum data:previouslySelectedChoices) {
if ((data.getId().equals(currentData.getId()))/*&& data.getDesc().equals(currentData.getDesc())*/){
shouldCheck=true;
clickCallback.onRowClicked(currentData,ChoiceClickType.ADD_CHOICE);
}
}
basicInfoViewHolder.basicInfoCheckBox.setChecked(shouldCheck);
}
if (clickCallback instanceof SingleChoiceItemClickCallback){
basicInfoViewHolder.basicInfoCheckBox.setChecked(i == mCheckedPostion);
if (previouslySelectedChoices!=null && !previouslySelectedChoices.isEmpty()){
boolean shouldCheck=false;
for (Datum data:previouslySelectedChoices) {
if ((data.getId().equals(currentData.getId()))/*&& data.getDesc().equals(currentData.getDesc())*/){
shouldCheck=true;
previouslySelectedChoices.clear();//so it wouldn't reselect on notifyDataSetChanged()
clickCallback.onRowClicked(currentData,ChoiceClickType.ADD_SINGLE_CHOICE);
}
}
if (shouldCheck) mCheckedPostion = i;
//Log.d("slctdwf","choice: "+ currentData.getDesc()+", position: "+mCheckedPostion);
basicInfoViewHolder.basicInfoCheckBox.setChecked(shouldCheck);
}
}
}
@Override
public int getItemCount() {
if (offeredChoicesFiltered!=null) return offeredChoicesFiltered.size();
else return 0;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return position;
}
private Datum getCurrentRowInfo(int position) {
return offeredChoicesFiltered.get(position);
}
public void setPreviouslySelectedChoices (List<Datum> data) {
if (data!=null && !data.isEmpty()){
this.previouslySelectedChoices = data;
notifyDataSetChanged();
}
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String charString = constraint.toString();
List<Datum> filteredList = new ArrayList<>();
if (charString.isEmpty()) {
filteredList = offeredChoices;
} else {
for (Datum choice : offeredChoices) {
if (choice.getDesc().toLowerCase().contains(charString.toLowerCase())) {
filteredList.add(choice);
}
}
}
FilterResults filterResults = new FilterResults();
filterResults.count = filteredList.size();
filterResults.values = filteredList;
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
offeredChoicesFiltered = (ArrayList<Datum>) results.values;
notifyDataSetChanged();
}
};
}
class BasicInfoViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private CheckBox basicInfoCheckBox;
private CardView entireRowCardView;
BasicInfoViewHolder(View itemView) {
super(itemView);
basicInfoCheckBox = itemView.findViewById(R.id.choice_checkbox);
entireRowCardView = itemView.findViewById(R.id.entire_row_basic_choice);
entireRowCardView.setOnClickListener(this);
if (resources == null) {
resources = itemView.getResources();
}
}
@Override
public void onClick(View v) {
Datum currentChoice = getCurrentRowInfo(getAdapterPosition());
int position = getAdapterPosition();
if (clickCallback instanceof MultipleChoiceItemClickCallback){
if (basicInfoCheckBox.isChecked()){
basicInfoCheckBox.setChecked(false);
clickCallback.onRowClicked(currentChoice, ChoiceClickType.REMOVE_CHOICE);
}
else if (!basicInfoCheckBox.isChecked()){
basicInfoCheckBox.setChecked(true);
clickCallback.onRowClicked(currentChoice, ChoiceClickType.ADD_CHOICE);
}
}
if (clickCallback instanceof SingleChoiceItemClickCallback){
if (position == mCheckedPostion) {
mCheckedPostion = -1;
//Log.d("slctdwf","removed single choice: "+ currentChoice.getDesc());
clickCallback.onRowClicked(currentChoice, ChoiceClickType.REMOVE_SINGLE_CHOICE);
basicInfoCheckBox.setChecked(false);
notifyDataSetChanged();
} else {
mCheckedPostion = position;
//Log.d("slctdwf","added single choice: "+ currentChoice.getDesc());
clickCallback.onRowClicked(currentChoice, ChoiceClickType.ADD_SINGLE_CHOICE);
basicInfoCheckBox.setChecked(true);
notifyDataSetChanged();
}
}
}
}
public interface ItemClickCallback {
void onRowClicked(Datum choiceData, ChoiceClickType choiceClickType);
}
public interface MultipleChoiceItemClickCallback extends ItemClickCallback{
void onRowClicked(Datum choiceData, ChoiceClickType choiceClickType);
}
public interface SingleChoiceItemClickCallback extends ItemClickCallback {
void onRowClicked(Datum choiceData, ChoiceClickType choiceClickType);
}
public enum ChoiceClickType {
ADD_CHOICE,
REMOVE_CHOICE,
ADD_SINGLE_CHOICE,
REMOVE_SINGLE_CHOICE
}
}
解决方案
我认为 onQueryChanged 回调是控制空状态的错误位置。您可以使用DataSetObserver (文档)来收听列表更改,因此您始终拥有正确的 size() 匹配项。
注册一个观察者,当此适配器使用的数据发生更改时调用该观察者。
adapter.registerDataSetObserver(new DataSetObserver() {
@Override public void onChanged() {
super.onChanged();
showEmptyStateIfAdapterIsEmpty();
// access adapter's dataset size here or in that method
}
});
推荐阅读
- java - 带概率的字符串随机生成器
- c# - 附加信息:向 https://pilot.Test.in/autoTest.asmx 发出 HTTP 请求时出错
- java - Java Fx - 以编程方式添加样式以标记而不覆盖
- javascript - 为什么在逗号运算符中抛出异常不会停止对其他操作数的评估?
- azure - 使用 Terraform 在 Azure 中分配角色
- sql - 如何计算连续值并在计数 3 后根据需要更改状态
- javascript - 连续的 Material-UI Snackbars(使用 React-Redux)
- php - 如何在laravel中对特定列进行分页?
- javascript - WebSocket - 失败:WebSocket 握手期间出错:缺少“连接”标头
- reporting-services - SSRS 图表数据集分组过滤器值