Android заставляет Fragment перестраивать View - PullRequest
14 голосов
/ 17 октября 2011

У меня есть простое приложение, которое имеет два фрагмента, и когда в альбомном режиме оба фрагмента показаны рядом, а в портретном изображении я показываю фрагмент A, а затем, если они выбирают опцию, запускает действие, которое показывает фрагмент B. Моя проблема это когда я нахожусь в портретном режиме и показываю фрагмент B, если пользователь выбирает пункт меню, я хочу обновить или перерисовать представление, связанное с фрагментом B, и не могу понять, как заставить это работать. Я попробовал метод getView и метод getLayoutInflater, но экран не изменился, потому что я думаю, что я создаю новый вид. Я также пытался получить ссылку на фрагмент А, думая, что могу вызвать его процедуру для создания нового фрагмента и замены фрагмента Б, но не могу получить ссылку на него, потому что он не отображается. Что мне действительно нужно сделать, так это просто вызвать метод onCreateView для повторного вызова, чтобы раздувать новое представление, но я попытался сделать несколько методов, чтобы попытаться это сделать, но не могу получить вызов onCreateView для повторного вызова. Есть мысли о том, как это сделать?

Ответы [ 2 ]

9 голосов
/ 17 октября 2011

Вы захотите выполнить FragmentTransaction и использовать метод replace()

Это не должно быть слишком сложно, но ответ будет зависеть от того, где находится ваше меню (т.е.onOptionsItemSelected() перезвоните в вашей родительской Деятельности или во Фрагменте A / B?).

Предположим, для простоты, ваша реализация меню и onOptionsItemSelected() находятся в родительском действии, и вы хотите изменить форму фрагментов в случае, если выбрано menu_option1.Это выглядело бы примерно так:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}

В качестве альтернативы, если ваше меню является дочерним по отношению к одному из ваших фрагментов (что должно быть для более многократно используемого кода), то один из методов - это требовать, чтобыАктивность хоста для реализации интерфейса, определенного фрагментом, который можно использовать в качестве обратного вызова.А в обратном вызове onOptionsItemSelected() внутри вашего класса фрагмента вы просто вызываете этот метод обратного вызова.

Хотя это звучит как глоток, вам действительно нужно сделать всего пару вещей.Представьте, что это ваш фрагмент-класс

public static class FragmentA extends ListFragment {
OnSelectedListener mListener;
// Container Activity must implement this interface
public interface OnSelectedListener {
    public void onSelected();
}
...
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    //This is to ensure that the Activity has implemented the interface we set up above
    try {
        mListener = (OnSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString() + " must implement OnSelectedListener");
    }
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
//...
switch (item.getItemId()) {
case R.id.menu_option1:
    //do something
    getActivity().onSelected();
    return true;
case R.id.menu_option2:
    //do something else;
    return true;
default:
    return super.onOptionsItemSelected(item);
}
}
...
}

Тогда в Задании вы увидите что-то вроде:

public class MainActivity extends Activity implements FragmentA.onSelectedListener{
...
public void onSelected(){
    FragmentManager fragmentManager = getFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment newFragment = new YourFragmentClass();
    FragmentTransaction transaction = getFragmentManager().beginTransaction();
    transaction.replace(R.id.your_fragment_id, newFragment);
    transaction.addToBackStack(null);
    transaction.commit();
}
}
1 голос
/ 17 октября 2011

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

В onOptionsItemSelected(), пусть действие вызывает метод для фрагмента, который заставляет его обновлять свои виджеты новым содержимым.Или попросите действие выполнить FragmentTransaction для замены фрагмента (если фрагмент был изначально настроен с помощью FragmentTransaction).

...