从片段RecycerView适配器替换ViewPager内部的片段返回空白屏幕?

时间:2018-12-18 02:06:33

标签: android android-fragments

单击片段的recycelerview中的项目时,我试图替换ViewPager中的当前活动片段。到目前为止,单击第一个片段上的项目时,我设法在第二个片段上弹出Toast,但是第二个片段的全部视图为空白。

这是我的代码:

MainActivity.class

public class MainActivity extends AppCompatActivity {
    
    private ViewPager viewPager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        viewPager = findViewById(R.id.view_pager);
        FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager());
        
        viewPager.setAdapter(adapter);
        viewPager.setOffscreenPageLimit(adapter.getCount() - 1);
    
    }
    
    // ..........
    
    private static class FragmentAdapter extends FragmentStatePagerAdapter {

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

        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return AllGenreFragment.newInstance();
                case 1:
                    return DashboardFragment.newInstance();
                case 2:
                    return NotificationFragment.newInstance();
            }
            return null;
        }

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

AllGenreFragment.class

public class AllGenreFragment extends Fragment {

    RecyclerView genreRV;
    private AllGenreAdapter allGenreAdapter;
    private List<Genre> genreList;
    
    public static AllGenreFragment newInstance() {
        return new AllGenreFragment();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_genre, container, false);

        genreRV = v.findViewById(R.id.rv);
        genreRV.setHasFixedSize(true);
        GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
        genreRV.setLayoutManager(layoutManager);
        genreList = new ArrayList<>();
        allGenreAdapter = new AllGenreAdapter(genreList, getContext());
        genreRV.setAdapter(allGenreAdapter);

        return v;
    }

}

AllGenreAdapter.class

public class AllGenreAdapter extends RecyclerView.Adapter<AllGenreAdapter.ViewHolder> {

    // .......
    
    class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {

        public ViewHolder(final View itemView) {
            super(itemView);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                
                    Toast.makeText(context, "Genre: " + genre_title.getText().toString(), Toast.LENGTH_SHORT).show();

                    AppCompatActivity activity = (AppCompatActivity) itemView.getContext();

                    FragmentManager fragmentManager = activity.getSupportFragmentManager();
                    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

                    Fragment allAnimeFragment = new AllAnimeFragment();

                    Bundle bundle = new Bundle();
                    bundle.putString("genreid", genre_id.getText().toString().trim());
                    allAnimeFragment.setArguments(bundle);

                    fragmentTransaction.replace(R.id.view_pager, allAnimeFragment);
                    fragmentTransaction.addToBackStack(null);
                    fragmentTransaction.commit();

                }
            });

        }

    }

    // .......

}

AllAnimeFragment.class

public class AllAnimeFragment extends Fragment {

    RecyclerView animeRV;
    private AllAnimeAdapter allAnimeAdapter;
    private List<Anime> animeList;
    String genreid;

    public static AllAnimeFragment newInstance() {
        return new AllAnimeFragment();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_anime, container, false);

        Bundle arguments = getArguments();
        genreid = arguments.getString("genreid");
        
        Toast.makeText(getContext(), genreid, Toast.LENGTH_SHORT).show();
        
        // .....

        return v;
    }
}

2 个答案:

答案 0 :(得分:0)

您应该在适配器的构造函数中添加上下文

public class AllGenreAdapter(Context context) extends RecyclerView.Adapter<AllGenreAdapter.ViewHolder> {
// ....... 
}

然后将您的活动传递给适配器,用它来替换片段

答案 1 :(得分:0)

您的方法并不是很好,请尝试以下方法:

  • 创建一个名为ContainerFragment的容器片段,例如,您将为ViewPager使用该片段。

  • ContainerFragment应该包含一个容器视图,并在第一个被调用的AllGenreFragment中添加。

  • AllGenreFragment中创建一个回调,当单击RecyclerView中的某个项目时,然后在ContainerFragment中将替换(或添加)当前片段({{1} })到AllGenreFragment

首先,创建AllAnimeFragment

ContainerFragment

此片段应实现public class ContainerFragment extends Fragment implements AllGenreFragment.OnAllGenreFragmentListener { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_container, container, false); } @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); initialLoad(); } private void initialLoad() { getChildFragmentManager() .beginTransaction() .add(R.id.container, AllGenreFragment.newInstance()) .commit(); } @Override public void OnItemClick() { getChildFragmentManager() .beginTransaction() .replace(R.id.container, AllAnimeFragment.newInstance()) .commit(); } } 的回调以处理片段事务。

还有AllGenreFragment布局

xml

下一步,将上面的片段添加到<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" /> 中,我们使用ViewPager而不是ContainerFragment

AllGenreFragment

好,现在回到 @Override public Fragment getItem(int position) { switch (position) { case 0: return ContainerFragment().newInstance(); case 1: return DashboardFragment.newInstance(); case 2: return NotificationFragment.newInstance(); } return null; } ,我们应该创建一个在AllGenreFragment中实现的CallBack

ContainerFragment

然后

public interface AllGenreFragmentListener {
     onItemClicked();
}

因此我们有一个private AllGenreFragmentListener listener; @Override public void onAttach(Context context) { super.onAttach(context); if (getParentFragment() instanceof AllGenreFragmentListener) { listener = (AllGenreFragmentListener) getParentFragment(); } } 的实例,从现在开始,每当AllGenreFragmentListener调用listener时,onItemClicked中的方法onItemClicked将被调用。

好吧,让它

在您的ContainerFragment中创建以下变量和方法:

AllGenreAdapter

并更新您的private AllGenreFragmentListener listener; public void setListener(AllGenreFragmentListener listener) { this.listener = listener; }

ViewHodler

请不要忘记在您的itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context, "Genre: " + genre_title.getText().toString(), Toast.LENGTH_SHORT).show(); if (listener != null) listener.onItemClicked() }); } 中调用setListener方法,因此请添加

AllGenreFragment

全部,

我是手动输入此代码的,而不是在我的IDE中输入的,因此它可能无法编译,因此如果遇到任何编译错误,请修复它。

注意

如果要保持@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); if (allGenreAdapter != null) allGenreAdapter.setListener(listener); } 按钮的行为,请在BACK中覆盖OnBackPressed

MainActivity

此外,每当我们将片段添加到容器视图(在您的@Override public void onBackPressed() { Fragment f = getCurrentFragment(); if (f != null) { if (f.getChildFragmentManager().getBackStackEntryCount() > 1) { f.getChildFragmentManager().popBackStack(); } else { super.onBackPressed(); } } else { super.onBackPressed(); } } public Fragment getCurrentFragment() { return (Fragment) viewPager.getAdapter() .instantiateItem(viewPager, viewPager.getCurrentItem()); } 中)时,都将片段添加到backStack

ContainerFragment