2014-09-10 3 views
2

Я написал эту функцию:Android: ArrayIndexOutOfBounds Exception на addRule в LayoutParams

private void SetNewsBackButton(Boolean visible) 
{ 
    LinearLayout backButton = (LinearLayout)findViewById(R.id.backButton); 
    TextView headerText = (TextView)findViewById(R.id.headerText); 
    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)headerText.getLayoutParams(); 
    if (visible) 
    { 
     backButton.setVisibility(View.VISIBLE); 
     params.addRule(RelativeLayout.END_OF, R.id.backButton); 
    } else { 
     backButton.setVisibility(View.INVISIBLE); 
     params.addRule(RelativeLayout.END_OF, 0); 
    } 
} 

Функция должен сделать LinearLayout видимым или невидимым и выравнивать текстовое поле к нему, если они видны, не совпадают, когда невидимое.

Моей проблема: Приложение падает с

09-10 12:48:32.260 16663-16663/nidhoegger.org.nfansde W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41a9c600) 
09-10 12:48:32.270 16663-16663/nidhoegger.org.nfansde E/AndroidRuntime﹕ FATAL EXCEPTION: main 
java.lang.ArrayIndexOutOfBoundsException: length=16; index=19 
     at android.widget.RelativeLayout$LayoutParams.addRule(RelativeLayout.java:1222) 
     at nidhoegger.org.nfansde.NewsList.SetNewsBackButton(NewsList.java:147) 
     at nidhoegger.org.nfansde.NewsList.ReadNews(NewsList.java:182) 
     at nidhoegger.org.nfansde.NewsList$1.onItemClick(NewsList.java:103) 
     at android.widget.AdapterView.performItemClick(AdapterView.java:298) 
     at android.widget.AbsListView.performItemClick(AbsListView.java:1199) 
     at android.widget.ListView.performItemClick(ListView.java:4444) 
     at android.widget.AbsListView$PerformClick.run(AbsListView.java:3067) 
     at android.widget.AbsListView$1.run(AbsListView.java:3753) 
     at android.os.Handler.handleCallback(Handler.java:615) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:155) 
     at android.app.ActivityThread.main(ActivityThread.java:5536) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:511) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1074) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:841) 
     at dalvik.system.NativeStart.main(Native Method) 

И я не могу понять, почему. Что я здесь не так понял?

Heres активность (stipped до минимальной версии):

public class NewsList extends Activity { 

    ListView newsHeaderList; 
    LinearLayout backButton; 
    TextView headerText; 

    public NewsList() 
    { 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_news_list); 

     backButton = (LinearLayout)findViewById(R.id.backButton); 
     headerText = (TextView)findViewById(R.id.headerText); 

     newsHeaderList.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       ReadNews(position); 
      } 
     }); 
    } 

    private void SetNewsBackButton(Boolean visible) 
    { 
     RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)headerText.getLayoutParams(); 
     if (visible) 
     { 
      backButton.setVisibility(View.VISIBLE); 
      params.addRule(RelativeLayout.END_OF, R.id.backButton); 
     } else { 
      backButton.setVisibility(View.INVISIBLE); 
      params.addRule(RelativeLayout.END_OF, 0); 
     } 
    } 

    public void ReadNews(Integer guid) 
    { 
     SetNewsBackButton(true); 
    } 
} 

Heres просмотров, XML код (также stipped вниз):

<RelativeLayout 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:padding="0dp" 
tools:context=".NewsList"> 

    <LinearLayout 
     android:orientation="horizontal" 
     android:layout_width="wrap_content" 
     android:layout_height="75dp" 
     android:id="@+id/backButton"> 

     <ImageView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/imageView" 
      android:src="@drawable/headerbackbutton" 
      android:layout_gravity="center_vertical" /> 

     <TextView 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:textAppearance="?android:attr/textAppearanceLarge" 
      android:text="News" 
      android:id="@+id/textView" 
      android:layout_gravity="center_vertical" 
      android:textColor="@color/colorheadertext" 
      android:layout_marginLeft="-15dp" /> 
    </LinearLayout> 

    <ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="75dp" 
     android:id="@+id/imageView2" 
     android:src="@drawable/nfansheader" 
     android:layout_alignParentTop="true" 
     android:layout_alignParentRight="true" /> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textAppearance="?android:attr/textAppearanceLarge" 
     android:text="NFans.de - News" 
     android:id="@+id/headerText" 
     android:layout_toStartOf="@+id/imageView2" 
     android:textColor="@color/colorheadertext" 
     android:textStyle="bold" 
     android:layout_centerVertical="true" 
     android:layout_toEndOf="@+id/backButton" 
     android:maxLines="1" 
     android:singleLine="true" 
     android:layout_toLeftOf="@+id/imageView2" 
     android:layout_toRightOf="@+id/backButton" 
     android:layout_marginLeft="5dp" 
     android:layout_marginRight="-20dp" /> 
</RelativeLayout> 
+0

Проверьте, 'вызванного by' линии в LogCat. Что такое номер строки '147'? – Aniruddha

+0

попробуйте всегда искать в onCreate() вместо настраиваемого метода. –

+0

вы вызываете этот метод из любого цикла? –

ответ

7

Эти правила вводятся с уровнем API 17. Если вы запускаете свой код на более старом API, он сработает с этим ArrayIndexOutOfBoundsException.

/** 
* Rule that aligns a child's end edge with another child's start edge. 
*/ 
public static final int START_OF     = 16; 
/** 
* Rule that aligns a child's start edge with another child's end edge. 
*/ 
public static final int END_OF     = 17; 
/** 
* Rule that aligns a child's start edge with another child's start edge. 
*/ 
public static final int ALIGN_START    = 18; 
/** 
* Rule that aligns a child's end edge with another child's end edge. 
*/ 
public static final int ALIGN_END    = 19; 
/** 
* Rule that aligns the child's start edge with its RelativeLayout 
* parent's start edge. 
*/ 
public static final int ALIGN_PARENT_START  = 20; 
/** 
* Rule that aligns the child's end edge with its RelativeLayout 
* parent's end edge. 
*/ 
public static final int ALIGN_PARENT_END   = 21; 

Вы можете обойти эту проблему с помощью RIGHT вместо END и LEFT вместо START для тех старых API. И вместо removeRule(X) вы можете позвонить addRule(X, 0), который очищает правило.

Пример:

 final boolean hasSdk17 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1; 
     if (hasSdk17) { 
      plateParams.removeRule(RelativeLayout.ABOVE); 
      buttonsParams.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.myView); 
      buttonsParams.addRule(RelativeLayout.ALIGN_END, R.id.myView); 
      buttonsParams.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM); 
     } else { 
      plateParams.addRule(RelativeLayout.ABOVE, 0); 
      buttonsParams.addRule(RelativeLayout.ALIGN_BOTTOM, R.id.myView); 
      buttonsParams.addRule(RelativeLayout.ALIGN_RIGHT, R.id.myView); 
      buttonsParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0); 
     } 
Смежные вопросы