How to get the currently selected fragment in FragmentTabHost

There are several issues related to this problem. For example, this one . But that does not work.

Let me show you what I did in my code.

activity_main.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" tools:ignore="MergeRootFrame" > <fragment android:id="@+id/my_fragment" android:layout_width="match_parent" android:layout_height="match_parent" android:name="com.example.zhouhao.test.MyFragment" tools:layout="@layout/fragment_my" /> </FrameLayout> 

fragment_my.xml (my main fragment, which includes FragmentTabHost)

 <?xml version="1.0" encoding="utf-8"?> <android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:weightSum="100" android:orientation="horizontal"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="0dp" android:layout_height="0dp" android:layout_weight="0" /> <LinearLayout android:layout_width="0dp" android:layout_weight="95" android:layout_height="match_parent" android:orientation="vertical"> <FrameLayout android:id="@+id/panel_content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout> </LinearLayout> </android.support.v4.app.FragmentTabHost> 

fragment_tab1.xml (for a fragment corresponding to another tab, they are similar, so I only show one code)

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.zhouhao.test.TabFragment"> <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/fragment_tab1" /> </FrameLayout> 

MainActivity.java

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { FragmentManager fm = getSupportFragmentManager(); mMyFragment = (MyFragment) fm.findFragmentById(R.id.my_fragment); } } 

public class MyFragment extends Fragment implements TabHost.OnTabChangeListener {

 FragmentTabHost mFragmentTabHost; public MyFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_my, container, false); if (rootView != null) { mFragmentTabHost = (FragmentTabHost) rootView.findViewById(android.R.id.tabhost); mFragmentTabHost.setup(getActivity(), getActivity().getSupportFragmentManager(), R.id.panel_content); TabFragment1 tab1Fragment = new TabFragment1(); TabFragment2 tab2Fragment = new TabFragment2(); TabFragment3 tab3Fragment = new TabFragment3(); TabHost.TabSpec spec1 = mFragmentTabHost.newTabSpec("1").setIndicator(""); TabHost.TabSpec spec2 = mFragmentTabHost.newTabSpec("2").setIndicator(""); TabHost.TabSpec spec3 = mFragmentTabHost.newTabSpec("3").setIndicator(""); mFragmentTabHost.addTab(spec1,tab1Fragment.getClass(), null); mFragmentTabHost.addTab(spec2,tab2Fragment.getClass(), null); mFragmentTabHost.addTab(spec3,tab3Fragment.getClass(), null); mFragmentTabHost.setOnTabChangedListener(this); return rootView; } else { return super.onCreateView(inflater, container, savedInstanceState); } } @Override public void onTabChanged(String tabId) { BaseFragment f = (BaseFragment)getActivity().getSupportFragmentManager().findFragmentByTag(tabId); Log.d("Log",tabId); } 

}

My problem is that BaseFragment is always null in my onTabChanged. Can anyone help? Thanks.

+6
source share
2 answers

You cannot get the selected fragment right away if the fragment has never been created.

 @Override public void onTabChanged(final String tabId) { Fragment fg = getSupportFragmentManager().findFragmentByTag(tabId); Log.d(TAG, "onTabChanged(): " + tabId + ", fragment " + fg); if (fg == null) { new Handler().postDelayed(new Runnable() { @Override public void run() { Fragment fg = getSupportFragmentManager().findFragmentByTag(tabId); Log.d(TAG, "onTabChanged() delay 50ms: " + tabId + ", fragment " + fg); } }, 50); } } 

conclusion:

 // cannot get the selected fragment immediately if the fragment has never been instantiated. onTabChanged(): 1, fragment null onTabChanged() delay 50ms: 1, fragment HistoryFragment{6f7a9d5 #2 id=0x7f09006e 1} onTabChanged(): 2, fragment null onTabChanged() delay 50ms: 2, fragment HistoryFragment{10c59e72 #3 id=0x7f09006e 2} // can get the selected fragment immediately if the fragment already instantiated. onTabChanged(): 1, fragment HistoryFragment{6f7a9d5 #2 id=0x7f09006e 1} onTabChanged(): 2, fragment HistoryFragment{10c59e72 #3 id=0x7f09006e 2} 
+4
source

I think I found the right way to solve this problem, below is my answer.

  1. Create TabBean
 private int imgId; private int textId; private Class fragment; public MainTabBean(int textId, int imgId, Class fragment) { this.textId = textId; this.imgId = imgId; this.fragment = fragment; } public int getTextId() { return textId; } public void setTextId(int textId) { this.textId = textId; } public int getImgId() { return imgId; } public void setImgId(int imgId) { this.imgId = imgId; } public Class getFragment() { return fragment; } public void setFragment(Class fragment) { this.fragment = fragment; } 
  1. Then get three instances of TabBean with three fragments
 List<MainTabBean> tabs = new ArrayList<>(); // three TabBean instances TabBean homeTab = new MainTabBean(R.string.home, R.drawable.tab_home, HomepageFragment.class); TabBean postcardTab = new MainTabBean(R.string.postcard, R.drawable.tab_postcard, PostcardFragment.class); Bean notificationTab = new MainTabBean(R.string.notification, R.drawable.tab_notification, NotificationFragment.class); // put tabs into a list tabs.add(homeTab); tabs.add(postcardTab); tabs.add(notificationTab); 
  1. Third, just bind TabBeans to FragmentTabHost as usual
 // Obtain FragmentTabHost tabHost = findViewById(android.R.id.tabhost); // Associate fragmentManager with container tabHost.setup(this, getSupportFragmentManager(), R.id.main_content); // Create TabSpecs with TabBean and add it on TabHost for(MainTabBean tab : tabs) { TabHost.TabSpec spec = tabHost.newTabSpec(String.valueOf(tab.getTextId()))// set a tag .setIndicator(getTabIndicator(tab));// set an indicator tabHost.addTab(spec, tab.getFragment(), null);// add a tab } 
  1. Fourth, this is the most important step, I did not get an instance of the fragment with findFragmentByTag () like this
 getSupportFragmentManager() .findFragmentByTag(String.valueOf(tabs.get(1).getTextId())); 

Instead, my answer is exactly this:

 tabs.get(0).getFragment().newInstance(); 

and play it .

And I finally got a snippet.

+1
source

Source: https://habr.com/ru/post/1210713/


All Articles