如何从嵌套在 NavigationView 片段中的 ViewPager 片段中的项目的单击事件中获取 Activity containerViewId?
How to get Activity containerViewId from click event on item in ViewPager fragment nested in NavigationView Fragment?
我有一个带有 NavigationView 的 Activity。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.app.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="@+id/containerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" ></RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
启动应用程序或单击 NavigationView 项目时,会调用以下内容:
fragmentManager.beginTransaction().replace(R.id.containerView, new NavFragment()).commit();
其中:
FragmentManager fragmentManager = getSupportFragmentManager();
NavFragment
具有以下布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/tabContainer">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:theme="@style/AppTheme.AppBarOverlay"
android:background="@color/colorPrimary"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
并包含一个选项卡式 ViewPager:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.nav_frag, container, false);
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
String tab1 = getResources().getString(R.string.tab_1);
String tab2= getResources().getString(R.string.tab_2);
String tab3 = getResources().getString(R.string.tab_3);
adapter.addFragment(new Frag1(), tab1);
adapter.addFragment(new Frag2(), tab2);
adapter.addFragment(new Frag3(), tab3);
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
然后每个 ViewPager
片段都包含自己的 RecyclerView
项。
现在我的问题是,我在 onClick
中为嵌套 ViewPager
选项卡中的 RecyclerView
项放入什么,调用相同的主容器,containView
在 MainActivity
布局中?
也就是说,我如何引用该容器?基本上,我需要新片段来替换 tablayout
和 ViewPager
。然后单击后退按钮,使其 return 到单击项目的 ViewPager
位置,调用新 activity 时的方式。
按照以下思路思考:
fragmentManager.beginTransaction().replace(R.id.containerView, new ClickedItemFrag()).commit();
调用片段而不是新 activity 的目的是维护 NavigationView
中的所有内容。我看了又看,但找不到解决我试图引用 containerView
.
的困境的有效解决方案
提前致谢。
编辑:我尝试使用:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent()).getId(), ClickedItemFrag()).commit();
给出:
09-27 12:48:16.720 17000-17000/com.example.app E/FragmentManager: No view found for id 0x7f0d0138 (com.example.app:id/viewpager) for fragment ClickedItemFrag{b189f1c #0 id=0x7f0d0138}
然后:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent().getParent()).getId(), ClickedItemFrag()).commit();
给出:
09-27 12:43:12.999 13621-13621/com.example.app E/FragmentManager: No view found for id 0x7f0d0135 (com.example.app:id/tabContainer) for fragment ClickedItemFrag{68c33f0 #0 id=0x7f0d0135}
然后:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent().getParent().getParent()).getId(), ClickedItemFrag()).commit();
给出:
java.lang.IllegalArgumentException: No view found for id 0x7f0d0075 (com.example.app:id/containerView) for fragment ClickedItemFrag{4f136ab #0 id=0x7f0d0075}
在包含所有布局的 Activity 中添加方法 navigateToFragment()
:
class MainActivity extends Activity {
// ..Your code here
public void navigateToFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.add(R.id.containerView, fragment)
.addToBackStack(null)
.commit();
}
}
然后,当您的 RecyclerView 中的某个项目被单击时,您会从 Frag1、Frag2、Frag3 片段中调用 navigateToFragment()
:
((MainActivity) getActivity()).navigateToFragment(new ClickedItemFrag());
我有一个带有 NavigationView 的 Activity。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true"
tools:context="com.example.app.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="@+id/containerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" ></RelativeLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"/>
</android.support.v4.widget.DrawerLayout>
启动应用程序或单击 NavigationView 项目时,会调用以下内容:
fragmentManager.beginTransaction().replace(R.id.containerView, new NavFragment()).commit();
其中:
FragmentManager fragmentManager = getSupportFragmentManager();
NavFragment
具有以下布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:id="@+id/tabContainer">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:theme="@style/AppTheme.AppBarOverlay"
android:background="@color/colorPrimary"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</LinearLayout>
并包含一个选项卡式 ViewPager:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.nav_frag, container, false);
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.viewpager);
TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
return rootView;
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
String tab1 = getResources().getString(R.string.tab_1);
String tab2= getResources().getString(R.string.tab_2);
String tab3 = getResources().getString(R.string.tab_3);
adapter.addFragment(new Frag1(), tab1);
adapter.addFragment(new Frag2(), tab2);
adapter.addFragment(new Frag3(), tab3);
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
然后每个 ViewPager
片段都包含自己的 RecyclerView
项。
现在我的问题是,我在 onClick
中为嵌套 ViewPager
选项卡中的 RecyclerView
项放入什么,调用相同的主容器,containView
在 MainActivity
布局中?
也就是说,我如何引用该容器?基本上,我需要新片段来替换 tablayout
和 ViewPager
。然后单击后退按钮,使其 return 到单击项目的 ViewPager
位置,调用新 activity 时的方式。
按照以下思路思考:
fragmentManager.beginTransaction().replace(R.id.containerView, new ClickedItemFrag()).commit();
调用片段而不是新 activity 的目的是维护 NavigationView
中的所有内容。我看了又看,但找不到解决我试图引用 containerView
.
提前致谢。
编辑:我尝试使用:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent()).getId(), ClickedItemFrag()).commit();
给出:
09-27 12:48:16.720 17000-17000/com.example.app E/FragmentManager: No view found for id 0x7f0d0138 (com.example.app:id/viewpager) for fragment ClickedItemFrag{b189f1c #0 id=0x7f0d0138}
然后:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent().getParent()).getId(), ClickedItemFrag()).commit();
给出:
09-27 12:43:12.999 13621-13621/com.example.app E/FragmentManager: No view found for id 0x7f0d0135 (com.example.app:id/tabContainer) for fragment ClickedItemFrag{68c33f0 #0 id=0x7f0d0135}
然后:
fragmentManager.beginTransaction().replace(((ViewGroup)getView().getParent().getParent().getParent()).getId(), ClickedItemFrag()).commit();
给出:
java.lang.IllegalArgumentException: No view found for id 0x7f0d0075 (com.example.app:id/containerView) for fragment ClickedItemFrag{4f136ab #0 id=0x7f0d0075}
在包含所有布局的 Activity 中添加方法 navigateToFragment()
:
class MainActivity extends Activity {
// ..Your code here
public void navigateToFragment(Fragment fragment) {
getSupportFragmentManager().beginTransaction()
.add(R.id.containerView, fragment)
.addToBackStack(null)
.commit();
}
}
然后,当您的 RecyclerView 中的某个项目被单击时,您会从 Frag1、Frag2、Frag3 片段中调用 navigateToFragment()
:
((MainActivity) getActivity()).navigateToFragment(new ClickedItemFrag());