Ok, it turns the problem was somewhere else. A little longer down the road, I perform a check for user input, which was setting the basic layout to something else, missing the android:id="@+id/player1"
element. Thanks for the effort and sorry for wasting your time people.
Android: findViewById returns Null under specific user input
Question
I am trying to develop a score-board application for Android. I have defined all the Elements in my XML layout (such as TextFields, buttons etc.) which are hidden by default and set to "visible" when the user is prompted to give the number of players. My problem is the following:
When the user input is higher than 4, the findViewById method throws a NullPointer Exception, even though the View it is pointing at is found and returned just fine with lower input. Here is a sample of the code, where the problem occurs and the onCreate() method before that.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_rssitem_detail);
//Stop rotation screen
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
container = (LinearLayout) findViewById(R.id.container);
// Write everything here inside the container.
DialogFragment newFragment = new StartDialogFragment();
newFragment.show(getSupportFragmentManager(), "startDialog");
}
This method is having if(...) checks for num>0 , num>1 etc subsequently, up to num>7. The problem occurs right after findViewById(R.id.player1).setVisibility(1) ;
if the input is 5 or higher. NOTE: it works fine for all lower inputs.
public void createPlayers(int num){
if(num>0) {
findViewById(R.id.player1).setVisibility(View.VISIBLE) ;
p1= ((Button)findViewById(R.id.Plus1));
p1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
TextView t= ((TextView) findViewById(R.id.score1));
scoreUp(t);
}
});
m1= ((Button)findViewById(R.id.Minus1));
m1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
TextView t= ((TextView) findViewById(R.id.score1));
scoreDown(t);
}
});
}
And here is a sample of my XML layout. This is the part for the elements of ONE player. This code is practically repeated for the creation of 7 more.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/player"
>
<LinearLayout
android:id="@+id/player1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="invisible"
>
<EditText
android:id="@+id/edit1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/player1"
android:layout_weight="0.5"
android:background="@android:color/transparent"
android:textStyle="bold"
android:textSize="14pt"
android:typeface="sans"
android:textColor="@android:color/white"
android:shadowColor="#ffd803"
android:shadowRadius="15.0"
android:layout_gravity="left"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:orientation="horizontal"
>
<Button
android:id="@+id/Plus1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/plusbutton"
android:layout_weight=".125"
/>
<TextView
android:id="@+id/score1"
android:text="@string/score1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".25"
android:gravity="center"
android:textStyle="bold"
android:textSize="14pt"
android:typeface="sans"
android:textColor="#36ff00"
android:shadowColor="#ffd803"
android:shadowRadius="15.0"
/>
<Button
android:id="@+id/Minus1"
android:text="@string/minusbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight=".125"
></Button>
</LinearLayout>
</LinearLayout>
Here is the LogCat Output file:
07-13 18:31:42.913: D/View(26377): onTouchEvent: viewFlags: 0x18244001
07-13 18:31:42.913: D/View(26377): onTouchEvent: isFocusable: true, isFocusableInTouchMode: true, isFocused: true; focusTaken: false
07-13 18:31:45.856: D/View(26377): onTouchEvent: viewFlags: 0x18004001
07-13 18:31:45.856: D/View(26377): onTouchEvent: isFocusable: true, isFocusableInTouchMode: false, isFocused: false; focusTaken: false
07-13 18:31:45.876: I/System.out(26377): this is the given input: 5
07-13 18:31:45.926: D/AndroidRuntime(26377): Shutting down VM
07-13 18:31:45.926: W/dalvikvm(26377): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
07-13 18:31:45.926: E/AndroidRuntime(26377): FATAL EXCEPTION: main
07-13 18:31:45.926: E/AndroidRuntime(26377): java.lang.NullPointerException
07-13 18:31:45.926: E/AndroidRuntime(26377): at keke.koko.PooCounter2.createPlayers(PooCounter2.java:40)
07-13 18:31:45.926: E/AndroidRuntime(26377): at keke.koko.PooCounter2.onDialogPositiveClick(PooCounter2.java:246)
07-13 18:31:45.926: E/AndroidRuntime(26377): at keke.koko.StartDialogFragment$1.onClick(StartDialogFragment.java:28)
07-13 18:31:45.926: E/AndroidRuntime(26377): at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:161)
07-13 18:31:45.926: E/AndroidRuntime(26377): at android.os.Handler.dispatchMessage(Handler.java:99)
07-13 18:31:45.926: E/AndroidRuntime(26377): at android.os.Looper.loop(Looper.java:150)
07-13 18:31:45.926: E/AndroidRuntime(26377): at android.app.ActivityThread.main(ActivityThread.java:4385)
07-13 18:31:45.926: E/AndroidRuntime(26377): at java.lang.reflect.Method.invokeNative(Native Method)
07-13 18:31:45.926: E/AndroidRuntime(26377): at java.lang.reflect.Method.invoke(Method.java:507)
07-13 18:31:45.926: E/AndroidRuntime(26377): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)
07-13 18:31:45.926: E/AndroidRuntime(26377): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
07-13 18:31:45.926: E/AndroidRuntime(26377): at dalvik.system.NativeStart.main(Native Method)
La solution 2
Autres conseils
I think you misunderstand how setVisibility
works. If you want the R.id.player1
to be visible, you will set
findViewById(R.id.player1).setVisibility(View.VISIBLE);
You shouldn't hard-coded it with any integer. Use View.VISIBLE
, View.INVISIBLE
, or View.GONE
.