2011-11-02 16 views
8

Así que tengo diferentes diseños para esta actividad.Injectview (Roboguice) no funciona con varios diseños

Y tengo diferentes clases que cada uno abren y hacen su trabajo con un diseño.

Inyecté estas clases en la Actividad a través de @Inject. Todo esto no tiene problema

Pero cuando intento utilizar @InjectView en uno de los controles que están en el diseño no activo, aparece un error.

11-02 19: 17: 31.086: ERROR/Android Runtime (1326): Causado por: java.lang.NullPointerException: No se puede inyectar valor nulo en clase be.baes.notes.View.EditNoteImpl .saveButton cuando el campo no es @Nullable

Este sería entonces el código.

public class EditNoteImpl implements EditNote { 
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener; 
    @Inject SaveNoteClickListener saveNoteClickListener; 
    @Inject Provider<Activity> activity; 
    @InjectView(R.id.saveButton) Button saveButton; 

    /* (non-Javadoc) 
    * @see be.baes.notes.EditNote#activateEditNote() 
    */ 
    @Override 
    public void activateEditNote() 
    { 
     activity.get().setContentView(R.layout.editnote); 

     this.saveButton.setOnClickListener(saveNoteClickListener); 
    } 
} 

Puedo hacer esto.

public class EditNoteImpl implements EditNote { 
    @Inject CancelEditNoteClickListener cancelEditNoteClickListener; 
    @Inject SaveNoteClickListener saveNoteClickListener; 
    @Inject Provider<Activity> activity; 
    private Button saveButton; 

    /* (non-Javadoc) 
    * @see be.baes.notes.EditNote#activateEditNote() 
    */ 
    @Override 
    public void activateEditNote() 
    { 
     activity.get().setContentView(R.layout.editnote); 
     saveButton = (Button)activity.get().findViewById(R.id.saveButton); 

     this.saveButton.setOnClickListener(saveNoteClickListener); 
    } 
} 

¿Hay una mejor manera de hacerlo?

+0

¿Hay alguna razón por la que hacer que el botón @Nullable no sea una opción? –

+0

Lo intenté, pero eso tampoco inyecta el botón. – chrissie1

+0

¿Estás usando RoboGuice 2.0? Esto * puede * funcionar en 2.0 – emmby

Respuesta

4

acabo de comenzar a utilizar roboguice así que alguien con más experiencia podría ser capaz de dar una respuesta mejor, pero esto es lo que he encontrado hasta ahora:

  • En roboguice-1.1.2 (la versión estable actual), @InjectView artículos se inyectan solo cuando se llama setContentView() por primera vez en la Actividad. Como su código llama al setContentView() de forma dinámica desde las clases auxiliares, los elementos inyectados allí no se inyectarán correctamente.

  • En roboguice-2.0b2 (la versión beta actual), hay soporte para múltiples llamadas setContentView() y su código debería funcionar. Sin embargo, las vistas inyectadas todavía están vinculadas a la Actividad de contexto (en lugar de a la clase declarante) por lo que cada @InjectView posiblemente también necesite ser @Nullable en todas las clases auxiliares que compartan la misma Actividad.

Dado que la cuestión aquí parece tener sus raíces en el diseño múltiple (y por lo tanto, múltiples setContentView() llamadas) en una sola actividad, una forma alternativa de hacer lo que quiere es evitar que la siguiente manera:

  • en lugar de tener varios diseños, utilizar un único diseño utilizando la etiqueta <include/> para cargar todos los diseños en una matriz FrameLayout:
<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" > 

    <include layout="@layout/layout1" /> 

    <include layout="@layout/layout2" /> 

    <!-- other layouts... --> 

</FrameLayout> 
  • entonces, en lugar de llamar setContentView(), utilizar un método que va a cambiar el diseño visible en la actividad, algo como esto:
// instead of: activity.setContentView(R.layout.layout1); 
// use: activity.showLayout(R.id.layoutview1); 
public void showLayout(int layoutViewId) { 
    final View view = findViewById(layoutViewId); 
    final ViewGroup root = (ViewGroup) view.getParent(); 
    for (int i = 0; i < root.getChildCount(); i++) { 
     final View v = root.getChildAt(i); 
     v.setVisibility(v == view ? View.VISIBLE : View.GONE); 
    } 
} 

La alternativa anterior debería funcionar para tanto el lanzamiento estable como el beta roboguice. La compensación aquí es que estamos cargando varios diseños al mismo tiempo en lugar de cargar cada uno en diferentes momentos. Parece funcionar bastante bien para mí (aunque podría ser diferente para sus necesidades).

Una cosa que debería destacar es que en la actual página "Upgrading from RoboGuice 1.1 to 2.0", se mencionan los siguientes:

La capacidad de utilizar @InjectView en Vistas (aunque tendrá que llamar RoboGuice.injectMembers() usted mismo, ya que no existe la clase RoboView base y probablemente nunca lo haga).

Parece que esto debería permitir a implementar sus clases auxiliares que se derivan de visualizar y de realizar @InjectView en ellos funcionan mejor (esperemos que no hay necesidad de que sean @Nullable ya que están menos ligados a la actividad). Sin embargo, mirando el código actual, esta característica no parece estar implementada todavía (aunque podría haber estado buscando en el lugar equivocado).

Cuestiones relacionadas