suk*_*uku 5 android android-layout android-spinner android-layout-weight
我做了一个简化的实验来确定我遇到这个问题的地方.这是一个很长的问题,前面有很多代码.现在我保留了一个简单的小代码:
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.
Run Code Online (Sandbox Code Playgroud)
这是错误:
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)
Run Code Online (Sandbox Code Playgroud)
出现此错误是因为我已设置layout_width = 0dp.但同时layout_weight = 1. 注意:当setSelection(0)时,微调器正确膨胀.所以问题不在于直接通货膨胀.
这是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" />
Run Code Online (Sandbox Code Playgroud)
如果layout_width =任何非零dp或match_parent或wrap_content 而没有layout_weight,则整个代码可以正常工作.
但是使用上面相同的布局,以下代码可以正常工作,没有崩溃:
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);
Run Code Online (Sandbox Code Playgroud)
因此,我可以得出结论,我所做的ProfileSpinnerAdapter类存在一些问题,它与layout_weight = 1和width = 0dp冲突
这是适配器:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
错误的原因在于适配器.如果spinner width = 100dp,它不会出错,并且只有在layout_weight属性放在微调器上时才会出错
小智 6
spin1.setSelection(0); //does not crash
spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1);
Run Code Online (Sandbox Code Playgroud)
改成
spin1.setSelection(0, true);
spin1.setSelection(getResources().getStringArray(R.array.feet).length - 1, true);
Run Code Online (Sandbox Code Playgroud)
我也有这个问题并解决了