2013-03-24 2 views
1

Я все еще получаю NPE, но теперь это из моего onCreate(). Когда я удаляю кнопки, все работает нормально.Получение NPE (Отредактировано)

Вот XML (каждая таблица строк из отдельных XMLs):

<TableRow 
     android:id="@+id/tableRow1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginTop="50dp" > 

     <Button 
      android:id="@+id/doneP1" 
      android:layout_width="50dp" 
      android:layout_height="wrap_content" 
      android:text="Done" /> 

     <Button 
      android:id="@+id/resetP1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:text="Reset" /> 

    </TableRow> 

<TableRow 
      android:id="@+id/tableRow1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="50dp" > 

      <Button 
       android:id="@+id/doneP2" 
       android:layout_width="50dp" 
       android:layout_height="wrap_content" 
       android:text="Done" /> 

      <Button 
       android:id="@+id/resetP2" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:text="Reset" /> 

     </TableRow> 

Вот код:

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

     /*doneP1 = (Button) this.findViewById(R.id.doneP1); 
     doneP2 = (Button) this.findViewById(R.id.doneP2); 
     resetP1 = (Button) this.findViewById(R.id.resetP1); 
     resetP2 = (Button) this.findViewById(R.id.resetP2); 

     checkTurn(); //starts the game 

     //buttons 
     doneP1.setOnClickListener(this); 
     doneP2.setOnClickListener(this); 
     resetP1.setOnClickListener(this); 
     resetP2.setOnClickListener(this);*/ //commented out 
    } 

и вне OnCreate

@Override 
public void onClick(View v) { 
     switch(v.getId()) { 
     case R.id.doneP1: 
      checkTurn(); 
      break; 
     case R.id.doneP2: 
      checkTurn(); 
      break; 
     case R.id.resetP1: 
      break; 
     case R.id.resetP2: 
      break; 
     } 
} 

здесь является checkturn

public void checkTurn() 
    { 
     if(turn == 1) 
     { 
      changeLayout(turn); 
      turn = 2; 
     } 
     else 
     { 
      changeLayout(turn); 
      turn = 1; 
     } 
    } 

вот changelayout (EDIT: новый changeLayout, я просто инициализируется каждый кнопки внутри метода, но до сих пор никакого эффекта, я делаю это правильно?)

public void changeLayout(int turn) 
{ 
    FragmentManager fm  = getSupportFragmentManager(); 
    Fragment  fragment = fm.findFragmentById(R.id.fragment_container); 
    FragmentTransaction ft; 

    if(turn == 1) //if its player 1's turn 
    { 
     doneP1 = (Button) this.findViewById(R.id.doneP1); 
     resetP1 = (Button) this.findViewById(R.id.resetP1); 
     doneP1.setOnClickListener(this); 
     resetP1.setOnClickListener(this); 
     if(fragment == null) //checks wether the current framelayout contains a fragment or not 
     { 
      ft = fm.beginTransaction(); 
      ft.add(R.id.fragment_container, new PlayerTurn1()); 
      ft.commit(); 
      //setPlayer1(); 
     } 
     else 
     { 
      ft = fm.beginTransaction(); 
      ft.replace(R.id.fragment_container, new PlayerTurn1()); 
      ft.commit(); 

     } 
    } 
    else 
    { 
     doneP2 = (Button) this.findViewById(R.id.doneP2); 
     resetP2 = (Button) this.findViewById(R.id.resetP2); 
     doneP2.setOnClickListener(this); 
     resetP2.setOnClickListener(this); 
     if(fragment == null) 
     { 
      ft = fm.beginTransaction();; 
      ft.add(R.id.fragment_container, new PlayerTurn2()); 
      ft.commit(); 
      //setPlayer2(); 
     } 
     else 
     { 
      ft = fm.beginTransaction();; 
      ft.replace(R.id.fragment_container, new PlayerTurn2()); 
      ft.commit(); 
     } 
    } 
} 

и вот LogCat

03-24 07: 51: 55.954: E/AndroidRuntime (5092): вызвано: java.lang.NullPointerException 03-24 07: 51: 55.954: E/AndroidRuntime (5092): at As2.packageTK.TicTacToeGame .onCreate (TicTacToeGame.java:88)

линия 88 является:

doneP1.setOnClickListener(this); 

Я работал над этим в течение около 4 часов, и я до сих пор не может решить простую задачу. У меня голова пускает слюни, и я действительно устал, я хочу исправить это, прежде чем я пойду спать, поэтому я буду благодарен за быстрый ответ. Я очистил и перестроил свою проблему ... ничего. Кажется, все хорошо, но нет ... NPE всегда имеет бюст в.

