0 votos

Hola, ahora me he encontrado con un problema que no sé porque me está pasando esto, he creado un proyecto para hacer pruebas, con solo un Activity con un botón que muestra un Fragment.
En este Fragmen muestro un Exposed Drop-Down Menu, que una vez que he visto que funciona bien, este código lo paso a otro proyecto.
 
Pues bien, este segundo proyecto tiene un menú horizontal con 7 pestañas, os describo el comportamiento que tiene el menu…. en la pestaña 4 he puesto el Drop-Down, pero cuando inicio por primera vez la aplicación, y pulso en la pestaña 5, me muestra el contenido de la pestaña 7 (la última).

Si quito el código del Drop-Down y pongo un simple TextView, todos los menús funcionan bien.

Este es el código:

Fragment.java

String[] items =  {"Material","Design","Components","Android","5.0 Lollipop"};

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

	View rootView  = inflater.inflate( R.layout.f_esta, container, false );


	AutoCompleteTextView autoCompleteTxt = rootView.findViewById(R.id.auto_complete_txt);
      ArrayAdapter<String> adapterItems = new ArrayAdapter<String>(getActivity(),R.layout.items_list,items);
      autoCompleteTxt.setAdapter(adapterItems);

retrum rootView;

}

f_esta.xml

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clickable="false">

    <com.google.android.material.textfield.TextInputLayout
        style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        android:hint="@string/nombres"
        app:boxBackgroundColor="@color/Snow">

        <AutoCompleteTextView
            android:id="@+id/auto_complete_txt"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="none" />
    </com.google.android.material.textfield.TextInputLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

items_list.xml

<TextView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_margin="5dp"
        android:ellipsize="end"
        android:maxLines="1"
        android:layout_centerHorizontal="true"
        android:textSize="20sp"
        android:fontFamily="@font/arno"
        app:fontFamily="@font/arno"
        android:textStyle="bold|italic"
        app:drawableLeftCompat="@drawable/icon_estacion_5"
        android:background="@drawable/esquinas_redondas_3"
        android:textAppearance="?attr/textAppearanceSubtitle1">

</TextView>

La aplicación no se detiene ni muestra ningún mensaje de error, y en alguna ocasión cuando he cambiado el código, y la aplicación se ha detenido, en el Logcat ha mostrado este error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.AutoCompleteTextView.setAdapter(android.widget.ListAdapter)' on a null object reference

Pero ahora mismo con el código que he puesto, no muestra ningun mensaje de error, pero tiene ese comportamiento
Porque en el otro proyecto funciona bien, y al pasar el código aquí, ya no funciona bien el menú ?
 
Agradecería vuestra ayuda.

por en Android

1 Respuesta

+1 voto
Mejor respuesta
Parece que no te está encontrando algún recurso, en tu código no veo nada raro ¿En qué línea te da el error? Se me ocurre que en el Activity que engloba al Fragment, en el "setContentView" exista el recurso que estás llamando.
por
seleccionada por

Hola Ramón, ahora no me muestra ese error, en otras pruebas que he estado haciendo, el error la marcaba en la tercera linea que te muestra aqui (autoCompleteTxt.setAdapter(adapterItems); :

AutoCompleteTextView autoCompleteTxt = rootView.findViewById(R.id.auto_complete_txt);
ArrayAdapter<String> adapterItems = new ArrayAdapter<String>(getActivity(),R.layout.items_list,items);
autoCompleteTxt.setAdapter(adapterItems);

 

este es el codigo que tengo en el activity_main.xml 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FAFAFA"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/my_Toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:paddingLeft="0dp"
        android:paddingRight="0dp"
        app:contentInsetLeft="0dp"
        app:contentInsetStart="0dp"
        app:contentInsetStartWithNavigation="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:popupTheme="@style/AppTheme.FondoMenu" />


    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="90dp"
        android:layout_below="@id/my_Toolbar"
        android:background="@color/colorPrimary"
        android:elevation="6dp"
        app:tabIconTint="@drawable/color_icono_selector"
        app:tabIndicatorColor="#FA0707"
        app:tabIndicatorFullWidth="false"
        app:tabIndicatorHeight="6dp"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="#FA0707"
        app:tabTextAppearance="@style/CustomTextAppearanceTab"
        app:tabTextColor="#FFFFFF"
        app:titleTextColor="#FFFFFF" />


    <View
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:background="@color/Gris_1"
        app:layout_constraintBottom_toBottomOf="@+id/tabLayout" />


    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewPager2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/tabLayout" />

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

    </FrameLayout>


</RelativeLayout>

 

El caso es que si al iniciar la aplicación y en lugar de entrar la primera vez en la pestaña 5, entro en la pestaña 4 donde esta el Drop-Down, luego puedo entrar en cualquier otra y ya me muestra bien el contenido de cada pestaña/fragment

 

 

Tiene pinta de ser porque cuando inicias ciertas pestañas carga el layout con el id existente y cuando inicias en otras no se carga el layout. Fíjate si cuando estás en las pestañas que falla antes pueda cargarse el layout "f_esta.xml" que contiene al id "auto_complete_txt", quizás no se llame en esas pestañas a ese fragment.

Los fragmen o pestañas todos los muestro de la misma forma.

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.f_esta, container, false);

    return rootView;

}

