FindViewByID devuelve null

En primer lugar: sí, he leído todos los demás temas sobre este tema. Y no sólo los de este sitio … (ya ves, estoy un poco frustrado)

La mayoría de ellos vienen con el consejo de usar android:id lugar de simplemente id en el archivo XML. Yo si.

De otros, aprendí que View.findViewById funciona diferente de Activity.findViewById . Yo también lo manejé.

En mi location_layout.xml , uso:

 <FrameLayout .... > <some.package.MyCustomView ... /> <LinearLayout ... > <TextView ... android:id="@+id/txtLat" /> ... </LinearLayout> </FrameLayout> 

En mi Actividad:

 ... setContentView( R.layout.location_layout ); 

Y en mi clase de vista personalizada:

 ... TextView tv = (TextView) findViewById( R.id.txtLat ); 

Que devuelve null . Haciendo esto, mi actividad funciona bien. Así que tal vez es debido a las diferencias Activity.findViewById y View.findViewById . Así que almacené el contexto pasado al constructor de vista de aduanas localmente y probé:

 ... TextView tv = (TextView) ((Activity) context).findViewById( R.id.txtLat ); 

Que también devolvió null .

Luego, cambié mi vista personalizada para extender ViewGroup vez de View y cambiar el location_layout.xml para dejar que el TextView ser un hijo directo de mi vista personalizada, de modo que el View.findViewById debería funcionar como se supone. Sorpresa: no resolvió nada.

Entonces, ¿qué demonios estoy haciendo mal?

Apreciaré cualquier comentario.

Que devuelve nulo

Posiblemente porque lo está llamando demasiado pronto. Espere hasta que onFinishInflate() . A continuación se muestra un proyecto de ejemplo que muestra una View personalizada que accede a su contenido.

Posiblemente, está llamando a findViewById antes de llamar a setContentView ? Si ese es el caso, intente llamar a findViewById DESPUÉS de llamar a setContentView

Asegúrese de que no tiene varias versiones de su diseño para diferentes densidades de pantalla. Me encontré con este problema una vez al agregar un nuevo id a un diseño existente, pero se olvidó de actualizar la versión hdpi. Si se olvida de actualizar todas las versiones del archivo de diseño, funcionará para algunas densidades de pantalla, pero no para otras.

En mi caso, tuve 2 actividades en mi proyecto, main.xml y main2.xml . Desde el principio, main2 era una copia de main , y todo funcionó bien, hasta que agregué el nuevo TextView a main2 , por lo que el R.id.textview1 hizo disponible para el resto de la aplicación. Entonces traté de buscar por llamada estándar:

 TextView tv = (TextView) findViewById( R.id.textview1 ); 

Y siempre fue nulo. Resultó que en el constructor onCreate estaba instanciando no main2 , pero el otro. Tuve:

 setContentView(R.layout.main); 

en lugar de

 setContentView(R.layout.main2); 

Me di cuenta de esto después de llegar aquí, en el sitio.

Junto a las causas clásicas, mencionadas en otra parte:

  • Asegúrese de haber llamado a setContentView() antes de findViewById()
  • Asegúrese de que el id que desea está en la vista o el diseño que ha asignado a setContentView()
  • Asegúrese de que el id no se duplique accidentalmente en diferentes diseños

Hay uno que he encontrado para las vistas personalizadas en los diseños estándar, que va en contra de la documentación:

En teoría, puede crear una vista personalizada y añadirla a un diseño ( consulte aquí ). Sin embargo, he encontrado que en tales situaciones, a veces el atributo id funciona para todas las vistas en el diseño excepto las personalizadas. La solución que uso es:

  1. Reemplace cada vista personalizada con un FrameLayout con las mismas propiedades de diseño que desea que tenga la vista personalizada. Dale un id adecuado, por ejemplo, frame_for_custom_view .
  2. En onCreate :

     setContentView(R.layout.my_layout); FrameView fv = findViewById(R.id.frame_for_custom_layout); MyCustomView cv = new MyCustomView(context); fv.addView(cv); 

    Que pone la vista personalizada en el marco.

  @Override protected void onStart() { // use findViewById() here instead of in onCreate() } 

FindViewById puede ser nulo si llama al constructor súper incorrecto en una vista personalizada. La etiqueta ID es parte de attrs, por lo que si ignora attrs, elimina la ID.

Esto estaría mal

 public CameraSurfaceView(Context context, AttributeSet attrs) { super(context); } 

Esto es correcto

 public CameraSurfaceView(Context context, AttributeSet attrs) { super(context,attrs); } 

Una respuesta para aquellos que utilizan ExpandableListView y se ejecutan en esta pregunta basada en su título.

Tuve este error intentando trabajar con TextViews en mis vistas de niño y grupo como parte de una implementación de ExpandableListView.

Puede utilizar algo como lo siguiente en sus implementaciones de los métodos getChildView () y getGroupView ().

  if (convertView == null) { LayoutInflater inflater = (LayoutInflater) myContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = inflater.inflate(R.layout.child_layout, null); } 

Encontré esto aquí .

Soy bastante nuevo en Android / Eclipse, por error agregué las cosas de la interfaz de usuario a activity_main.xml lugar de fragment_main.xml . Me tomó algunas horas para averiguar eso …

En mi caso particular, estaba intentando agregar un pie de página a un ListView. La siguiente llamada en onCreate () devolvió null.

 TextView footerView = (TextView) placesListView.findViewById(R.id.footer); 

Cambiar esto para inflar la vista de pie de página en lugar de encontrarla por ID resolvió este problema.

 View footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.footer_view, null, false); 

