SetSelection en un spinner se bloquea cuando layout_weight se asigna a spinner

He hecho un experimento simplificado para identificar dónde estoy teniendo este problema. Era una pregunta larga con mucho código anterior. Ahora he guardado un código pequeño y simple:

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_spinner_test); Spinner spin1 = (Spinner) findViewById(R.id.spin1); spin1.setAdapter(new ProfileSpinnerAdapter(this, R.array.feet)); spin1.setSelection(0); //does not crash spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1); //it crashes //it crashes for any value greater than 0 and less than array length. 

Este es el error:

 java.lang.NullPointerException: Attempt to read from field 'int android.view.ViewGroup$LayoutParams.width' on a null object reference at android.widget.TextView.checkForRelayout(TextView.java:6830) at android.widget.TextView.onRtlPropertiesChanged(TextView.java:8948) at android.view.View.resolveRtlPropertiesIfNeeded(View.java:13118) at android.view.View.measure(View.java:17557) at android.widget.Spinner.setUpChild(Spinner.java:657) at android.widget.Spinner.makeView(Spinner.java:610) at android.widget.Spinner.getBaseline(Spinner.java:456) at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1294) at android.widget.LinearLayout.onMeasure(LinearLayout.java:615) at android.view.View.measure(View.java:17562) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at android.view.View.measure(View.java:17562) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) at android.view.View.measure(View.java:17562) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5536) at android.widget.FrameLayout.onMeasure(FrameLayout.java:436) at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2871) at android.view.View.measure(View.java:17562) at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015) at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5891) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) at android.view.Choreographer.doCallbacks(Choreographer.java:580) at android.view.Choreographer.doFrame(Choreographer.java:550) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5294) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699) 

Este error viene porque he establecido el layout_width = 0dp. Pero al mismo tiempo layout_weight = 1. NOTA : El hilandero está correctamente inflado cuando setSelection (0). Así que el problema no es con la inflación directa.

Aquí está el xml:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context="in.jiyofit.the_app.SpinnerTestActivity"> <Spinner android:id="@+id/spin1" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" /> 

El código completo funciona perfectamente si layout_width = Cualquier dp no igual o match_parent o wrap_content mientras no hay layout_weight .

Pero con el mismo diseño anterior el código siguiente funciona correctamente sin bloqueos:

  Spinner spin1 = (Spinner) findViewById(R.id.spin1); ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.feet, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spin1.setAdapter(adapter); spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1); 

Por lo tanto, puedo concluir que hay algún problema con la clase ProfileSpinnerAdapter que he hecho, lo que entra en conflicto con layout_weight = 1 y width = 0dp

Aquí está el adaptador:

 public class ProfileSpinnerAdapter extends BaseAdapter { String[] array; Context ctx; public ProfileSpinnerAdapter(Context context, int arrayID) { this.ctx = context; this.array = ctx.getResources().getStringArray(arrayID); } @Override public int getCount() { return array.length; } @Override public Object getItem(int position) { return array[position]; } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { TextView textView = new TextView(ctx); textView.setText(array[position]); textView.setTextSize(16); if(array[position].length() > 6){ Typeface hindiFont = Typeface.createFromAsset(ctx.getAssets(),"fonts/mfdev010.ttf"); textView.setTextSize(22); textView.setTypeface(hindiFont); } if(position == 0){ textView.setTextColor(ContextCompat.getColor(ctx, R.color.primaryText)); } return textView; } @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { TextView textView = new TextView(ctx); textView.setText(array[position]); textView.setTextSize(16); textView.setPadding(0, 5, 0, 0); if(array[position].length() > 6){ Typeface hindiFont = Typeface.createFromAsset(ctx.getAssets(),"fonts/mfdev010.ttf"); textView.setTextSize(22); textView.setTypeface(hindiFont); textView.setPadding(10,5,10,5); } textView.setBackgroundColor(ContextCompat.getColor(ctx, R.color.white)); textView.setTextColor(ContextCompat.getColor(ctx, R.color.primaryText)); textView.setGravity(Gravity.CENTER); /* the adapter fills the number of elements based in the getCount so either getCount returns value conditionally for an array of different size in getDropDownView or the requisite value at position is hidden */ if(position == 0){ textView.setVisibility(View.GONE); textView.setHeight(0); } return textView; } } 

La causa del error está en el adaptador. No da error si spinner width = 100dp y sólo da error cuando el atributo layout_weight se pone en la ruleta

He resuelto el problema con poner el TextView en un grupo de diseño de forma programática:

 @Override public View getView(int position, View arg1, ViewGroup arg2){ ... // without this rtl the app crashes on lollipop devices with shawnlin number-picker RelativeLayout rtlContainer = new RelativeLayout(mContext); rtlContainer.addView(textView); return rtlContainer; } 

También interesante, que el accidente ocurrió después de que incluyo esta biblioteca numberpicker a mi proyecto. No sé cuál es la coherencia entre la biblioteca y el accidente, pero si lo excluyo, el accidente desaparece de nuevo.

También encontré un problema android relacionado. La razón proporcionada es: Dado que TextView no está envuelto en un ViewGroup, cualquier interacción con la vista hace que la aplicación se bloquee con una excepción de puntero nulo. TextView está intentando medir algunos ViewGroup.LayoutParams.

 spin1.setSelection(0); //does not crash spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1); 

cambiar a

 spin1.setSelection(0, true); spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1, true); 

También tuve esta pregunta y resuelto

Establecer android:layout_width="0dp" a TextView y dar layout_weight a ella como por su requisito.

Creo que esto sucede porque como usted está utilizando el peso para esta disposición lineal y también se establece el ancho de TextView

Android: layout_width = "80dp"

Fije la anchura 0dp de TextView y dé el peso.

Android: layout_width = "0dp"

Androide: layout_weight = "0.25" // según el peso total

Tienes que dar peso por separado para todas las sub vistas de esta disposición lineal y también establecer la anchura 0dp para todas las vistas secundarias.

Espero que esto funcione para usted …

Como solución alternativa, en lugar de layout_weight, he utilizado percentrelativelayout. La biblioteca se puede incluir agregando compile 'com.android.support:percent:23.2.0' a las dependencias en build.gradle.

Aquí es cómo lo usé. Funciona exactamente como yo quiero. * He eliminado los atributos xml innecesarios.

  <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="80dp" android:layout_height="wrap_content" android:text="@string/aprofile_height" /> <android.support.percent.PercentRelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <Spinner android:id="@+id/aprofile_dd_feet" app:layout_widthPercent="50%" android:layout_height="wrap_content" /> <Spinner android:id="@+id/aprofile_dd_inches" app:layout_widthPercent="50%" android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:layout_alignParentRight="true"/> </android.support.percent.PercentRelativeLayout> </LinearLayout> 
  • ¿Qué tipo de objeto Spinner.getItemAtPosition (...) devuelve?
  • ¿Cómo hago para que el estado "deshabilitado" de un Spinner esté deshabilitado?
  • ¿Por qué mi hilandero es tan horrible?
  • Altura del menú desplegable de Spinner para coincidir con el padre
  • Android Appcompat v21 - utilizar el estilo antiguo del hilandero
  • Android Spinner con diferentes diseños para "drop down state" y "closed state"?
  • Spinner: infla la excepción al usar AppCompat
  • Spinner onItemSelected llamado erróneamente (sin acción del usuario)
  • Obtener Android para tratar HTML Seleccionar como Android Spinner?
  • ¿Cómo crear una lista desplegable?
  • Cómo ajustar contenido de texto en ActionBarSherlock spinner de navegación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.