otro que se muestra igual, el unico en el xml es que muestra un texto <TextView>


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.f_tele, container, false);

    return rootView;

}

Como compruebo eso que dices, aunque no llego a entender muy bien lo que quieres decir con que quizás no se llame en esas pestañas a ese fragment ?

Como te comento, las otras pestañas muestran un simple Texto de prueba, si la pestaña que contiene el Drop-Down lo quito, y en su lugar pongo un <TextView> para que muestre un texto, todo funciona bien.


He ejecutado la aplicación en modo Debug, y he puesto un punto de interrupción, no sé si se llama loop, para que al pasar el cursor por ahí se detenga, lo he puesto en todas en el código "View rootView = inflater.inflate(R.layout......." y solo se ha detenido en la primera pestaña que es cuando se muestra su contenido, luego he pulsado otra pestaña 5 y ha mostrado el contenido de la última, pero ni se ha detenido el cursor en esos puntos que he puesto, ni en la pestaña 5 ni en la última.

 

 

Me refiero que en las pestañas que no te da error se carga el layout y en las pestañas que sí te da error no se carga el layout y por tanto no encuentra el id, que es el que está dando error (en tu ejemplo quizás en R.layout.f_tele cargas todo y en R.layout.f_esta quizás no, o viceversa, puede que incluso sea por un layout emebebido en otro que es cuando se complica como en tu ejemplo que tienes un item_list que queda dentro de otro layout; en alguno de estos hay alguno que no se inicia y por tanto al llamar al id da error, esto lo mejor es hacerse un esquema). Esto es un error común cuando se usan menús o pestañas, ya que cada pestaña tiene su layout y en desarrollo si se llama al id que es de otro layout es cuando da el error.
O sea, que porque tengo un Layaut y dentro de este muestro otro, es cuando se produce este problema, no me digas que esto no se puede hacer, porque si no, no voy a poder utilizar el Drop-Down, hay alguna forma de solucionarlo? dices que es mejor hacer un esquema, esto como se hace

Me gustaría ver como solucionarlo porque si no puedo me tira para atras otras obciones que tengo en mente hacer como entrada de datos en una base de datos con varios Drop-Down.

El caso es que si entro a esa pestaña la primera ver, luego no hay problemas con las demas, pero si entro a otra pestaña no me muestra su layaut.
Poder se puede hacer, lo único que te está fallando es que no carga el layout en cierta pestaña.

Lo que quiero decir con esquema es para tener claro qué layout carga primero y cuál después en cada una de las pestañas, así localizar el punto en el que no está cargando el que falla el id, para tener todo el recorrido de carga de layouts cuando tenemos este tipo de problemas, localizar dónde y corregirlo.

Sugeriría que hicieras una app básica con dos pestañas para ver el error, entrando en una pestaña debería funcionar y al entrar en la otra debería de fallar (reiniciando el proceso de la aplicación), para que sea más fácil verlo y corregirlo sobre esta app de prueba y luego pasar la correción a la app final
Con dos pestañas ?

Te pregunto esto porque he empezado hacer un nuevo proyecto con dos pestañas, pero creo que se tendria que hacer por lo menos con 4, porque cuando inicia la aplicación se muestra la pestaña 1, en la pestaña dos pongo el DropDown, cuando se produce el fallo es cuando se pulsa en la pestaña 3 que lo que hace es mostrar  el contenido la pestaña 4.

