如何在RealmResults为空时可靠地为RecyclerView显示空视图

时间:2017-06-02 00:18:03

标签: android android-fragments realm

我知道有很多关于它的信息,但我还没有找到一个与我的情况相符的信息。

我对一个始终打开的片段有一个recycleview,因此片段基本上不会重新创建。

这是我加载适配器的代码。

    reLoad(); //method shown below
    mRecycler.setAdapter(new SolicitationAdapter(myRealm.where(SolicitationDatabase.class).findAllAsync()));

这就是我提出的逻辑:

public void reLoad() {
    if (!myRealm.where(SolicitationDatabase.class).findAll().isEmpty()) {
        mNothingHere.setVisibility(View.GONE);
        mRecycler.setVisibility(View.VISIBLE);
    } else {
        mNothingHere.setVisibility(View.VISIBLE);
        mRecycler.setVisibility(View.GONE);
    }
}

用户第一次打开应用时效果很好。

当用户创建记录时,麻烦就开始了,因为片段不会重新创建它自己从不重新加载。

我在用户添加内容后无法重新加载的原因是因为添加新记录的方法是在从不同活动中调用的单身。这意味着当我尝试这样做时,我在声明recycleview和textview时会得到nullpointerexception。

编辑 - 我尝试了什么(从其他地方重新加载视图)

我有一个名为PostHelper的班级,这个班级负责发布新纪录。

这是构造函数:

public PostHelper(Context context, Activity activity) {
    this.mContext = context;
    this.mActivity = activity; //I call this in order to use "findViewById"

这是帖子发生的地方:

public String addSolicitation(File _file, boolean fromQueue) {
//loading view
    TextView nothingHere = (TextView) mActivity.findViewById(R.id.nothing_here);
    RecyclerView recycler = (RecyclerView) mActivity.findViewById(R.id.recycler);
...so on until after the post:
SolicitationAdapter n = new SolicitationAdapter(myRealm.where(SolicitationDatabase.class).findAll());
n.notifyDataSetChanged();

nothingHere.setVisibility(View.GONE);
recycler.setVisibility(View.VISIBLE);

这是堆栈跟踪:

06-01 21:43:37.511 9122-9122/? E/AndroidRuntime: FATAL EXCEPTION: main
                                             Process: com.example.ga.realm3, PID: 9122
                                             io.reactivex.exceptions.OnErrorNotImplementedException: Attempt to invoke virtual method 'void android.widget.TextView.setVisibility(int)' on a null object reference

编辑2 - 我使用以下命令加载PostHelper类:

mPostHelper = new PostHelper(this, PostSolicitationActivity.this);

2 个答案:

答案 0 :(得分:3)

您应该确保SolicitationAdapterRealmRecyclerViewAdapter,如下所示:

public class SolicitationAdapter extends RealmRecyclerViewAdapter<SolicitationDatabase, SolicitationViewHolder> {
     public SolicitationAdapter(OrderedRealmCollection<SolicitationDatabase> results) {
         super(results, true);
     }
 ...
}

然后您需要做的是将RealmResults作为字段引用放在Activity中:

public class PostSoliticiationActivity extends AppCompatActivity {
     RealmResults<Solicitation> results;
     Realm realm;
     RealmChangeListener<RealmResults<Solicitiation> realmChangeListener = (results) -> {
         if(results.isLoaded() && results.isValid()) {
            if(results.isEmpty()) {
                mNothingHere.setVisibility(View.GONE);
                mRecycler.setVisibility(View.VISIBLE);
            } else {
                mNothingHere.setVisibility(View.VISIBLE);
                mRecycler.setVisibility(View.GONE);
            }
         }
     }

     SolicitationAdapter adapter;

     @Override
     protected void onCreate(Bundle bundle) {
         super.onCreate(bundle);
         setContentView(R.layout.soliticiation_activity);
         // bind views 
         realm = Realm.getDefaultInstance();
         results = realm.where(SolicitationDatabase.class).findAllSortedAsync("id");
                                // .sort("id").findAllAsync(); in 4.3.0+
         results.addChangeListener(realmChangeListener);
         adapter = new SoliticiationAdapter(results);
         mRecycler.setAdapter(adapter);
         // layout manager as well
     }

     @Override
     public void onDestroy() {
         results.removeChangeListener(realmChangeListener);
         realm.close();
         super.onDestroy();
     }
}

所以你不需要的东西:

1。)reLoad()方法

2。)onPostAdded回调

3。)PostActionListener

只要您在事务中将SoliticiationDatabase添加到Realm,它就可以在不手动同步ui的情况下工作。

答案 1 :(得分:0)

如果我理解正确,您希望在其他地方发生操作时在其他视图中收到通知。

这样做的方法通常是接口。

public class PostHelper {

    // Define these
    public interface PostActionListener {
        void onPostAdded();
    }

    private PostActionListener postListener;

    public void setPostActionListener(PostActionListener listener) throws ClassCastException {
        this.postListener = (PostActionListener) context;
    }

    public PostHelper(Context context) {
        this.mContext = context;

        // Cast the passed context as a listener
        if (mContext instanceof PostActionListener) {
            this.postListener = (PostActionListener) mContext;
        }
    }

    public String addSolicitation(File _file, boolean fromQueue) {
        // Do something

        // Callback to the UI to update
        if (this.postListener != null) {
            this.postListener.onPostAdded();
        }
    }

然后,在您的初始活动中

public class YourActivity extends AppCompatActivity 
    implements PostHandler.PostActionListener {

    // ... fields

    @Override
    public void onPostAdded() {
        reLoad();
    }

    public void reLoad() {
        boolean emptyList = myRealm.where(SolicitationDatabase.class).findAll().isEmpty();
        mNothingHere.setVisibility(emptyList ? View.VISIBLE : View.GONE);
        mRecycler.setVisibility(emptyList ? View.GONE : View.VISIBLE);
    }

    @Override
    public void onCreate(Bundle b) {
        ...

        mPostHelper = new PostHelper(this);
    }

然而,因为您使用的是Realm,并且确实没有您需要的数据&#34;返回&#34;在这里,您可以简单地让Android Activity生命周期为您刷新数据。