RealmRecyclerView 仅在选项卡之间切换后更新。空视图出现延迟
RealmRecyclerView updates only after switching between tabs. Empty view appears with delay
有 ViewPager
共 3 页 (FragmentPagerAdapter
)
RealmRecyclerView
在第一页。
当Realm
为空时"No items"消息和"Add"按钮表示。没关系。
因此,我已将我的第一个对象添加到 Realm
。
EmptyView 仍然在这里,尽管我希望看到 RealmRecyclerView
(RRV)。
当我在 tab1
和 tab2
之间切换时,没有任何变化。
但是如果我切换到 tab3
然后回到我的 tab1
- RRV
终于出现了。
而且它不依赖于页面的内容。
RRV
的外观仅受 tab3
中的 return 影响。
我不明白原因。
我重新检查了我的 TabViewPager
、TabAdapter
和 Fragments
。
一切正常。
没有多余的东西,我认为可能会影响这一点。
第二题:
当我通过 SearchView
的查询过滤我的 RRV
时,小部件 EmptyView 出现延迟。
例如:如果有“12345”项,只有在查询为“1234567”而不是预期的“123456”时才会出现 EmptyView..
Аt 第一个不匹配的 RRV
仍然可见,尽管它是空的。
并且仅当两个或多个字符 RRV
的差异消失时。
删除多余的字符也不能给出正确的表示。
我认为这两种情况都有一个原因。
你能指出错误吗?
FirstFragment.java
public class FirstFragment extends Fragment {
Realm realm;
RecyclerView realmRecyclerView;
FirstAdapter adapter;
TextView emptyText;
Button buttonAdd;
public FirstFragment () {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_first, container, false);
realm = Realm.getDefaultInstance();
realmRecyclerView = fragmentView.findViewById(R.id.recyclerView_first);
RealmResults<Object> results = realm.where(Object.class).findAll();
emptyText = fragmentView.findViewById(R.id.tv_no_data);
buttonAdd = fragmentView.findViewById(R.id.button_add);
setUpRealmRecyclerView();
initButtonAdd();
if (!results.isEmpty()) {
realmRecyclerView.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
buttonAdd.setVisibility(View.GONE);
} else {
realmRecyclerView.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.VISIBLE);
}
return fragmentView;
}
private void setUpRealmRecyclerView() {
adapter = new FirstAdapter(realm, realm.where(Object.class).findAll());
realmRecyclerView.setHasFixedSize(true);
realmRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
realmRecyclerView.setAdapter(adapter);
FirstTouchHelper callback = new FirstTouchHelper(realm);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(realmRecyclerView);
}
@Override
public void onDestroyView() {
super.onDestroyView();
realmRecyclerView.setAdapter(null);
realm.close();
}
private void initButtonAdd() {
//create new object dialog
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.actionbar_menu, menu);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
searchView.setSearchableInfo(searchableInfo);
searchView.setIconifiedByDefault(true);
EditText editTextSearch = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
adapter.getFilter().filter(editable);
if (adapter.getItemCount()==0) {
realmRecyclerView.setVisibility(View.GONE);
buttonAdd.setVisibility(View.VISIBLE);
} else {
realmRecyclerView.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.GONE);
}
}
});
super.onCreateOptionsMenu(menu, inflater);
}
}
RRV 适配器:
public class FirstAdapter
extends RealmRecyclerViewAdapter<Object, RecyclerView.ViewHolder>
implements Filterable{
Realm realm;
public FirstAdapter(Realm realm, OrderedRealmCollection<Object> data) {
super(data, true, true);
this.realm = realm;
setHasStableIds(true);
}
@Override
public long getItemId(int index) {
return getItem(index).getId();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rrv_item, parent, false);
ObjectClass holder = new ObjectClass(v);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Object object = getData().get(position);
ObjectClass classHolder = (ObjectClass) holder;
classHolder.name.setText(object.getName());
}
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
RealmQuery<Object> query = realm.where(Object.class);
if (text == null || "".equals(text)) {
updateData(query
.findAll()
.sort("name"));
} else {
updateData(query
.contains("name", text, Case.INSENSITIVE)
.findAll()
.sort("name"));
}
}
public Filter getFilter() {
ObjectFilter filter = new ObjectFilter(this);
return filter;
}
private class ObjectFilter
extends Filter {
private final FirstAdapter adapter;
private ObjectFilter(FirstAdapter adapter) {
super();
this.adapter = adapter;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filterResults(constraint.toString());
}
}
private class ObjectClass
extends RecyclerView.ViewHolder {
TextView name;
private ObjectClass(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name_text_view);
}
}
}
之所以点击第 3 个标签然后点击第 1 个标签 "reloads" 并正确显示您的视图是因为 offscreenPageLimit
默认为 1
,所以当 tab 1
被选中时,tab 3
被销毁,当被选中tab 3
时,tab 1
被销毁。
因此您的视图已重新创建,因此它会正确显示。
但是要解决您的问题,您应该使用 RealmChangeListener 在 Realm 写入时接收通知。
public class FirstFragment extends Fragment {
Realm realm;
RealmResults<Object> results;
RealmChangeListener<RealmResults<Object>> changeListener = new RealmChangeListener<RealmResults<Object>>() {
@Override
public void onChange(RealmResults<Object> results) {
if (!results.isEmpty()) {
realmRecyclerView.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
buttonAdd.setVisibility(View.GONE);
} else {
realmRecyclerView.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.VISIBLE);
}
}
};
RecyclerView realmRecyclerView;
PickProductAdapter adapter;
TextView emptyText;
Button buttonAdd;
public FirstFragment () {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_first, container, false);
realm = Realm.getDefaultInstance();
realmRecyclerView = fragmentView.findViewById(R.id.recyclerView_first);
results = realm.where(Object.class).findAllAsync();
results.addChangeListener(changeListener);
emptyText = fragmentView.findViewById(R.id.tv_no_data);
buttonAdd = fragmentView.findViewById(R.id.button_add);
setUpRealmRecyclerView();
initButtonAdd();
return fragmentView;
}
private void setUpRealmRecyclerView() {
adapter = new PickProductAdapter(realm, results);
realmRecyclerView.setHasFixedSize(true);
realmRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
realmRecyclerView.setAdapter(adapter);
FirstTouchHelper callback = new FirstTouchHelper(realm);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(realmRecyclerView);
}
@Override
public void onDestroyView() {
super.onDestroyView();
results.removeAllChangeListeners();
realmRecyclerView.setAdapter(null);
realm.close();
}
private void initButtonAdd() {
//create new object dialog
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.first_actionbar_menu, menu);
// set searchview
}
}
编辑:您的空视图不更新的原因是因为它独立于适配器中的内容,因此您需要添加一些可以在过滤器处于活动状态时调用的回调方法。
public class FirstFragment extends Fragment {
...
public void updateData(RealmResults<Object> results) {
if(this.results != null && this.results.isValid()) {
this.results.removeAllChangeListeners();
}
this.results = results;
results.addChangeListener(changeListener);
}
和
public class FirstAdapter
extends RealmRecyclerViewAdapter<Object, RecyclerView.ViewHolder>
implements Filterable{
FirstFragment firstFragment; // could be interface or somethin'
Realm realm;
public FirstAdapter(FirstFragment firstFragment, Realm realm, OrderedRealmCollection<Object> data) {
...
...
@Override
public void updateData(OrderedRealmCollection<Object> collection) {
super.updateData(collection);
firstFragment.updateData((RealmResults<Object>)collection);
}
编辑:
还有
RealmQuery<Object> query = realm.where(Object.class);
if (text == null || "".equals(text)) {
updateData(query
.sort("name")
.findAllAsync());
} else {
updateData(query
.contains("name", text, Case.INSENSITIVE)
.sort("name")
.findAllAsync());
}
和
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
adapter.getFilter().filter(editable);
// this should be in `onChange()`
/*if (adapter.getItemCount()==0) {
realmRecyclerView.setVisibility(View.GONE);
buttonAdd.setVisibility(View.VISIBLE);
} else {
realmRecyclerView.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.GONE);
}*/
}
});
有 ViewPager
共 3 页 (FragmentPagerAdapter
)
RealmRecyclerView
在第一页。
当Realm
为空时"No items"消息和"Add"按钮表示。没关系。
因此,我已将我的第一个对象添加到 Realm
。
EmptyView 仍然在这里,尽管我希望看到 RealmRecyclerView
(RRV)。
当我在 tab1
和 tab2
之间切换时,没有任何变化。
但是如果我切换到 tab3
然后回到我的 tab1
- RRV
终于出现了。
而且它不依赖于页面的内容。
RRV
的外观仅受 tab3
中的 return 影响。
我不明白原因。
我重新检查了我的 TabViewPager
、TabAdapter
和 Fragments
。
一切正常。
没有多余的东西,我认为可能会影响这一点。
第二题:
当我通过 SearchView
的查询过滤我的 RRV
时,小部件 EmptyView 出现延迟。
例如:如果有“12345”项,只有在查询为“1234567”而不是预期的“123456”时才会出现 EmptyView..
Аt 第一个不匹配的 RRV
仍然可见,尽管它是空的。
并且仅当两个或多个字符 RRV
的差异消失时。
删除多余的字符也不能给出正确的表示。
我认为这两种情况都有一个原因。 你能指出错误吗?
FirstFragment.java
public class FirstFragment extends Fragment {
Realm realm;
RecyclerView realmRecyclerView;
FirstAdapter adapter;
TextView emptyText;
Button buttonAdd;
public FirstFragment () {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_first, container, false);
realm = Realm.getDefaultInstance();
realmRecyclerView = fragmentView.findViewById(R.id.recyclerView_first);
RealmResults<Object> results = realm.where(Object.class).findAll();
emptyText = fragmentView.findViewById(R.id.tv_no_data);
buttonAdd = fragmentView.findViewById(R.id.button_add);
setUpRealmRecyclerView();
initButtonAdd();
if (!results.isEmpty()) {
realmRecyclerView.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
buttonAdd.setVisibility(View.GONE);
} else {
realmRecyclerView.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.VISIBLE);
}
return fragmentView;
}
private void setUpRealmRecyclerView() {
adapter = new FirstAdapter(realm, realm.where(Object.class).findAll());
realmRecyclerView.setHasFixedSize(true);
realmRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
realmRecyclerView.setAdapter(adapter);
FirstTouchHelper callback = new FirstTouchHelper(realm);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(realmRecyclerView);
}
@Override
public void onDestroyView() {
super.onDestroyView();
realmRecyclerView.setAdapter(null);
realm.close();
}
private void initButtonAdd() {
//create new object dialog
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.actionbar_menu, menu);
SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
final SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchableInfo searchableInfo = searchManager.getSearchableInfo(getActivity().getComponentName());
searchView.setSearchableInfo(searchableInfo);
searchView.setIconifiedByDefault(true);
EditText editTextSearch = (EditText) searchView.findViewById(android.support.v7.appcompat.R.id.search_src_text);
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
adapter.getFilter().filter(editable);
if (adapter.getItemCount()==0) {
realmRecyclerView.setVisibility(View.GONE);
buttonAdd.setVisibility(View.VISIBLE);
} else {
realmRecyclerView.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.GONE);
}
}
});
super.onCreateOptionsMenu(menu, inflater);
}
}
RRV 适配器:
public class FirstAdapter
extends RealmRecyclerViewAdapter<Object, RecyclerView.ViewHolder>
implements Filterable{
Realm realm;
public FirstAdapter(Realm realm, OrderedRealmCollection<Object> data) {
super(data, true, true);
this.realm = realm;
setHasStableIds(true);
}
@Override
public long getItemId(int index) {
return getItem(index).getId();
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rrv_item, parent, false);
ObjectClass holder = new ObjectClass(v);
return holder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Object object = getData().get(position);
ObjectClass classHolder = (ObjectClass) holder;
classHolder.name.setText(object.getName());
}
public void filterResults(String text) {
text = text == null ? null : text.toLowerCase().trim();
RealmQuery<Object> query = realm.where(Object.class);
if (text == null || "".equals(text)) {
updateData(query
.findAll()
.sort("name"));
} else {
updateData(query
.contains("name", text, Case.INSENSITIVE)
.findAll()
.sort("name"));
}
}
public Filter getFilter() {
ObjectFilter filter = new ObjectFilter(this);
return filter;
}
private class ObjectFilter
extends Filter {
private final FirstAdapter adapter;
private ObjectFilter(FirstAdapter adapter) {
super();
this.adapter = adapter;
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
return new FilterResults();
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.filterResults(constraint.toString());
}
}
private class ObjectClass
extends RecyclerView.ViewHolder {
TextView name;
private ObjectClass(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name_text_view);
}
}
}
之所以点击第 3 个标签然后点击第 1 个标签 "reloads" 并正确显示您的视图是因为 offscreenPageLimit
默认为 1
,所以当 tab 1
被选中时,tab 3
被销毁,当被选中tab 3
时,tab 1
被销毁。
因此您的视图已重新创建,因此它会正确显示。
但是要解决您的问题,您应该使用 RealmChangeListener 在 Realm 写入时接收通知。
public class FirstFragment extends Fragment {
Realm realm;
RealmResults<Object> results;
RealmChangeListener<RealmResults<Object>> changeListener = new RealmChangeListener<RealmResults<Object>>() {
@Override
public void onChange(RealmResults<Object> results) {
if (!results.isEmpty()) {
realmRecyclerView.setVisibility(View.VISIBLE);
emptyText.setVisibility(View.GONE);
buttonAdd.setVisibility(View.GONE);
} else {
realmRecyclerView.setVisibility(View.GONE);
emptyText.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.VISIBLE);
}
}
};
RecyclerView realmRecyclerView;
PickProductAdapter adapter;
TextView emptyText;
Button buttonAdd;
public FirstFragment () {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View fragmentView = inflater.inflate(R.layout.fragment_first, container, false);
realm = Realm.getDefaultInstance();
realmRecyclerView = fragmentView.findViewById(R.id.recyclerView_first);
results = realm.where(Object.class).findAllAsync();
results.addChangeListener(changeListener);
emptyText = fragmentView.findViewById(R.id.tv_no_data);
buttonAdd = fragmentView.findViewById(R.id.button_add);
setUpRealmRecyclerView();
initButtonAdd();
return fragmentView;
}
private void setUpRealmRecyclerView() {
adapter = new PickProductAdapter(realm, results);
realmRecyclerView.setHasFixedSize(true);
realmRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
realmRecyclerView.setAdapter(adapter);
FirstTouchHelper callback = new FirstTouchHelper(realm);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(realmRecyclerView);
}
@Override
public void onDestroyView() {
super.onDestroyView();
results.removeAllChangeListeners();
realmRecyclerView.setAdapter(null);
realm.close();
}
private void initButtonAdd() {
//create new object dialog
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
inflater.inflate(R.menu.first_actionbar_menu, menu);
// set searchview
}
}
编辑:您的空视图不更新的原因是因为它独立于适配器中的内容,因此您需要添加一些可以在过滤器处于活动状态时调用的回调方法。
public class FirstFragment extends Fragment {
...
public void updateData(RealmResults<Object> results) {
if(this.results != null && this.results.isValid()) {
this.results.removeAllChangeListeners();
}
this.results = results;
results.addChangeListener(changeListener);
}
和
public class FirstAdapter
extends RealmRecyclerViewAdapter<Object, RecyclerView.ViewHolder>
implements Filterable{
FirstFragment firstFragment; // could be interface or somethin'
Realm realm;
public FirstAdapter(FirstFragment firstFragment, Realm realm, OrderedRealmCollection<Object> data) {
...
...
@Override
public void updateData(OrderedRealmCollection<Object> collection) {
super.updateData(collection);
firstFragment.updateData((RealmResults<Object>)collection);
}
编辑:
还有
RealmQuery<Object> query = realm.where(Object.class);
if (text == null || "".equals(text)) {
updateData(query
.sort("name")
.findAllAsync());
} else {
updateData(query
.contains("name", text, Case.INSENSITIVE)
.sort("name")
.findAllAsync());
}
和
editTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
adapter.getFilter().filter(editable);
// this should be in `onChange()`
/*if (adapter.getItemCount()==0) {
realmRecyclerView.setVisibility(View.GONE);
buttonAdd.setVisibility(View.VISIBLE);
} else {
realmRecyclerView.setVisibility(View.VISIBLE);
buttonAdd.setVisibility(View.GONE);
}*/
}
});