Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get current selected Fragment in FragmentTabHost

There are some questions related to this same issue. For example, this one. But it doesn't work.

Let me show 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 include a 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 the fragment corresponding to different tab, they are similar so that I only show you 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 the BaseFragment is always null in my onTabChanged. Can anybody help? Thanks.

like image 956
Bagusflyer Avatar asked Jan 09 '15 04:01

Bagusflyer


People also ask

How do you get current visible fragments?

To get the current fragment that's active in your Android Activity class, you need to use the supportFragmentManager object. The supportFragmentManager has findFragmentById() and findFragmentByTag() methods that you can use to get a fragment instance.

What is FrameLayout in fragment?

FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other.

How do you know if a fragment is visible?

Now I know which fragments are not visible to user. Another problem is to detect when fragment is visible to user. The easiest solution was to add code to. userVisibleHint = true to previous method but we will not cover case when user click back button ( popBackStack() executes).


1 Answers

You cannot get the selected fragment immediately if the fragment has never been instantiated.

@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);
    }
}

the output:

// 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}
like image 107
li2 Avatar answered Nov 13 '22 19:11

li2