FWIW, no veo que alguien haya resuelto esto de la misma manera que yo necesitaba. No hay quejas en tiempo de compilación, pero estaba recibiendo una vista nula en tiempo de ejecución, y llamando a las cosas en el orden correcto. Es decir, findViewById () después de setContentView (). El problema resultó que mi vista se define en content_main.xml, pero en mi activity_main.xml, me faltaba esta declaración:

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

Cuando agregué eso a activity_main.xml, no más NullPointer.

En mi caso, estaba usando ExpandableListView y había establecido android:transcriptMode="normal" . Esto estaba causando que algunos niños en el grupo expandible desaparecieran y yo solía obtener una excepción NULL cuando alguna vez usé desplazarse por la lista.

Para mí tenía dos diseños xml para la misma actividad – uno en modo retrato y uno en el paisaje. Por supuesto que había cambiado el id de un objeto en el xml paisaje, pero se había olvidado de hacer el mismo cambio en la versión retrato. Asegúrese de que si cambia uno hace lo mismo con el otro xml o no obtendrá un error hasta que ejecute / depurarlo y no pueda encontrar el ID que no cambió. Oh errores tontos, ¿por qué me castigas así?

Establezca el contenido de la actividad de un recurso de diseño. Es decir, setContentView(R.layout.basicXml) ;

Yo tuve el mísmo problema. Estaba utilizando una biblioteca de terceros que le permite anular su adaptador para un GridView y especificar su propio diseño para cada celda GridView.

Finalmente me di cuenta de lo que estaba sucediendo. Eclipse seguía utilizando el archivo xml de diseño de la biblioteca para cada celda de GridView, aunque no daba ninguna indicación de ello. En mi adaptador personalizado, indicó que estaba utilizando el recurso xml de mi propio proyecto, aunque en tiempo de ejecución, no lo era.

Así que lo que hice fue asegurarse de que mis diseños e IDs personalizados de xml fueran diferentes de los que todavía estaban sentados en la biblioteca, limpié el proyecto y luego empezó a leer los diseños personalizados correctos que estaban en mi proyecto.

En resumen, tenga cuidado si está reemplazando el adaptador de una biblioteca de otro fabricante y especificando su propio xml de diseño para que el adaptador lo use. Si su diseño dentro de su proyecto tiene el mismo nombre de archivo que en la biblioteca, ¡podría encontrarse con un error muy difícil de encontrar!

Tengo el mismo problema, pero creo que vale la pena compartirlo con ustedes. Si tiene que findViewById en un diseño personalizado, por ejemplo:

 public class MiniPlayerControllBar extends LinearLayout { //code } 

No se puede obtener la vista en constructor. Debería llamar a findViewById después de que la vista se haya inflado. Su es un método que puede anular onFinishInflate

En mi caso había inflado el diseño, pero las opiniones de los niños estaban volviendo nulo. Originalmente tuve esto:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_history); footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false); pbSpinner = (ProgressBar) findViewById(R.id.pbListviewFooter); tvText = (TextView) findViewById(R.id.tvListviewFooter); ... } 

Sin embargo, cuando lo cambié a lo siguiente funcionó:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_history); footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listview_footer, null, false); pbSpinner = (ProgressBar) footerView.findViewById(R.id.pbListviewFooter); tvText = (TextView) footerView.findViewById(R.id.tvListviewFooter); ... } 

La clave era hacer referencia específicamente al diseño ya inflado con el fin de obtener las vistas del niño. Es decir, para agregar footerView :

  • FooterView .findViewById …

En mi experiencia, parece que esto también puede suceder cuando su código se llama después de OnDestroyView (cuando el fragmento está en la pila trasera). Si está actualizando la interfaz de usuario en la entrada de un BroadCastReceiver, debería comprobar si este es el caso .

Además de las soluciones anteriores, asegúrese de que
tools:context=".TakeMultipleImages" en el diseño es el mismo valor en el archivo mainfest.xml:
android:name=".TakeMultipleImages" para el mismo elemento de actividad. Se produce cuando se usa copiar y pegar para crear nueva actividad

INFLAR LA DISPOSICIÓN !! (Que contiene el id)

En mi caso findViewById () devuelto nulo, porque el diseño en el que se escribió el elemento, no se infló …

P.ej. Fragment_layout.xml

 <ListView android:id="@+id/listview"> 

FindViewById (R.id.listview) devolvió null, porque no había hecho inflater.inflate (R.layout.fragment_layout, …, …); antes de eso.

Espero que esta respuesta ayude a algunos de ustedes.

Mi solución era limpiar el proyecto.

Sólo quería tirar mi caso específico aquí. Podría ayudar a alguien en la línea.

Yo estaba usando la directiva en mi interfaz de usuario de Android XML como este:

Vista de los padres:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:tag="home_phone" android:background="@color/colorPrimary"> ... <include layout="@layout/retry_button" android:visibility="gone" /> 

Vista de niño (retry_button):

 <com.foo.RetryButton xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/retry" android:layout_gravity="center" android:orientation="vertical" android:layout_width="100dp" android:layout_height="140dp"> 

.findViewById (R.id.retry) siempre devolverá null. Pero, si moví el ID de la vista secundaria en la etiqueta de inclusión, empezó a funcionar.

Padre fijo:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:tag="home_phone" android:background="@color/colorPrimary"> ... <include layout="@layout/retry_button" android:id="@+id/retry" android:visibility="gone" /> 

Niño fijo:

 <com.foo.RetryButton xmlns:android="http://schemas.android.com/apk/res/android" android:layout_gravity="center" android:orientation="vertical" android:layout_width="100dp" android:layout_height="140dp"> 

FindViewById también puede devolver null si está dentro de un Fragmento. Como se describe aquí: findViewById in Fragment

Debería llamar a getView () para devolver la vista de nivel superior dentro de un fragmento. A continuación, puede encontrar los elementos de diseño (botones, vistas de texto, etc)

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.