【问题标题】:Subscribe a Navigation Drawer to an Observable订阅导航抽屉到可观察对象
【发布时间】:2015-07-07 21:17:35
【问题描述】:

我想通过订阅Observable 来填充导航抽屉,该Observable 从数据库获取数据,完成后通知订阅者(使用RxJava)。我做了类似的事情,Subscriber 是一个扩展Fragment 的类,但不同之处在于导航抽屉不是一个单独的片段,而是在 MainActivity 中定义。

如何将Navigation Drawer 订阅到Observable

MainActivity.java

private DrawerLayout mDrawerLayout;
private ListView mDrawerList;

@Override
public void onStart() {                                                                                                                       mLoadAndStoreDataObservable = Observable.create(
    super.onStart();                                                                                                                              new Observable.OnSubscribe<String>() {

    // fragment creation code was here

    // populates a String[] myStringArray for Navigation Drawer                                                                                                                                                                  permitsSQLiteManager.addLogLine(mActivity, logString);
    if (!skipRestfulServiceCall) {
        getDataFromRestfulService();                                                                                                                      }
    }                                                                                                                                                     catch (Exception e) {
    else {  // get data from SQLite                                                                                                                           Log.e("loadAndStoreData  ", "Exception: " + e.getMessage());
        getDataFromSQLite();                                                                                                                                  mProgressDialog.dismiss();
    }                                                                                                                                                     }
                                                                                                                                                      }
    mTitle = mDrawerTitle = getTitle();                                                                                                           }
    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);                                                                              .subscribeOn(Schedulers.io())
    mDrawerList = (ListView) findViewById(R.id.left_drawer);                                                                                      .observeOn(AndroidSchedulers.mainThread())
                                                                                                                                                  .subscribe(mDrawerLayout); // parameter was a Fragment
    mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

    mDrawerList.setAdapter(new ArrayAdapter<String>(this,  R.layout.drawer_list_item, myStringArray));
    mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

    // enable ActionBar app icon to behave as action to toggle nav drawer
    getActionBar().setDisplayHomeAsUpEnabled(true);
    getActionBar().setHomeButtonEnabled(true);

    mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open,R.string.drawer_close
    ) {
        public void onDrawerClosed(View view) {
            getActionBar().setTitle(mTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }

        public void onDrawerOpened(View drawerView) {
            getActionBar().setTitle(mDrawerTitle);
            invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
        }
    };
    mDrawerLayout.setDrawerListener(mDrawerToggle);
}

private void getDataFromRestfulService() {

    <get data>


    // implement RxJava-Observable/Subscriber
    mLoadAndStoreDataObservable = Observable.create(
            new Observable.OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {

                    try {
                        Utilities.loadAndStoreData(mActivity);
                        subscriber.onNext("Utilities.loadAndStoreData Done");
                        //subscriber.onCompleted();
                        Log.e("MainActivity.onCreate()", "subscriber.onNext(\"Utilities.loadAndStoreData Done\")");

                        String logString = "MainActivity.onCreate() - subscriber.onNext(Utilities.loadAndStoreData Done)";
                        Log.e(TAG, logString);
                        PermitsSQLiteManager permitsSQLiteManager = PermitsSQLiteManager.getInstance();
                        permitsSQLiteManager.addLogLine(mActivity, logString);

                        mProgressDialog.dismiss();
                    }
                    catch (Exception e) {
                        Log.e("loadAndStoreData  ", "Exception: " + e.getMessage());
                        subscriber.onError(e);
                        mProgressDialog.dismiss();
                    }
                }
            }
    )
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(mDrawerLayout); // compile error // suscriber was a Fragment, but no longer
}

【问题讨论】:

    标签: android navigation-drawer rx-java observable


    【解决方案1】:

    如果 mDrawerLayout 是实现 Observer 的类的实例,则可以将其转换为 Observer

    NavigationDrawer mDrawerLayout = ...
    yourObservable.subscribe((Observer)mDrawerLayout);
    

    如果它没有实现Observer 接口,那么您可以创建一个新的Observer 来操作您的导航抽屉。 (您可能需要将mDrawerLayout 声明为final)

    final NavigationDrawer  mDrawerLayout = ...
    yourObservable.subscribe(new Observer<String>() {
                    @Override
                    public void onCompleted() {
                        // on completed
                    }
    
                    @Override
                    public void onError(Throwable throwable) {
                        // on error
                    }
    
                    @Override
                    public void onNext(String people) {
                            mDrawerLayout.doSomething(); 
                    }
                });
    

    【讨论】:

    • mDrawerLayout 不是实现Observer 的类的实例。它是android.support.v4.widget.DrawerLayout
    • 然后我的回答结束了:创建一个新的观察者,它在你的抽屉布局上调用方法。
    【解决方案2】:

    假设您想接收来自 News.java 类的更新。

    所以你从你的新闻类中实现观察者接口

    News implements Observable{
    
       public void publishNews(){
           String newNews = "newNews";
           //Now notify Users that new news is available by calling the following
           // two methods
           setChanged();
           notifyObservers(); // This will call the subscribers and notify them 
                              // that there is a change.
       }
    
    }
    

    现在,您希望用户接收更新。

    public class User implements Observer(){
    
    }
    

    将此添加到您正在创建用户类变量的任何类中。此代码确保 user1、user2 对象被“订阅”到 News Class

    News news = new News();
    User user1 = new User();
    User user2 = new User();
    news.add(user1); // You have to instantiate News object to user the add method
    news.add(user2); // from Observable interface.
    

    在任何内容更新时添加逻辑。 update() 方法由 Observer 提供 界面。

    @Overrride
    public void update(Observable, Object){
    // This gets called after notifyObservers() in the Observable class
    // Whatever you want to do after Observable calls notifyObservers, goes here
    }
    

    【讨论】:

    • 我不确定这是否适用。我想我很清楚我想成为观察者 -> mDrawerLayout/mDrawerList
    • 对了,我忘了再说一件事。当你的数据库做它的事情时,你需要调用另外两个方法——setChanged()、notifyObservers()。将编辑答案
    • 如果它适合您,请支持并接受答案。 @AllLelopath
    • 我没有看到您的更改如何解决我原来评论中的问题
    • 将subscriber.oncompleted 代码放在类中重写的onUpdate() 方法中。
    猜你喜欢
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多