如何在片段生命周期中正确处理回收者视图?
how to properly handle recycler view in a fragments lifecycle?
您好,我有一个选项卡布局,它通过 viewpager 扩充了一堆片段,每个片段实例化了一堆视图,一切正常,但是如果我刷过几个片段然后再刷回这些片段,就会出现问题存在分离和附加以及设置其视图的生命周期,导致片段在其布局中加倍视图,
例如:片段显示 5 个视图,滑动浏览一些片段并向回滑动同一片段然后显示 10 个视图
我相信这是因为我在 onCreateView 中设置了所有内容,我试图将设置调用移至 onViewCreated,这给了我一个不同的问题,片段和视图创建得很好,但是当你滑开然后返回时,视图消失了并且控制台告诉我 'no adapter attached skipping layout',研究这个给我的印象是我需要将我的适配器调用移动到主线程但是我无法让它工作空指针无论我尝试什么都可以有人指出我正确的方向,
这是我的片段的主要部分
public class OneFragment extends Fragment{
public static List<CardWriter> cardMakerList = new ArrayList<>();
private RecyclerView recyclerView;
private GridLayoutManager staggeredGridLayoutManagerVertical;
public static CardAdapter cardAdapter;
public OneFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate
(R.layout.fragment_one, container, false);
RecyclerView.LayoutManager staggeredGridLayoutManagerVertical = new
StaggeredGridLayoutManager(4,LinearLayoutManager.VERTICAL);
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_grid);
cardAdapter = new CardAdapter(cardMakerList);
recyclerView.setLayoutManager(staggeredGridLayoutManagerVertical);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(cardAdapter);
recyclerView.addOnItemTouchListener(new
RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
CardWriter cardWriter = cardMakerList.get(position);
SpeakGrid.cardMakerList.add(SpeakGrid.cardMakerList.size(),cardWriter);
SpeakGrid.cardAdapter.notifyItemInserted(SpeakGrid.cardMakerList.size());
SpeakRecyclerGrid.cardMakerList.add
(SpeakRecyclerGrid.cardMakerList.size(),cardWriter);
SpeakRecyclerGrid.cardAdapter.notifyItemInserted
(SpeakGrid.cardMakerList.size());
Snackbar.make(view, "This card is " +
cardWriter.getCardEmotion() + " and it would say " +
cardWriter.getCardEmotion(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
ive been going through and debugging this and it was also happening while rotating so im now using if (savedinstance state == null) to solve the issue with rotating but it must be lost when scrolling because it still happens if i scroll more than one away and come back the cards in the view have doubled
如果您没有在选项卡式 activity 中使用 ViewPager,请确保您在片段事务中使用 replace(),而不是 add()
Fragment fragment = new Fragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit();
此外,我建议您在选项卡中使用 viewpager,因为它会为您处理事务。如果您没有使用 ViewPager,那就是。
我确定这不是管理它的正确方法,但它似乎适用于旋转和切换选项卡,它非常蛮力,但确保该方法只被调用一次
if (bool == false) {
prepareCardData();
bool = true;
};
在 onCreateView 中初始化您的视图,然后在 onActivityCreated 中编辑它们。在onCreateView中调用getActivity()会导致空指针异常
/**
* Called to have the fragment instantiate its user interface view, can be
* null for non-graphical fragments Called after onCreate(Bundle) and
* beforeonActivityCreated(Bundle).
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_one, container, false);
RecyclerView.LayoutManager staggeredGridLayoutManagerVertical = new
StaggeredGridLayoutManager(4,LinearLayoutManager.VERTICAL);
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_grid);
return rootView;
}
/**
* Called when the fragment's activity has been created and this fragment's
* view hierarchy instantiated. Called after onCreateView(Bundle) and before
* onViewStateRestored(Bundle).
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
cardAdapter = new CardAdapter(cardMakerList);
recyclerView.setLayoutManager(staggeredGridLayoutManagerVertical);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(cardAdapter);
recyclerView.addOnItemTouchListener(new
RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
CardWriter cardWriter = cardMakerList.get(position);
SpeakGrid.cardMakerList.add(SpeakGrid.cardMakerList.size(),cardWriter);
SpeakGrid.cardAdapter.notifyItemInserted(SpeakGrid.cardMakerList.size());
SpeakRecyclerGrid.cardMakerList.add
(SpeakRecyclerGrid.cardMakerList.size(),cardWriter);
SpeakRecyclerGrid.cardAdapter.notifyItemInserted
(SpeakGrid.cardMakerList.size());
Snackbar.make(view, "This card is " +
cardWriter.getCardEmotion() + " and it would say " +
cardWriter.getCardEmotion(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}
您好,我有一个选项卡布局,它通过 viewpager 扩充了一堆片段,每个片段实例化了一堆视图,一切正常,但是如果我刷过几个片段然后再刷回这些片段,就会出现问题存在分离和附加以及设置其视图的生命周期,导致片段在其布局中加倍视图,
例如:片段显示 5 个视图,滑动浏览一些片段并向回滑动同一片段然后显示 10 个视图
我相信这是因为我在 onCreateView 中设置了所有内容,我试图将设置调用移至 onViewCreated,这给了我一个不同的问题,片段和视图创建得很好,但是当你滑开然后返回时,视图消失了并且控制台告诉我 'no adapter attached skipping layout',研究这个给我的印象是我需要将我的适配器调用移动到主线程但是我无法让它工作空指针无论我尝试什么都可以有人指出我正确的方向,
这是我的片段的主要部分
public class OneFragment extends Fragment{
public static List<CardWriter> cardMakerList = new ArrayList<>();
private RecyclerView recyclerView;
private GridLayoutManager staggeredGridLayoutManagerVertical;
public static CardAdapter cardAdapter;
public OneFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate
(R.layout.fragment_one, container, false);
RecyclerView.LayoutManager staggeredGridLayoutManagerVertical = new
StaggeredGridLayoutManager(4,LinearLayoutManager.VERTICAL);
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_grid);
cardAdapter = new CardAdapter(cardMakerList);
recyclerView.setLayoutManager(staggeredGridLayoutManagerVertical);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(cardAdapter);
recyclerView.addOnItemTouchListener(new
RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
CardWriter cardWriter = cardMakerList.get(position);
SpeakGrid.cardMakerList.add(SpeakGrid.cardMakerList.size(),cardWriter);
SpeakGrid.cardAdapter.notifyItemInserted(SpeakGrid.cardMakerList.size());
SpeakRecyclerGrid.cardMakerList.add
(SpeakRecyclerGrid.cardMakerList.size(),cardWriter);
SpeakRecyclerGrid.cardAdapter.notifyItemInserted
(SpeakGrid.cardMakerList.size());
Snackbar.make(view, "This card is " +
cardWriter.getCardEmotion() + " and it would say " +
cardWriter.getCardEmotion(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
ive been going through and debugging this and it was also happening while rotating so im now using if (savedinstance state == null) to solve the issue with rotating but it must be lost when scrolling because it still happens if i scroll more than one away and come back the cards in the view have doubled
如果您没有在选项卡式 activity 中使用 ViewPager,请确保您在片段事务中使用 replace(),而不是 add()
Fragment fragment = new Fragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).commit();
此外,我建议您在选项卡中使用 viewpager,因为它会为您处理事务。如果您没有使用 ViewPager,那就是。
我确定这不是管理它的正确方法,但它似乎适用于旋转和切换选项卡,它非常蛮力,但确保该方法只被调用一次
if (bool == false) {
prepareCardData();
bool = true;
};
在 onCreateView 中初始化您的视图,然后在 onActivityCreated 中编辑它们。在onCreateView中调用getActivity()会导致空指针异常
/**
* Called to have the fragment instantiate its user interface view, can be
* null for non-graphical fragments Called after onCreate(Bundle) and
* beforeonActivityCreated(Bundle).
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_one, container, false);
RecyclerView.LayoutManager staggeredGridLayoutManagerVertical = new
StaggeredGridLayoutManager(4,LinearLayoutManager.VERTICAL);
recyclerView = (RecyclerView) rootView.findViewById(R.id.card_grid);
return rootView;
}
/**
* Called when the fragment's activity has been created and this fragment's
* view hierarchy instantiated. Called after onCreateView(Bundle) and before
* onViewStateRestored(Bundle).
*/
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
cardAdapter = new CardAdapter(cardMakerList);
recyclerView.setLayoutManager(staggeredGridLayoutManagerVertical);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(cardAdapter);
recyclerView.addOnItemTouchListener(new
RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
CardWriter cardWriter = cardMakerList.get(position);
SpeakGrid.cardMakerList.add(SpeakGrid.cardMakerList.size(),cardWriter);
SpeakGrid.cardAdapter.notifyItemInserted(SpeakGrid.cardMakerList.size());
SpeakRecyclerGrid.cardMakerList.add
(SpeakRecyclerGrid.cardMakerList.size(),cardWriter);
SpeakRecyclerGrid.cardAdapter.notifyItemInserted
(SpeakGrid.cardMakerList.size());
Snackbar.make(view, "This card is " +
cardWriter.getCardEmotion() + " and it would say " +
cardWriter.getCardEmotion(), Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
}