2015-07-07 29 views
7

Desidero popolare un cassetto di navigazione sottoscrivendo un Observable che ottiene i dati da un db e al termine, notifica l'utente (utilizzando RxJava). Ho fatto qualcosa di simile con la Subscriber che è una classe che si estende Fragment, ma questo è diverso in quanto il Navigation Drawer non è un frammento separato, ma piuttosto, è definito in MainActivity.Sottoscrizione di un cassetto di navigazione a un osservabile

Come si sottoscrive lo Navigation Drawer su 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 
} 

risposta

2

se mDrawerLayout è un'istanza di una classe che implementa Observer di quanto si può gettarlo ai Observer

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

se non implementa l'interfaccia Observer, allora si può crea un nuovo Observer che manipolerà il tuo cassetto di navigazione. (Potrebbe essere necessario dichiarare mDrawerLayout come finale)

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(); 
       } 
      }); 
+0

'mDrawerLayout' è * non * un'istanza di una classe che implementa' Observer'. è 'android.support.v4.widget.DrawerLayout'. –

+0

Quindi si applica la fine della mia risposta: crea un nuovo osservatore che chiama i metodi nel tuo layout del cassetto. – dwursteisen

2

si supponga di voler ricevere gli aggiornamenti dalla classe News.java.

Così si implementano l'interfaccia Observer dal Notizie Classe

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

} 

Ora, si desidera l'utente per ricevere ad aggiornamenti.

public class User implements Observer(){ 

} 

Aggiungerlo a qualsiasi classe in cui si stanno creando variabili di classe utente. Questo codice garantisce che user1, oggetti user2 sono "abbonati" a News Classe

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. 

Aggiungi la logica in cui tutto viene aggiornato. Il metodo update() è fornito dall'interfaccia 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 
} 
+0

Non sono sicuro che questo si applica. Penso di essere chiaro su cosa voglio essere l'Observer -> mDrawerLayout/mDrawerList –

+0

Giusto, ho dimenticato di menzionare un'altra cosa. Quando il tuo db fa la sua cosa, devi chiamare altri due metodi: setChanged(), notifyObservers(). Modifica la risposta –

+0

Inoltri e accetta la risposta se funziona per te. @ AlLelopath –

Problemi correlati