片段ViewPager未在其上旋转RecyclerView显示任何内容 [英] Fragment in ViewPager is not displaying anything in its RecyclerView on rotation

查看:390
本文介绍了片段ViewPager未在其上旋转RecyclerView显示任何内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个与TabLayout一体的ViewPager 4个片段。每个那些片段的持有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.

到目前为止的所有作品完美,但一旦我旋转设备碎片不加载任何东西。什么是片段内显示。在外部活动的意见显示,虽然罚款。奇怪的是,如果我触摸更改日期的一个按钮时,片段被加载并正确显示的数据。但我需要的一切旋转之后立即显示不只是当我点击这些按钮中的一个。这里是我的code:

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();
    }
}

2个按钮米prevDateButton mNextDateButton 是当点击修复的问题按钮。里面他们的点击听众,在 updateDate()方法仅做与一个TextView对象的东西,所以我并没有包括定义(我试图保持张贴尽可能短)。所以我肯定知道它是与我的 setupViewPagerAdapter()方法。我在的onCreate尝试添加这个方法() onResume()但碎片仍停留空白。

The 2 buttons mPrevDateButton and mNextDateButtonare 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适配器code:

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片段之一。他们pretty多少都有类似的设计。

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();
        }
    }

我看了那么多帖子放在这里,改变了我的code很多次,我仍然不能得到它的工作。我只是困惑,它修复当我点击日期按钮之一。如果你想我张贴的东西更code让我知道。很抱歉的长期职位,但我觉得是需要的上下文。我真的AP preciate任何帮助!

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 。我相信这是与被摧毁和重建再次将片段。

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的片段,当你创建它的适配器,使用 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整个片段只是为了让我转向使用 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显示任何内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