切换时,ViewPager不会更新每个选项卡内的RecylcerView

时间:2017-07-01 01:45:35

标签: android android-fragments android-viewpager static-classes

我有一个ViewPager,我在一个简单的示例应用程序中设置。我有一个静态片段作为内部类实现,其中包含RecylerView。我想根据我所在的选项卡更改RecyclerView的LayoutManager。我的实现如下所示。这不适合我。当我加载此ViewPager时,它从第一个位置开始,但具有交错布局(应该是第三个位置)。当我向上滑动到第二个位置时,它仍然是交错布局,因为我的PagerAdapter的getItem()方法从未被调用,所以没有任何改变。当我切换到第3个位置时,调用getItem()并重新加载RecylerView,但它仍然具有交错布局(这实际上应该是交错布局)。

在ViewPagers上读了一下之后,我意识到PagerAdapter会在确定它可以的情况下重用该片段。我想这就是这里发生的事情。有没有办法防止这种情况发生?只使用一个片段,我可以让LayoutManager切换每个标签吗?基本上我希望它为每个选项卡实例化一个新的片段。

public class TabbedActivity extends AppCompatActivity {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link FragmentPagerAdapter} derivative, which will keep every
     * loaded fragment in memory. If this becomes too memory intensive, it
     * may be best to switch to a
     * {@link android.support.v4.app.FragmentStatePagerAdapter}.
     */
    private SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    private ViewPager mViewPager;

    public static Intent newIntent(Context packageContext){
        Intent intent = new Intent(packageContext, TabbedActivity.class);
        return intent;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tabbed);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(mViewPager);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_tabbed, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public static class RecyclerFragment extends Fragment {

        private static final String ARG_LAYOUT_TYPE = "layout-type";

        private int layoutType = 0;

        RecyclerView recyclerView;
        public ArrayList<AndroidVersion> data;
        public DataAdapter adapter;

        public static final int FRAGMENT_LINEAR = 0;
        public static final int FRAGMENT_GRID = 1;
        public static final int FRAGMENT_STAG_GRID = 2;

        public static RecyclerFragment newInstance(int layoutType) {
            Timber.d("newInstance() called with int: " + layoutType);
            RecyclerFragment fragment = new RecyclerFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_LAYOUT_TYPE, layoutType);
            fragment.setArguments(args);
            return fragment;
        }

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

            if(getArguments() != null){
                layoutType = getArguments().getInt(ARG_LAYOUT_TYPE);
            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
            View rootView = inflater.inflate(R.layout.fragment_linear, container, false);

            Button button = (Button) rootView.findViewById(R.id.view_pager_button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent mainActivityIntent = MainActivity.newIntent(getActivity().getApplicationContext());
                    startActivity(mainActivityIntent);
                }
            });

            recyclerView = (RecyclerView) rootView.findViewById(R.id.card_recyler_view_pager);
            //recyclerView.setHasFixedSize(true);

            // Check to see what the layout type should be and create the necessary LayoutManager
            switch(layoutType){
                case FRAGMENT_LINEAR:
                    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false);
                    recyclerView.setLayoutManager(layoutManager);
                case FRAGMENT_GRID:
                    GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
                    recyclerView.setLayoutManager(gridLayoutManager);
                case FRAGMENT_STAG_GRID:
                    StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
                    recyclerView.setLayoutManager(staggeredGridLayoutManager);
            }

            loadJSON();

            return rootView;
        }

        private void loadJSON() {
            Retrofit retrofit = MainActivity.getRestAdapter();
            RequestInterface request = retrofit.create(RequestInterface.class);
            Call<JSONResponse> call = request.getJSON();
            call.enqueue(new Callback<JSONResponse>() {
                @Override
                public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
                    JSONResponse jsonResponse = response.body();
                    data = new ArrayList<>(Arrays.asList(jsonResponse.getAndroid()));
                    adapter = new DataAdapter(data);
                    recyclerView.setAdapter(adapter);
                }

                @Override
                public void onFailure(Call<JSONResponse> call, Throwable t) {
                    Log.d("Error", t.getMessage());
                }
            });
        }

    }

    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentPagerAdapter {

        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            Timber.d("getItem called, position: " + position);
            return RecyclerFragment.newInstance(position);
        }

        @Override
        public int getCount() {
            // Show 3 total pages.
            return 3;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return "Linear";
                case 1:
                    return "Grid";
                case 2:
                    return "Staggered";
            }
            return null;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

试试这个:

RecyclerFragment类中的

定义了一个静态变量:

private static RecyclerFragment instance = null;

并更改newInstance方法,如下所示:

public static RecyclerFragment newInstance(int layoutType) {
            Timber.d("newInstance() called with int: " + layoutType);
            instance =new RecyclerFragment();
            Bundle args = new Bundle();
            args.putInt(ARG_LAYOUT_TYPE, layoutType);
            instance.setArguments(args);
            return instance;
        }