Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subscribe a Navigation Drawer to an Observable

I want to populate a Navigation Drawer by subscribing to an Observable which gets data from a db and when done, notifies the subscriber (using RxJava). I've done something similar with the Subscriber being a class that extends Fragment, but this is different in that the Navigation Drawer is not a separate fragment, but rather, is defined in MainActivity.

How do I subscribe the Navigation Drawer to the 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
}
like image 397
Al Lelopath Avatar asked Jul 07 '15 21:07

Al Lelopath


People also ask

Which view is used to add the navigation drawer to an app?

Figure 3. An open drawer displaying a navigation menu. The drawer icon is displayed on all top-level destinations that use a DrawerLayout . To add a navigation drawer, first declare a DrawerLayout as the root view.


2 Answers

if mDrawerLayout is an instance of a class which implement Observer than you can cast it to Observer

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

if it does not implement Observer interface, then you can create a new Observer that will manipulate your navigation drawer. (You may need to declare mDrawerLayout as 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(); 
                }
            });
like image 52
dwursteisen Avatar answered Sep 29 '22 18:09

dwursteisen


Suppose you want to receive updates from the News.java class.

So you implement Observer interface from your News Class

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.
   }

}

Now, you want User to receive to updates.

public class User implements Observer(){

}

Add this to any class where you are creating User class variables. This code ensures that user1, user2 objects are "subscribed" to 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.

Add the logic when anything gets updated. update() method is provided by Observer interface.

@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
}
like image 24
ARK Avatar answered Sep 29 '22 19:09

ARK