Фрагмент с RecyclerView не отображается второй раз, пока не изменится - PullRequest
0 голосов
/ 04 апреля 2019

У меня есть фрагмент, содержащий RecyclerView и кнопку.Фрагмент вызывается при нажатии кнопки (которая добавляет некоторые данные) в предыдущем фрагменте, и утилита повторения показывает правильно заполненную кнопку, кнопка работает.Затем я возвращаюсь к предыдущему фрагменту, снова нажимаю кнопку (добавляю больше данных), и тот же фрагмент кода вызывает тот же фрагмент, но RecyclerView не заселен и кнопка не работает.После прочтения этого вопроса я предполагаю, что я что-то делаю в своем управлении фрагментами - потому что, как только я меняю ориентацию и фрагмент воссоздается, список отображается нормально, а кнопка работает нормально.

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

Сначала есть базовый класс, который я делаю для своегофрагменты:

public class BaseFragment extends Fragment {

    private AbstractFragmentCallback mCallback;


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            mCallback = (AbstractFragmentCallback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement " + 
AbstractFragmentCallback.class.getCanonicalName());
        }

    }

    /**
     * This method replaces the currently shown fragment with a new 
fragment of a particular class.
     * If a fragment of the required class already shown - does 
nothing.
     * @param clazz the class of the fragment to show
     * @param addToBackStack whether the replacement should be added 
to back-stack
     * @param args arguments for the newly created fragment (can be 
null)
     */
    public void replaceFragment(Class<? extends Fragment> clazz, 
boolean addToBackStack,
                            Bundle args) {
        mCallback.replaceFragment(clazz, addToBackStack, args);
    }



    public interface AbstractFragmentCallback {

        /**
         * Call to this method replaces the currently shown fragment 
with a new one
         *
         * @param clazz           the class of the new fragment
         * @param addToBackStack whether the old fragment should be 
added to the back stack
         * @param args           arguments to be set for the new fragment
         */
        void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
                         Bundle args);

    }

}

Итак, мой MainActivity реализует BaseFragment.AbstractfragmentCallback так:

public class MainActivity extends AppCompatActivity implements BaseFragment.AbstractFragmentCallback {

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

    setContentView(....);

    if (null == savedInstanceState) {
        replaceFragment(WelcomeFragment.class, false, null);
    }
}

// ---------------------------------------------------------------------------------------------
//
// Fragments management

@Override
public void replaceFragment(Class<? extends Fragment> clazz, boolean addToBackStack,
                            Bundle args) {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    Fragment newFragment;

    try {
        // Create new fragment
        newFragment = clazz.newInstance();
        if (args != null) newFragment.setArguments(args);
    } catch (InstantiationException e) {
        e.printStackTrace();
        return;
    } catch (IllegalAccessException e) {
        e.printStackTrace();
        return;
    }

    if (addToBackStack) {
        ft.addToBackStack(null);
    }

    // Change to a new fragment
    ft.replace(R.id.container, newFragment, clazz.getName());
    ft.commit();

}
// End of fragments management
//
// ---------------------------------------------------------------------------------------------

}

и когда мой фрагмент с кнопкой хочет вызвать фрагмент списка, он вызывает

replaceFragment(ListFragment.class, true, null);

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

public class ListFragment extends BaseFragment implements ListFragmentMvc.ListViewMvcListener {

private List<MyStuff> stuffList;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstance) {
    stuffList = new ArrayList<>();
    return inflater.inflate(R.layout.list_activity, container, true);
}

@Override
public void onResume() {
    super.onResume();
    recyclerView = mRootView.findViewById(R.id.recycler_view);


    letsGoButton = mRootView.findViewById(R.id.lets_go_button);
    letsGoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Activity activity = getActivity();
    if (activity != null) {
        getActivity().onBackPressed();
    }

        }
    });

    recyclerView.setItemAnimator(new DefaultItemAnimator());

    DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
    recyclerView.addItemDecoration(itemDecor);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
    recyclerView.setLayoutManager(mLayoutManager);

    setData(MyApplication.getAllStuffItems());

}
public void setData(List<MyStuff> stuff) {
    stuffList = stuff;
    mAdapter = new StuffAdapter(stuffList);
    recyclerView.setAdapter(mAdapter);

    mAdapter.notifyDataSetChanged();
}


}

Итак, у кого-нибудь есть подсказка, почему это не работает, пока я не изменю ориентацию при повторном входеg Фрагмент списка?

Спасибо

Ответы [ 2 ]

0 голосов
/ 04 апреля 2019

Ух ты, это была дикая трата дня.

В итоге у меня была пара ошибок, которые вставлялись и скрывали друг друга.

Реальная реальная причина, по которой это не сработало, я думаю, была в том, что я должен был

return inflater.inflate(R.layout.list_activity, container, false);

вместо

return inflater.inflate(R.layout.list_activity, container, true);

Я немного соврал в своем коде, потому что на самом деле я не возвращал результат inflater.inflate напрямую ... Я вызывал его (с неверным параметром), а затем возвращал ноль.

Полагаю, это научит меня быть более честным в публикации

0 голосов
/ 04 апреля 2019

Можете ли вы попытаться переместить код, который устанавливает / обновляет recyclerView и позволяет GoButton из метода onResume в onViewCreated метод, как показано ниже:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    recyclerView = view.findViewById(R.id.recycler_view);


    letsGoButton = view.findViewById(R.id.lets_go_button);
    letsGoButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Activity activity = getActivity();
            if (activity != null) {
                getActivity().onBackPressed();
            }

        }
    });

    recyclerView.setItemAnimator(new DefaultItemAnimator());

    DividerItemDecoration itemDecor = new DividerItemDecoration(context, HORIZONTAL);
    recyclerView.addItemDecoration(itemDecor);

    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
    recyclerView.setLayoutManager(mLayoutManager);

    setData(MyApplication.getAllStuffItems());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...