2013-08-19 3 views
1

Я пытаюсь узнать, как использовать фрагмент в качестве рабочего для активности андроида. У меня есть следующий простой макет XML для моей основной деятельности:Использование фрагментов в качестве рабочих для активности

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="vertical" > 

<Button 
     android:id="@+id/update" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Press me" /> 

<TextView 
     android:id="@+id/text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="" /> 

</LinearLayout> 

Я определяю свой фрагмент, используя следующее определение класса:

public class UpdateTextFragment extends Fragment { 

public static UpdateTextFragment newInstance() { 
    return new UpdateTextFragment(); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

public void startUpdateText() { 

    TextView textView = ((TextView) getActivity().findViewById(R.id.text)); 
    textView.setText("I've been pressed!"); 

} 

} 

Тогда из моей основной деятельности я просто добавить фрагмент и вызовом startUpdateText Способ фрагмента с помощью кнопки он onClickListener, т.е.

public void onClick(View arg0) { 

    UpdateTextFragment fragment = UpdateTextFragment.newInstance(); 
    getFragmentManager().beginTransaction().add(fragment, "updateText").commit(); 
    fragment.startUpdateText(); 


} 

код компилируется и добавления к таблетке без проблем. Я ожидаю, что он напишет текст «Я был нажат!» для текстового просмотра при нажатии кнопки, но приложение просто выходит из строя со стандартным «К сожалению приложение перестало работать». Я еще не реализовал класс, чтобы поймать это непокрытое исключение - я надеялся, что это может быть что-то очевидное, я пропал или не понимаю?

Thanx

+1

Прежде всего, проверьте свой логарифмический файл на предмет фактических ошибок. Он должен содержать stracktrace. Во-вторых, это просто не то, как Фрагменты работают и для чего они нужны. Прежде всего, ознакомьтесь с использованием фрагментов и их целью в документации разработчика. –

+0

Спасибо Стефан.Logcat предлагает исключение java.lang.NullPointerException. Будут исследовать дальше. Кроме того, почему бы не использовать такой фрагмент? Я не собираюсь использовать его, чтобы просто изменить текст где-то, но как рабочий для AsyncTask, чтобы он мог сохранять свое состояние между изменениями ориентации (выше это была просто попытка понять его реализацию). Документация, похоже, предполагает, что вы можете использовать фрагменты в качестве рабочих, но, пожалуйста, дайте мне знать, если я пропущу что-то важное. –

+0

Фрагмент является повторно используемым «пользовательским элементом», размещенным внутри Activity. Цель состоит в том, чтобы некоторые части пользовательского интерфейса были повторно использованы для разных макетов. Таким образом, фрагмент имеет свой собственный вид xml и в значительной степени автономный. Он не собирается запускать для простой задачи, делать что-то на Activity и закрывать. Если вам нужны такие работники, вам лучше взглянуть на темы и службы. Ваш Nullpointer, вероятно, является «фрагментом», равным нулю, или «textview» внутри вашего фрагмента. –

ответ

2

Altough это старый вопрос, который я хотел бы ответить на него, как я был озадачен, почему ваш образец кода не работает.

Причина, по которой вы получаете NullPointerException, заключается в том, что вы создаете экземпляр своего Fragment и сразу же вызываете метод, который требует, чтобы деятельность была введена во Фрагмент. Активность вводится по методу FragmentManager/FragmentTransaction#commit но этот метод не сразу оценить транзакцию (как от JavaDocs):

Графики фиксации этой транзакции. Конец не происходит немедленно; он будет запланирован, так как работа над основным потоком будет выполнена в следующий раз, когда поток будет готов.

Что означает

getFragmentManager().beginTransaction().add(fragment, "updateText").commit(); 
fragment.startUpdateText(); 

уступит NPE в startUpdateText() (так как сделка еще не была выполнена!).

Добавив вызов метода getFragmentManager().executePendingTransactions(); сразу после совершения сделки, транзакция будет выполнена немедленно и операция, введенная во фрагмент. getActivity() в Fragment теперь возвращает активность он был прикреплен к и ваш пример работает :)

Как из комментариев ниже Ваш вопрос: Это правда, что фрагмент является многоразовый «UI-элемент» прошел внутри Мероприятия. (@Stefan de Bruijn), но также и то, что [...] фрагмент не является частью макета деятельности; вы также можете использовать фрагмент без собственного пользовательского интерфейса в качестве невидимого работника для этой деятельности. (как говорится в официальном сообщении Android doc).

Таким образом, фрагмент не обязательно является компонентом графического интерфейса (т. Е. Представлением в MVC), но также действует как контроллер с собственным жизненным циклом жизни.