#java #android #android-studio #android-fragments
#java #Android #android-studio #android-фрагменты
Вопрос:
Большую часть выходных я ломал голову, пытаясь решить проблему, связанную с Android Studio. Задача состоит в том, чтобы создать фрагмент списка, который будет обновляться, когда пользователь нажимает кнопки на панели управления, но, несмотря на все мои усилия, на самом деле отображается только один из фрагментов (и он одинаков независимо от того, на какую кнопку нажимает пользователь).). Я сузил область поиска до такой степени, что я совершенно уверен, что проблема связана с обработкой пакетов конструктором, но я не уверен, где ошибка. Вот связанный код:
public static ItemFragment newInstance(String title, int position) {
ItemFragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
И позже вызов getArguments():
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
if (mPosition == 0) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, listItems));
} else if (mPosition == 1) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, newGoalItems));
} else if (mPosition == 2) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, markProgressItems));
} else if (mPosition == 3) {
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, android.R.id.text1, settingsItems));
}
}
Это связанный код в MainActivity:
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_list) {
list=ItemFragment.newInstance("List", 0);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_newGoal) {
newGoal=ItemFragment.newInstance("New Goal", 1);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_markProgress) {
markProgress=ItemFragment.newInstance("Mark Progress", 2);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
else if (id==R.id.action_settings) {
settings=ItemFragment.newInstance("Settings", 3);
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
fragmentTransaction.commit();
}
return super.onOptionsItemSelected(item);
}
Из тестирования я знаю, что код просто вылетает из-за приведенного выше оператора if. Чего я не знаю, так это почему… Мне кажется, что в getArguments должны быть некоторые значения, которые не позволяют ему возвращать null.
Комментарии:
1. ваш код выглядит правильным для меня .. где вы вызвали свой getArguments ()?
2. Как
getArguments
выглядит метод?3. Здесь недостаточно кода, чтобы распознать какую-либо проблему.
4. Извините, я не уверен, что вы имеете в виду, говоря о том, как выглядит метод getArguments… Должна ли где-то быть реализация? Кроме того, единственными вызовами getArguments() являются те, что указаны выше.
5. Я думаю, что Handrata конкретно имела в виду, в каком методе жизненного цикла вы вызываете get arguments (onCreate, onResume и т.д.)? Также как / где вы вызываете newInstance ()?
Ответ №1:
Напишите этот фрагмент кода в методе fragments onCreate (), он будет работать
if (getArguments() != null) {
mTitle=getArguments().getString(ARG_PARAM1);
mPosition=getArguments().getInt(ARG_PARAM2);
getActivity().setTitle(mTitle);
}
Комментарии:
1. Есть ли у вас какой-либо тег <fragment> в вашем xml, потому что onCreate() фрагмента будет вызываться первым, а не в коде Java, таким образом, не задавая аргументы. Попробуйте удалить тег фрагмента из xml
2. В XML нет тега fragment, который я могу найти… Я думаю, что это в этом файле Java, потому что, когда я вручную устанавливаю переменную, она отлично настраивается; проблема возникает только при ее динамической настройке на основе выбора из списка.
Ответ №2:
Похоже, вы пытаетесь прочитать аргументы в конструкторе вашего фрагмента. Контекст еще не будет установлен в конструкторе, поэтому вы должны читать из пакета в методе onCreate().
Комментарии:
1. Извините, я не очень хорошо объяснил ситуацию… Чтение уже настроено на выполнение в методе onCreate(). Я добавил большую часть кода, если это поможет
2. Все, что вы делаете, выглядит для меня хорошо. Вы пробовали комментировать «setRetainInstance(true);», чтобы посмотреть, влияет ли это на что-либо?
Ответ №3:
public static Fragment newInstance(String title, int position) {
Fragment fragment = new ItemFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1,title);
args.putInt(ARG_PARAM2,position);
fragment.setArguments(args);
return fragment;
}
Измените эту строку ItemFragment fragment = new ItemFragment(); на этот фрагмент fragment = new ItemFragment(); и весь ваш код будет идеальным.
Комментарии:
1. Я пробовал это, но это вызывает проблему с фрагментом возврата строки;
2. затем измените возвращаемый тип метода newInstance, вместо ItemFragment используйте только Fragment. пожалуйста, проверьте мое обновленное решение.
Ответ №4:
Я, наконец, понял это! Итак, проблема заключалась в том, что в процессе загрузки фрагментов во фрейм (третий раздел кода) профессор предоставил нам строку кода, которая создавала экземпляр нового фрагмента вместо того, чтобы использовать тот, который мы только что создали несколькими строками выше. Я просто заменил
fragmentTransaction.add(R.id.list_frame, new ItemFragment());
с
fragmentTransaction.add(R.id.list_frame, list);
и теперь все запускается. Всем спасибо за помощь!