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)。

当我在 tab1tab2 之间切换时,没有任何变化。 但是如果我切换到 tab3 然后回到我的 tab1 - RRV 终于出现了。 而且它不依赖于页面的内容。 RRV 的外观仅受 tab3 中的 return 影响。

我不明白原因。 我重新检查了我的 TabViewPagerTabAdapterFragments。 一切正常。 没有多余的东西,我认为可能会影响这一点。

第二题:

当我通过 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);
        }*/
    }
});