我正在尝试替换ViewPager内部的当前活动片段时,当figern fragment的Recycelerview中单击时。到目前为止,当单击第一个片段上的项目时,我设法在第二片片段上弹出吐司,但是第二片的所有视图都是空白的。
这是我的代码:
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;
}
}
// ..........
}
allgerrefragment.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;
}
}
您的方法不是很好,请在下面尝试:
-
创建一个称为
ContainerFragment
的容器片段,例如,您将使用此片段用于ViewPager
。 -
ContainerFragment
应包含一个容器视图,并在第一个中添加AllGenreFragment
。 -
在
AllGenreFragment
中,创建回调,当单击RecyclerView
中的项目时,ContainerFragment
中的项目将替换(或添加)当前片段(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 onItemClicked() {
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
时,ContainerFragment
中的方法onItemClicked
将被调用。
好吧,让我们做,
在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()
});
}
不要忘记AllGenreFragment
中的setListener
方法,所以请添加
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (allGenreAdapter != null) allGenreAdapter.setListener(listener);
}
全部,
我手工键入此代码,而不是在我的IDE中键入该代码,因此也许不会编译,因此,如果您遇到任何编译错误,请修复它。
注意
如果要保留BACK
按钮的行为,请在MainActivity
中覆盖onBackPressed
@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());
}
另外,每当我们将片段添加到容器视图(在您的ContainerFragment
中)
backStack
中 private void initialLoad() {
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, AllGenreFragment.newInstance())
.addToBackStack(null)
.commit();
}
@Override public void onItemClicked() {
// change `replace` to `add` and add more `.addToBackStack(null)`
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, AllAnimeFragment.newInstance())
.addToBackStack(null)
.commit();
}
您应该在适配器的构造函数中添加上下文
public class AllGenreAdapter(Context context) extends RecyclerView.Adapter<AllGenreAdapter.ViewHolder> {
// .......
}
然后将您的活动传递给适配器,用它来替换片段