Fragment in ViewPager is not displaying anything in its RecyclerView on rotation(ViewPager 中的片段在其 RecyclerView 旋转时未显示任何内容)
问题描述
我在与 TabLayout 集成的 ViewPager 中有 4 个片段.这些 Fragments 中的每一个都包含一个 RecyclerView,因为我正在显示未知数量的列表项.这些项目是按日期加载的,所以我有两个按钮可以让您更改日期,然后根据设置的日期加载列表项目中的相应数据.按钮是外部活动的一部分.
I have 4 Fragments in a ViewPager that is integrated with a TabLayout. Each of those Fragments holds a RecyclerView because I'm displaying an unknown amount of list items. The items are loaded by date, so I have two buttons that let you change days, and then the appropriate data in the list items is loaded based on the date that is set. The buttons are part of the outer activity.
到目前为止,一切都很完美,但是一旦我旋转设备,片段就不会加载任何东西.片段内不显示任何内容.不过,外部活动中的视图显示得很好.奇怪的是,如果我触摸其中一个更改日期的按钮,则会加载片段并正确显示数据.但是我需要在旋转后立即显示所有内容,而不仅仅是单击其中一个按钮时.这是我的代码:
Everything so far works perfectly BUT once I rotate the device the fragments don't load anything. Nothing is displayed inside the Fragments. The views in the outer activity are displayed fine though. The weird thing is that if I touch one of the buttons that changes the date, the Fragments are loaded and the data is displayed correctly. But I need everything to be displayed immediately after rotation not just when I click one of those buttons. Here is my code:
public class MainActivity extends AppCompatActivity implements DatePickerFragment.DateDialogInterface
{
private final static String COLOR_CONTROL_CHOSEN = "color_control_chosen";
private static final String DIALOG_DATE = "dialog_date";
private static final String TAG = "MainActivity";
private static final String SET_LOCATION = "set_location";
public static final String LEAGUE_POSITION = "league_position";
private Toolbar mToolbar;
private ViewPager mViewPager;
private TabLayout mTabLayout;
private ImageButton mPrevDateButton, mNextDateButton;
private TextView mDateTextView, mLeagueTextView;
private String mTodaysDate;
private Date mLastSelectedDate, mTodaysDateObj;
private ProgressBar mProgressBar;
private FragmentPagerAdapter mAdapterViewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.outnix_toolbar);
mViewPager = (ViewPager) findViewById(R.id.main_activity_view_pager);
mTabLayout = (TabLayout) findViewById(R.id.main_activity_tab_layout);
mDateTextView = (TextView) findViewById(R.id.display_date_text_view);
mLeagueTextView = (TextView) findViewById(R.id.league_title_header);
mPrevDateButton = (ImageButton) findViewById(R.id.previous_date_button);
mNextDateButton = (ImageButton) findViewById(R.id.next_date_button);
mProgressBar = (ProgressBar) findViewById(R.id.loading_circle);
mProgressBar.setVisibility(View.GONE);
setTodaysDate();
mDateTextView.setText("Today");
setSupportActionBar(mToolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayShowTitleEnabled(false);
NavDrawerFragment navDrawerFrag = (NavDrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_nav_drawer);
navDrawerFrag.setUp((DrawerLayout) findViewById(R.id.nav_drawer), mToolbar);
setUpViewPagerAdapterOnCreate();
mTabLayout.setupWithViewPager(mViewPager);
mDateTextView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
FragmentManager fm = getSupportFragmentManager();
DatePickerFragment dialog = new DatePickerFragment();
Bundle args = new Bundle();
args.putSerializable("ARG_DATE", mLastSelectedDate);
dialog.setArguments(args);
dialog.show(fm, DIALOG_DATE);
}
});
THESE TWO LISTENERS ARE WHAT DISPLAY THE DATA AFTER A ROTATION CHANGE
//////////////////////////////////////////////////////////////////
mPrevDateButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v)
{
mProgressBar.setVisibility(View.VISIBLE);
updateDate(-1);
setupViewPagerAdapter(getViewPagerPos());
}
});
mNextDateButton.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
mProgressBar.setVisibility(View.VISIBLE);
updateDate(1);
setupViewPagerAdapter(getViewPagerPos());
}
});
}
////////////////////////////////////////////////////////////////////
/* @Override
protected void onResume()
{
super.onResume();
setupViewPagerAdapter(getViewPagerPos());
}*/
private void setUpViewPagerAdapterOnCreate() //only called when opened from LauncherActivity
{
setupViewPagerAdapter(0);
int touchColorPixel = getIntent().getIntExtra(COLOR_CONTROL_CHOSEN, ContextCompat.getColor(this, R.color.blue));
if(touchColorPixel == ContextCompat.getColor(this, R.color.orange))
mViewPager.setCurrentItem(0);
else if(touchColorPixel == ContextCompat.getColor(this, R.color.blue))
mViewPager.setCurrentItem(1);
else
mViewPager.setCurrentItem(3);
}
private void setupViewPagerAdapter(int currentPos)
{
mAdapterViewPager = new MainPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mAdapterViewPager);
mViewPager.setOffscreenPageLimit(4);
mViewPager.setCurrentItem(currentPos);
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putSerializable(DIALOG_DATE, mLastSelectedDate); //save the last date selected (or last date displayed) on rotation change.
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
setDateFromDialog((Date) savedInstanceState.getSerializable(DIALOG_DATE)); //restore the last date selected to the new rotation change
}
public ProgressBar getProgressBar()
{
return mProgressBar;
}
@Override
public void setDateFromDialog(Date date)
{
String newDate = getFormattedDate(date);
updateTodaysDate();
mLastSelectedDate = date;
setupViewPagerAdapter(getViewPagerPos());
if(newDate.equals(mTodaysDate))
mDateTextView.setText("Today");
else
mDateTextView.setText(newDate);
}
private int getViewPagerPos()
{
return mViewPager.getCurrentItem();
}
}
mPrevDateButton
和 mNextDateButton
2 个按钮是单击修复"问题的按钮.在他们的点击监听器中, updateDate()
方法只做与 TextView 对象相关的事情,这就是我没有包含定义的原因(我试图让帖子尽可能短).所以我确定它与我的 setupViewPagerAdapter()
方法有关.我尝试在 onCreate()
和 onResume()
中添加此方法,但 Fragments 仍然保持空白.
The 2 buttons mPrevDateButton
and mNextDateButton
are the buttons that when clicked "fix" the problem. Inside their click listeners, the updateDate()
method is only doing stuff related to a TextView object and is why I didn't include the definitions (I'm trying to keep the post as short as possible). So I know for sure it has something to do with my setupViewPagerAdapter()
method. I've tried adding this method in onCreate()
and onResume()
but the Fragments still stay blank.
这是我的 ViewPager 适配器代码:
Here is my ViewPager adapter code:
public class MainPagerAdapter extends FragmentPagerAdapter
{
private final String[] mFragmentTitleList = {"My Games", "All Games", "All Places", "My Places"}; //tab title names
private final static int NUM_FRAGMENTS = 4;
public MainPagerAdapter(FragmentManager fm)
{
super(fm);
}
@Override
public Fragment getItem(int position)
{
switch(position)
{
case 0:
return MyGamesFragment.newInstance();
case 1:
return AllGamesFragment.newInstance();
case 2:
return AllPlacesFragment.newInstance();
case 3:
return MyPlacesFragment.newInstance();
default:
return null;
}
}
@Override
public int getCount()
{
return NUM_FRAGMENTS;
}
@Override
public CharSequence getPageTitle(int position)
{
return mFragmentTitleList[position];
}
}
这是 4 个片段之一.它们几乎都有相似的设计.
Here is one of the 4 fragments. They pretty much all have similar design.
public class AllGamesFragment extends Fragment
{
private SwipeRefreshLayout mSwipeRefreshLayout;
private RecyclerView mAllGamesRecyclerView;
private GameAdapter mGameAdapter;
private List<Game> mGameList = new ArrayList<>();
private MainActivity mMainActivity; //keeps a reference to MainActivity to access public methods
public static AllGamesFragment newInstance()
{
return new AllGamesFragment();
}
@Override
public void onAttach(Context context)
{
super.onAttach(context);
mMainActivity = (MainActivity) context;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setRetainInstance(true);
mMainActivity.getProgressBar().setVisibility(View.VISIBLE);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.recycler_view_all_games, container, false);
mAllGamesRecyclerView = (RecyclerView) view.findViewById(R.id.all_games_recycler_view);
mAllGamesRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mSwipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipe_refresh);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
{
@Override
public void onRefresh()
{
getGamesData();
mSwipeRefreshLayout.setRefreshing(false);
}
});
return view;
}
@Override
public void onResume()
{
super.onResume();
getGamesData();
}
private void setupAdapter()
{
if(isAdded())
{
mGameAdapter = new GameAdapter(mGameList);
mAllGamesRecyclerView.setAdapter(mGameAdapter);
}
}
private void getGamesData()
{
new GetDataTask(mMainActivity.getLastSelectedDate()).execute();
}
private class GetDataTask extends Scraper.GameDataTask
{
GetDataTask(Date date)
{
super(date, getActivity());
}
@Override
protected void onPostExecute(List<Game> games)
{
mGameList = games;
setupAdapter();
mMainActivity.getProgressBar().setVisibility(View.GONE);
}
}
private class GameAdapter extends RecyclerView.Adapter<GameHolder>
{
private List<Game> mGames;
public GameAdapter(List<Game> games)
{
mGames = games;
}
@Override
public GameHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(getActivity());
View view = inflater.inflate(R.layout.list_game_item, parent, false);
return new GameHolder(view, getActivity());
}
@Override
public void onBindViewHolder(GameHolder holder, int position)
{
holder.bindGameData(mGames.get(position));
}
@Override
public int getItemCount()
{
return mGames.size();
}
}
我在这里查看了很多帖子,多次更改了我的代码,但我仍然无法让它工作.当我单击其中一个日期按钮时,我只是对它修复"感到困惑.如果您希望我发布更多代码,请告诉我.很抱歉这篇长文,但我觉得需要上下文.非常感谢任何帮助!
I've looked at so many posts on here, changed my code many times and I still can't get it to work. I'm just baffled that it "fixes" when I click one of the date buttons. If you would like me to post more code of something let me know. Sorry for the long post but I feel the context is needed. I really appreciate any help!
推荐答案
我想通了!我不得不切换到 FragmentStatePagerAdapter
而不是使用 FragmentPagerAdapter
.我认为这与 Fragments 被销毁并重新创建有关.
I figured it out! I had to switch to a FragmentStatePagerAdapter
rather than use a FragmentPagerAdapter
. I believe it has something to do with the Fragments being destroyed and recreated again.
我还读到另一种方法是将 ViewPager 包装在 Fragment 中,并在创建其适配器时使用 getChildFragmentManager()
而不是 getSupportFragmentManager()
像这样:
I also read that another way would be to wrap the ViewPager in a Fragment and when you create its adapter you use getChildFragmentManager()
rather than getSupportFragmentManager()
like this:
mAdapterViewPager = new MyPagerAdapter(getChildFragmentManager());
我不想为了解决这个问题而在 ViewPager 周围添加整个 Fragment,所以我改用 FragmentStatePagerAdapter
并且它起作用了!希望这对其他人有帮助.
I didn't want to have to add an entire Fragment around my ViewPager just to fix this issue so I switched to using FragmentStatePagerAdapter
and it worked! Hope this helps someone else out there.
这篇关于ViewPager 中的片段在其 RecyclerView 旋转时未显示任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:ViewPager 中的片段在其 RecyclerView 旋转时未显示任何内容
基础教程推荐
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01