+1

PLZ также добавить checkTurn(); код с вопросом –

+0

Я добавил их. Im очень уверен, что код прав, но каждый раз, когда я удаляю код кнопок, он работает -.- – Morpheglus

+0

@ user2203939 Можете ли вы просто проверить, что вы сохранили файл макета, очистили и перестроили проект, и все еще получаете ошибка? – Tushar

ответ

0

Если вы получаете NPE на

doneP1.setOnClickListener(this); 

, что означает, что doneP1 равна нулю. Вы проверили только печать/loggin doneP1, doneP2, resetP1 и resetP2 (до линии 88, конечно). Например:

Log.d(TAG, "doneP1 = "+doneP1); 
Log.d(TAG, "doneP2 = "+doneP2); 
... 

Я предполагаю, что все эти компоненты равны нулю. Это означает, что вы, вероятно, загрузите неправильный макет. Или, может быть, вы загрузили правильную с самого начала, но изменить его на что-то еще в

public void changeLayout(int turn) 

EDIT:

Ваших TableRows находятся в разных раскладках?

"Here are the XML(each table rows are from separate XMLs):" 

Тогда, конечно, компоненты P1 будут нулевыми при загрузке макета P2 и наоборот.

EDIT2:

Загрузите ссылки в changeLayout.Так как у вас одновременно есть две кнопки на экране (сброс и выполнение), вам понадобятся только две ссылки (т. Е. Вам не нужны как donep1, так и donep2). А затем в макете изменения вы измените ссылку на правильную кнопку. Таким образом, вам нужна логика, чей ход был в onClick кнопок.

+0

Я еще не проверял loggin, но да, таблетки находятся в разной компоновке. Они должны быть, так как они будут помещены внутри фрагментов. Каждый макет представляет игрока, и у каждого игрока есть две кнопки ... Я не вижу, как все эти компоненты могут быть нулевыми. Я имею в виду, что я не изменяю их, насколько я вижу. Я проверю регистрацию и распечатаю ее – Morpheglus

+0

Если вы загрузили макет Player1; то компоненты Player2 будут нулевыми, верно? – jelgh

+0

Да, проблема в том, что каждый раз, когда вызывается метод changeLayout(), фрагмент player1 заменяется фрагментом плеера2, поэтому в основном я теряю идентификационную ссылку на каждую кнопку в обоих фрагментах. Я обновил то, что я пытался сделать, чтобы исправить это, но все равно ничего хорошего. – Morpheglus

0

Как это выглядит, вы получаете те представления в onCreate:

doneP1 = (Button) this.findViewById(R.id.doneP1); 
    doneP2 = (Button) this.findViewById(R.id.doneP2); 
    resetP1 = (Button) this.findViewById(R.id.resetP1); 
    resetP2 = (Button) this.findViewById(R.id.resetP2); 

, но после того, как вы изменили, чтобы включить и изменить расположение в вашем:

public void checkTurn() 
{ 
    if(turn == 1) 
    { 
     changeLayout(turn); 
     turn = 2; 
    } 
    else 
    { 
     changeLayout(turn); 
     turn = 1; 
    } 
} 

и запустив:

ft.replace(R.id.fragment_container, new PlayerTurn1()); 

Вы в основном теряете ссылку на эти виды. потому что их уже нет. они были заменены представлениями другого фрагмента.

EDIT:

alternatice бы установить onClick свойство в файле макета:

Установите "android:onClick="onDoneButtonOnClick"

и в своей деятельности создать метод:

public void onDoneButtonOnClick (View v) 
{ 
     // do here what every you want with this button. 
} 

В этом случае вам придется удалить реализацию onClickListener от вашей деятельности.

+0

Я думаю, что вы имеете смысл. Это значит, что я должен их инициализировать, пока я воссоздаю/заменяю вид фрагментов? – Morpheglus

+0

Итак, в основном после замены макета вам снова нужно снова запустить метод findByViewId 4 раза для ваших 4 просмотров, чтобы ссылаться на новые представления в недавно замененном макете фрагмента. –

+0

Итак, всякий раз, когда вызывается changeLayout, мне нужно повторно инициализировать кнопку. Это имеет смысл, я попробую. EDIT: только что протестирован и не работает. Возможно, я что-то делаю неправильно, но есть ли упрощенный способ сделать это, а не повторять каждый раз? – Morpheglus

Смежные вопросы