使用父 Fragment 销毁 FragmentStatePagerAdapter 实例
Destroy FragmentStatePagerAdapter instance with parent Fragment
我不知道怎么问这个。我试过了 in here, but I guess I was not clear enough. So, I thought I just write a small App to describe the situation. Please note, the App uses Googles SlidingTabLayout.
长话短说,在任何时候,如果我单击 Button1,FrameLayout
应该包含 Fragment1
,删除 Fragment2
(如果存在)。因此,FragmentViewPager也应该被销毁为Fragment2
。但是,即使这样,如果我改变设备的方向,我也会得到在 FragmentViewPager
的 onCreate()
方法中定义的 Toast。
为什么即使 Fragment2
是 paused/destroyed 也会调用 FragmentViewPager
的 onCreate?难不成,FragmentViewPager
的Toast在Fragment2
被销毁后就不会显示了?
主要活动:
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(onClickListener);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(onClickListener);
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment;
switch (v.getId()){
case R.id.button1:
fragment = new Fragment1();
break;
case R.id.button2:
fragment = new Fragment2();
break;
default:
return;
}
getFragmentManager().beginTransaction().replace(R.id.frame_container, fragment, v.getTag().toString()).addToBackStack(null).commit();
}
};
}
片段1
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
public Fragment1(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1,container,false);
setHasOptionsMenu(true);
return rootView;
}
}
片段2
package com.abdfahim.testproject;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
public Fragment2(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment2,container,false);
setHasOptionsMenu(true);
CharSequence titles[]= {"Tab A", "Tab B"};
// Creating The ViewPagerAdapter
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getFragmentManager(), titles, titles.length);
ViewPager pager = (ViewPager) rootView.findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assigning the Sliding Tab Layout View
SlidingTabLayout tabs = (SlidingTabLayout) rootView.findViewById(R.id.tabs);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
return rootView;
}
static class ViewPagerAdapter extends FragmentStatePagerAdapter {
private CharSequence titles[];
private int numbOfTabs;
public ViewPagerAdapter(FragmentManager fm, CharSequence mTitles[], int mNumbOfTabs) {
super(fm);
this.titles = mTitles;
this.numbOfTabs = mNumbOfTabs;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("displayText", "Inside Fragment 2, " + titles[position]);
FragmentViewPager fragment = new FragmentViewPager();
fragment.setArguments(bundle);
return fragment;
}
// This method return the titles for the Tabs in the Tab Strip
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
// This method return the Number of tabs for the tabs Strip
@Override
public int getCount() {
return numbOfTabs;
}
}
}
FragmentViewPager
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
public class FragmentViewPager extends Fragment {
public FragmentViewPager(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_view_pager,container,false);
setHasOptionsMenu(true);
Bundle bundle = this.getArguments();
TextView textView = (TextView) rootView.findViewById(R.id.tabText);
textView.setText(bundle.getString("displayText"));
return rootView;
}
@Override
public void onStart() {
super.onStart();
Toast.makeText(getActivity(), "This is View Pager Fragment", Toast.LENGTH_SHORT).show();
}
}
每次点击您的 OnClickListener
都会创建 Fragment2
的实例,但不会创建 Fragment1
。那是由于误用了View#getTag
.
在MainActivity#onCreate
中,将onClickListener
定义中的if
改成这样(使用this answer):
switch (v.getId()){
case R.id.button1:
fragment = new Fragment1();
break;
case R.id.button2:
fragment = new Fragment2();
break;
default:
return;
}
在您的代码中,在单击时检查的 if
中(例如单击 button1
后)android 询问 v
(单击的 View
) 为其标签 - 但由于 none 是使用 View#setTag 设置的 - 它 returns null
当然不等于为 String
创建的对象"button1",因此 if
每次都会恢复为 else
。
当您在另一个片段中使用片段时。您使用 getChildFragmentManager() 而不是 getFragmentManager。您可以从 onCreateView() 或 onActivityCreated()
为 ViewPager 调用 setAdapter()
了解更多详情。看看吧
Why it is not possible to use ViewPager within a Fragment? It actually is
我不知道怎么问这个。我试过了 in here, but I guess I was not clear enough. So, I thought I just write a small App to describe the situation. Please note, the App uses Googles SlidingTabLayout.
长话短说,在任何时候,如果我单击 Button1,FrameLayout
应该包含 Fragment1
,删除 Fragment2
(如果存在)。因此,FragmentViewPager也应该被销毁为Fragment2
。但是,即使这样,如果我改变设备的方向,我也会得到在 FragmentViewPager
的 onCreate()
方法中定义的 Toast。
为什么即使 Fragment2
是 paused/destroyed 也会调用 FragmentViewPager
的 onCreate?难不成,FragmentViewPager
的Toast在Fragment2
被销毁后就不会显示了?
主要活动:
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(onClickListener);
Button button2 = (Button) findViewById(R.id.button2);
button2.setOnClickListener(onClickListener);
}
private View.OnClickListener onClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
Fragment fragment;
switch (v.getId()){
case R.id.button1:
fragment = new Fragment1();
break;
case R.id.button2:
fragment = new Fragment2();
break;
default:
return;
}
getFragmentManager().beginTransaction().replace(R.id.frame_container, fragment, v.getTag().toString()).addToBackStack(null).commit();
}
};
}
片段1
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment1 extends Fragment {
public Fragment1(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment1,container,false);
setHasOptionsMenu(true);
return rootView;
}
}
片段2
package com.abdfahim.testproject;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
import android.support.v13.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class Fragment2 extends Fragment {
public Fragment2(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment2,container,false);
setHasOptionsMenu(true);
CharSequence titles[]= {"Tab A", "Tab B"};
// Creating The ViewPagerAdapter
ViewPagerAdapter adapter = new ViewPagerAdapter(getActivity().getFragmentManager(), titles, titles.length);
ViewPager pager = (ViewPager) rootView.findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assigning the Sliding Tab Layout View
SlidingTabLayout tabs = (SlidingTabLayout) rootView.findViewById(R.id.tabs);
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
return rootView;
}
static class ViewPagerAdapter extends FragmentStatePagerAdapter {
private CharSequence titles[];
private int numbOfTabs;
public ViewPagerAdapter(FragmentManager fm, CharSequence mTitles[], int mNumbOfTabs) {
super(fm);
this.titles = mTitles;
this.numbOfTabs = mNumbOfTabs;
}
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
@Override
public Fragment getItem(int position) {
Bundle bundle = new Bundle();
bundle.putString("displayText", "Inside Fragment 2, " + titles[position]);
FragmentViewPager fragment = new FragmentViewPager();
fragment.setArguments(bundle);
return fragment;
}
// This method return the titles for the Tabs in the Tab Strip
@Override
public CharSequence getPageTitle(int position) {
return titles[position];
}
// This method return the Number of tabs for the tabs Strip
@Override
public int getCount() {
return numbOfTabs;
}
}
}
FragmentViewPager
package com.abdfahim.testproject;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
public class FragmentViewPager extends Fragment {
public FragmentViewPager(){}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_view_pager,container,false);
setHasOptionsMenu(true);
Bundle bundle = this.getArguments();
TextView textView = (TextView) rootView.findViewById(R.id.tabText);
textView.setText(bundle.getString("displayText"));
return rootView;
}
@Override
public void onStart() {
super.onStart();
Toast.makeText(getActivity(), "This is View Pager Fragment", Toast.LENGTH_SHORT).show();
}
}
每次点击您的 OnClickListener
都会创建 Fragment2
的实例,但不会创建 Fragment1
。那是由于误用了View#getTag
.
在MainActivity#onCreate
中,将onClickListener
定义中的if
改成这样(使用this answer):
switch (v.getId()){
case R.id.button1:
fragment = new Fragment1();
break;
case R.id.button2:
fragment = new Fragment2();
break;
default:
return;
}
在您的代码中,在单击时检查的 if
中(例如单击 button1
后)android 询问 v
(单击的 View
) 为其标签 - 但由于 none 是使用 View#setTag 设置的 - 它 returns null
当然不等于为 String
创建的对象"button1",因此 if
每次都会恢复为 else
。
当您在另一个片段中使用片段时。您使用 getChildFragmentManager() 而不是 getFragmentManager。您可以从 onCreateView() 或 onActivityCreated()
为 ViewPager 调用 setAdapter()了解更多详情。看看吧
Why it is not possible to use ViewPager within a Fragment? It actually is