2017-06-02 48 views
2

据我所知,有很多关于它的信息,但是我还没有找到与我的案例相匹配的信息。如何仅在RealmResults为空时为RecyclerView可靠地显示空视图

我有一个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); 
+1

请显示堆栈跟踪和其他代码 –

+0

@ cricket_007感谢您指出。我用所需的信息编辑了它。你能帮我吗? – Rosenberg

+0

如果你正在更新领域“从不同的活动”,那么你不应该传递另一个活动的完整引用那里...另外,一个活动是一个上下文,所以你只是重复参数...我不能真正遵循你添加的代码,否则,调用'findViewById'不会像那样工作。你有没有试过只传递TextView和RecyclerView?假设你真的需要他们? –

回答

3

你应该确保SolicitationAdapterRealmRecyclerViewAdapter,像这样:

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

然后你需要做的是,你把RealmResults为您的活动现场参考:

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到领域的交易,系统会而无需手动同步UI的所有工作。

+1

我正要测试它,顺便说一句,适配器实际上是你自己做的(Realm book by example)!你总是帮助我,我真的很感激。 – Rosenberg

+0

这是一个合理的策略。但是,唯一不让它工作的是我无法绑定PostSolicitationActivity上的视图。它们属于HistoryFragment。 [Stacktrace here](https://gist.github.com/madd86/9fea4cf7981e81da1e0f84141cdd4775) – Rosenberg

+1

Nevermind在HistoryFragment上做了它,它工作。谢谢。 – Rosenberg

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); 
    } 

然而,因为使用的是境界,实在是没有数据,你需要“回归”在这里,你可以简单地让Android Activity生命周期会为您刷新数据。

+1

不是正确的答案。 – EpicPandaForce

+0

好吧,我在底部添加了免责声明:)我基本上手动实现'RealmChangeListener' –