Porque si creo el proyecto con dos pestañas, donde pongo el DropDown en la primera para que se muestre nada mas iniciar la aplicación, o en la segunda pestaña, de esta forma no creo que se muestre ese falo, no?

O pongo el DropDown en la segunda pestaña?
Me refería a hacer el proyecto mínimo para reproducir el fallo y ver más fácilmente dónde está el error.
Pues ahora ya no sé qué descargar para sacar el error, porque funciona bien, he creado un menú con 2 pestañas, los dos menús se muestran bien, luego he creado uno con 3, luego con cuatro, así hasta tener las 7 pestañas que tengo ahora, y siguen funcionando bien, en cada pestaña que pulso se muestra su contenido.

Y en el proyecto principal no funciona bien la primera vez que muestro los menus a partir de la pestaña donde se encuentra el DropDown, una vez que muestro la pestaña donde esta el DropDown ya puedo pulsar cualquier menu que se muestra bien.

Hay una cosa que no creo que tenga que ver, pero te lo voy a comentar, en el proyecto de pruebas los estilos/style estan en velues>themes, y los otros en values>styles, por lo demas es todo igual
Vale Ramón, ya creo que se donde puede estar el error, en el menú de Opciones o Overflow, he desactivado este código y ahora el menú o pestañas funcionan todas bien.

Lo que no es es que tiene que ver este menú, con el otro, o en que puede influir para que no funcione bien el menú horizontal, alguna idea de porque al quitar el menú funcione bien ?
Me alegro que se solucionara.

Los menús pueden cambiar los layouts disponibles, algunas veces pasa algo parecido al rotar el móvil y sobre todo con fragments. Por lo menos en lo que me he encontrado suele solucionarse recolocando los elementos de los layouts e intentando asegurar que los ids necesarios estén siempre estén disponibles.

He cambiado algunos nombres que tenia puesto en ventanas de alerta dentro de las opciones del menú Overflow, que no creo esto no que tenga que influir, también he desactivado algunas opciones que tenía en Styles como transiciones y animaciones, y parece que de momento funciona, no me digas porque, ya que esto que he desactivado, lo tengo en otros proyectos con pruebas que he realizado y funcionan.
Lo que si he visto es que ha cambiado el fondo del menú de Opciones, o mas bien los márgenes, superior/inferior:

 

Y no se como poner el mismo color del fondo, o igual con un color diferente, sabes porque ahora se muestra esos márgenes de un color diferente ?

Como te digo parece que funciona, salvo eso que he notado del color del fondo, pero por dejar bien el código a que te refieres con lo de asegurar que los ids necesarios estén siempre estén disponibles ?

Lo del color del fondo es jugar con los estilos hasta conseguir el deseado, en principio te debería de funcionar cambiando en los estilos del menú con:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    ...
    <item name="android:itemBackground">@color/mi_color</item>
    ...
</style>

Por cierto, para evitar que ocurra el error con los ids, es mejor y más sencillo utilizar binding (en vez de findById). Tienes más información y ejemplos en: https://developer.android.com/topic/libraries/view-binding

Encontré el problema por el que se muestran esas líneas blancas, yo tenía creado un estilo para ese menú de la siguiente forma, que por lo que había visto parecía que era el correcto, pero parece que no:

<style name="AppTheme.FondoMenu" parent="android:Widget.Holo.Light.ListPopupWindow">

ahora lo he cambiado por el que has puesto, y han desaparecido esas lineas, 

<style name="AppTheme.FondoMenu" parent="Theme.AppCompat.Light.DarkActionBar">

Lo que comentas sobre utilizar Binding en lugar de findById, no me queda muy claro, por lo que he visto es mejor como tu dices el utilizar binding, intentare buscar ejemplos para ver su funcionamiento, y poder enterarme mejor, porque lo que encuentro esta en ingles y las traducciones no son muy buenas, así que agradeceria un ejemplo para ver como aplicarlo, pero que no sea para kotlin que parece que este codigo esta creado para kolint ya que los ejemplos que veo estan en kotlin

 

 

Bueno Ramon, el tema del Binding creo que ya lo tengo un poco controlado, me estaba liando con darle el nombre de java, y era del xml.
En la página de Android se puede cambiar el idioma al Español y sale explicado de una manera bastante sencilla.

Como bien comentas, la gracia de binding lo que hace es tomar el id del xml y crea un objeto de java variables cuyos nombres son los ids puestos en el xml.

Me alegro que ya te funcionara todo :)