Converting ActivityGroup app to use Fragments/FragmentGroup

寵の児 提交于 2019-12-21 17:28:07

问题


I have an app that I desperately need to convert from using the old ActivityGroup class to Fragments. I'm not sure how to go about it though. Below is a sample of the code I use now. Could anyone provide some insight into what steps I should take to start switching it over to use Fragments / FragmentManager instead?

Main.java

public class Main extends TabActivity implements OnTabChangeListener {

    public static TextView txtViewHeading;
    public static Button btnBack;
    public static ImageButton btnShare;
    public static Main mainActivity;
    public static Boolean isVisible = false;
    private GoogleCloudMessaging gcm;
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mainActivity = this;
        NotificationsManager.handleNotifications(this, NotificationSettings.SenderId, PushHandler.class);
        registerWithNotificationHubs();

        //reference headings text & button for access from child activities
        txtViewHeading = (TextView) findViewById(R.id.txtViewHeading);
        btnBack = (Button) findViewById(R.id.btnBack);
        btnShare = (ImageButton) findViewById(R.id.btnShare);

        // Update the font for the heading and back button
        Typeface arialTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/arial.ttf");
        Typeface myriadTypeface = Typeface.createFromAsset(getApplicationContext().getAssets(), "fonts/myriad.ttf");
        txtViewHeading.setTypeface(myriadTypeface);
        btnBack.setTypeface(arialTypeface);

        Resources res = getResources();
        TabHost tabsNavigation = getTabHost();

        // Set up the views for each tab - custom view used for Badge icon
        LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        // Set up my tabs...each one looks similar to this
        View statusTabView = inflater.inflate(R.layout.tab, null);
        ImageView statusTabIcon = (ImageView) statusTabView.findViewById(R.id.tabIcon);
        statusTabIcon.setImageResource(R.drawable.tab_first);
        TextView statusTabText = (TextView) statusTabView.findViewById(R.id.tabText);
        statusTabText.setText("Status");
        statusTabText.setTypeface(arialTypeface);
        statusTabBadge = (TextView) statusTabView.findViewById(R.id.tabBadge);
        statusTabBadge.setTypeface(arialTypeface);
        tabsNavigation.addTab(tabsNavigation.newTabSpec(getResources().getString(R.string.main_tab_status))
                .setIndicator(statusTabView)
                .setContent(new Intent(this, StatusGroupActivity.class)
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)));

        //Set default tab to Status
        tabsNavigation.setCurrentTab(0);
        tabsNavigation.setOnTabChangedListener(this);

    }


    /* Set txtViewHeading text to selected tab text */
    @Override
    public void onTabChanged(String tabId) {
        // TODO Auto-generated method stub
        txtViewHeading.setText(tabId);
    }

    /* Set code to execute when onDestroy method is called */
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
    }


    /* Set code to execute when onPause method is called */
    @Override
    protected void onPause() {
        super.onPause();
        isVisible = false;
    }

    /* Set code to execute when onResume method is called */
    @Override
    protected void onResume() {
        super.onResume();
        isVisible = true;
    }


    /* Set code to execute when onStop method is called */
    @Override
    protected void onStop() {
        super.onStop();
        isVisible = false;
    }

    /**
     * Check the device to make sure it has the Google Play Services APK. If
     * it doesn't, display a dialog that allows users to download the APK from
     * the Google Play Store or enable it in the device's system settings.
     */
    private boolean checkPlayServices() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
                        .show();
            } else {
                ToastNotify("This device is not supported by Google Play Services.");
                finish();
            }
            return false;
        }

        return true;
    }

    public void ToastNotify(final String notificationMessage) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(Main.this, notificationMessage, Toast.LENGTH_LONG).show();
            }
        });
    }

    public void registerWithNotificationHubs()
    {
        if (checkPlayServices()) {
            // Start IntentService to register this application with GCM.
            Intent intent = new Intent(this, RegistrationIntentService.class);
            startService(intent);
        }
    }

}

TabGroupActivity.java

public class TabGroupActivity extends ActivityGroup 
{
    private ArrayList<String> mIdList;
    Button btnBack;
    ImageButton btnShare;
    TextView txtViewHeading;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        btnBack = Main.btnBack;
        btnShare = Main.btnShare;
        txtViewHeading = Main.txtViewHeading;
        btnBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        if (mIdList == null) mIdList = new ArrayList<String>();
    }
    /**
     * This is called when a child activity of this one calls its finish method.
     * This implementation calls {@link LocalActivityManager#destroyActivity} on the child activity
     * and starts the previous activity.
     * If the last child activity just called finish(),this activity (the parent),
     * calls finish to finish the entire group.
     */
    @Override
    public void finishFromChild(Activity child) 
    {
        try
        {
            btnShare.setVisibility(View.GONE);
            LocalActivityManager manager = getLocalActivityManager();
            int index = mIdList.size()-1;

            if (index < 1) 
            {
                finish();
                return;
            }

            manager.destroyActivity(mIdList.get(index), true);
            mIdList.remove(index);
            index--;
            String lastId = mIdList.get(index);
            Intent lastIntent = manager.getActivity(lastId).getIntent();
            Window newWindow = manager.startActivity(lastId, lastIntent);           
            setContentView(newWindow.getDecorView());
            //Set Heading text to current Id
            txtViewHeading.setText(getActivityHeading(lastId));     
            //Set Back button text to previous Id if applicable
            btnBack.setVisibility(View.VISIBLE);                
            //Back button
            String backId =  "";
            if(mIdList.size() > 1)
            {
                backId = mIdList.get(mIdList.size()-2);
                btnBack.setVisibility(View.VISIBLE);
                btnBack.setText(getActivityHeading(backId));
                txtViewHeading.setPadding(10,0,0,0);
            }
            else 
            {
                btnBack.setVisibility(View.GONE);
                txtViewHeading.setPadding(0,0,0,0);
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
    * Starts an Activity as a child Activity to this.
    * @param Id Unique identifier of the activity to be started.
    * @param intent The Intent describing the activity to be started.
    */
    public void startChildActivity(String Id, Intent intent) 
    {
        try
        {
            btnShare.setVisibility(View.GONE);
            Window window = getLocalActivityManager().startActivity(Id,intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP));
            if (window != null) 
            {
                mIdList.add(Id);
                setContentView(window.getDecorView());
                txtViewHeading.setText(getActivityHeading(Id));
                //Back button
                String backId =  "";
                if(mIdList.size() > 1)
                {
                    backId = mIdList.get(mIdList.size()-2);
                    btnBack.setVisibility(View.VISIBLE);
                    btnBack.setText(backId);
                    txtViewHeading.setPadding(5,0,0,0);
                }
                else 
                {
                    btnBack.setVisibility(View.GONE);
                    txtViewHeading.setPadding(0,0,0,0);
                }                   
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
    * The primary purpose is to prevent systems before android.os.Build.VERSION_CODES.ECLAIR
    * from calling their default KeyEvent.KEYCODE_BACK during onKeyDown.
    */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) 
    {
        if (keyCode == KeyEvent.KEYCODE_BACK) 
        {
            //preventing default
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    /**
    * Overrides the default implementation for KeyEvent.KEYCODE_BACK
    * so that all systems call onBackPressed().
    */
    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) 
    {
        if (keyCode == KeyEvent.KEYCODE_BACK) 
        {
            onBackPressed();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    /**
    * If a Child Activity handles KeyEvent.KEYCODE_BACK.
    * Simply override and add this method.
    */
    @Override
    public void onBackPressed () 
    {
        try
        {
            btnShare.setVisibility(View.GONE);
            int length = mIdList.size();
            if ( length > 1) 
            {
                Activity current = getLocalActivityManager().getActivity(mIdList.get(length-1));
                current.finish();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }   

    /**
    * Get the correct heading text and language based on activity id
    */
    public String getActivityHeading(String id)
    {
        // method that returns the TEXT for my main heading TextView based on the activity we're on...          
    }               

}

StatusGroupActivity

public class StatusGroupActivity extends TabGroupActivity
{
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        startChildActivity("Status", new Intent(this,Status.class));
    }    

}

... so basically when my app loads, I get my tabs at the bottom, my header at the top, and the "tab content" in the middle. In my Status activity, I can load another activity from it by using ...

Intent intent = new Intent(getParent(), SomeOtherActivity.class)
TabGroupActivity parentActivity = (TabGroupActivity)getParent();
parentActivity.startChildActivity("Some Other Activity", intent);

... and it loads the SomeOtherActivity activity into the content area. Hitting back takes me back to the Status screen.

Any pointers, examples and assistance with converting this over to use Fragments is so greatly appreciated. I will gladly donate 500 of my rep. points for a full example.

main.xml (Main Activity Layout file)

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    tools:ignore="ContentDescription,HardcodedText" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/imageSuccess"
                android:layout_width="wrap_content"
                android:layout_height="40dp"
                android:adjustViewBounds="true"
                android:scaleType="matrix"
                android:src="@drawable/bg_navbar_blank" />

            <com.myproject.android.BgButtonStyle
                android:id="@+id/btnBack"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="5dp"
                android:layout_marginTop="0dp"
                android:background="@drawable/back_button"
                android:text=""
                android:textColor="@color/White"
                android:textSize="12sp"
                android:visibility="visible"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:padding="5dp"/>

            <ImageButton
                android:id="@+id/btnShare"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="15dp"
                android:background="@null"
                android:src="@drawable/icon_share"
                android:visibility="visible"
                android:adjustViewBounds="false"
                android:scaleType="fitXY"/>

            <com.myproject.android.AutoResizeTextView
                android:id="@+id/txtViewHeading"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center_horizontal"
                android:paddingLeft="5dp"
                android:text="Status"
                android:textAppearance="?android:attr/textAppearanceLarge"
                android:textSize="28sp"
                android:textStyle="bold"
                android:paddingRight="5dp"
                android:layout_toEndOf="@id/btnBack"
                android:layout_toStartOf="@id/btnShare"
                android:layout_centerVertical="true"
                android:lines="1"/>

        </RelativeLayout>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1" >
        </FrameLayout>

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="-4dp"
            android:layout_weight="0"
            android:background="@drawable/bg_tabs">

        </TabWidget>
    </LinearLayout>

</android.support.v4.app.FragmentTabHost>

In my current TabGroupActivity class, in the finishFromChild and startChildActivity methods, I am able to call setText on the txtViewHeading TextView element in my main activity layout. Which is the current activities "title". If there is more than 1 activity in the group, the back button shows the previous title. How can I duplicate this in the examples below? The main activity layout there is much different than mine.


回答1:


First you need to add Design Support Library and AppCompatLibrary into your Project

Add this code into your app gradle

compile 'com.android.support:appcompat-v7:24.0.0'
compile 'com.android.support:design:24.0.0'

layout for activity_main.xml (like main.xml in your code)

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/appbar_padding_top"
    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|enterAlways"
        app:popupTheme="@style/AppTheme.PopupOverlay">

    </android.support.v7.widget.Toolbar>

    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

In above layout ViewPager will provides horizontal layout to display tabs. You can display more screens in a single screen using tabs. You can swipe the tabs quickly as you can.

Root Fragment

<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"
android:id="@+id/root_frame" >

View for First Fragment

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#ff0"
android:layout_height="match_parent" >

<TextView
    android:id="@+id/tv"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:text="@string/first_fragment" />
<Button 
    android:id="@+id/btn"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:text="@string/to_second_fragment"/>

 </RelativeLayout>

View for Second and Individual(s) Fragment.

<RelativeLayout 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"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin">

<TextView
    android:id="@+id/section_label"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

</RelativeLayout>

Now add a MainActivity(like Main Activity in yours code) under which all this thing will handle.

public class MainActivity extends AppCompatActivity {

private TabGroupAdapter mTabGroupAdapter;
private ViewPager mViewPager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    ArrayList<Fragment> fragmentList = new ArrayList<Fragment>();
    fragmentList.add(new RootFragment());
    fragmentList.add(new IndividualFragment1());
    fragmentList.add(new IndividualFragment2());
     ArrayList<String> name = new ArrayList<String>() {
        {
            add("Root Tab");
            add("Second Tab");
            add("Third Tab");
        }
    };
    // Create the adapter that will return a fragment for each of the three
    // primary sections of the activity.
    mTabGroupAdapter = new TabGroupAdapter(getSupportFragmentManager(),name, fragmentList,);

    // Set up the ViewPager with the sections adapter.
    mViewPager = (ViewPager) findViewById(R.id.container);
    mViewPager.setAdapter(mTabGroupAdapter);

    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(mViewPager);

}
}

There is one FragmentPagerAdapter defined as mTabGroupAdapter inside MainActivity that will add a different tabs inside a single Layout.

First we bind the mTabGroupAdapter to mViewPager.

TabLayout will act like a TabHost under which Tab will be added by FragmentPagerAdapter.

mViewPager is bind to the Tablayout.

Under MainActivity TabLayout will display the name of Tabs.

TabGroupAdapter

 public class TabGroupAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> fragmentList = new ArrayList<Fragment>();
    private ArrayList<String> fragment_name;

    public TabGroupAdapter(FragmentManager fm, ArrayList<String> name, ArrayList<Fragment> list) {
        super(fm);
        this.fragmentList = list;
        this.fragment_name = name;
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return fragment_name.get(position);
    }
}

In TabGroupAdapter you would pass a List of fragments(or single fragment) and list of fragments name(or single name) as arguments in the Constructor.

IndividualFragment(s) will act like a individual Tab instead of Activity.

RootFragment will be acting as a container for other fragments( First Fragment and Second Fragment)

Root Fragment

public  class RootFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.root_fragment, container, false);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.root_frame, new FirstFragment());
        fragmentTransaction.commit();
        return view;
    }
}

First Fragment

public  class FirstFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.first_fragment, container, false);

        Button btn = (Button) view.findViewById(R.id.btn);

        btn.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
            //use the "root frame" defined in
            //"root_fragment.xml" as the reference to replace fragment

            fragmentTransaction.replace(R.id.root_frame, new SecondFragment());
            /*
             * allow to add the fragment 
             * to the stack and return to it later, by pressing back
             */
           fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();
        }
    });
    }
}

Second Fragment

public  class SecondFragment extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}

Individual(s) Fragment

public  class IndividualFragment1 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}



public  class IndividualFragment2 extends Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container, false);
        return rootView;
    }
}

In OnCreateView method you would set a layout of a Tab .

You won't have to use the getTabHost() method.

Let me know if you persist any problem.

Whenever you want to dynamically change or update the Tabs in View Pager just add or remove item from fragmentList and call this method mTabGroupAdapter.notifyDataSetChanged(); inside MainActivity.




回答2:


Add these dependencies to your project:

compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'

First change your Main activity must be extended from AppCompatActivity.

Than change your main activity's layout like below:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/coordinatorlayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".Main">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbarlayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <include
            layout="@layout/toolbar_default"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout
            android:id="@+id/tabs"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:tabGravity="fill"
            app:tabMaxWidth="0dp"
            app:tabIndicatorHeight="4dp"
            app:tabMode="fixed"
            app:tabIndicatorColor="@android:color/white"
            android:background="@color/AppPrimary"/>
    </android.support.design.widget.AppBarLayout>

   <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".dashboard.DashboardActivity"
    tools:showIn="@layout/activity_dashboard">


    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

</android.support.design.widget.CoordinatorLayout>

And here's a toolbar layout example. You can customize however you want.

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/toolbar_main"
    style="@style/Widget.MyApp.Toolbar.Solid"
    android:layout_width="match_parent"
    android:layout_height="@dimen/abc_action_bar_default_height_material"
    android:background="@color/AppPrimary"
    app:contentInsetEnd="16dp"
    app:contentInsetStart="16dp" />

Than you need to create fragments which you'll use in your tabs instead of activities which you use for tabs. In this case this'll your Status Activity if i'm not wrong.

Define a StatusFragment like below:

public class StatusFragment extends Fragment
{
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        // this is your Status fragment. You can do stuff which you did in     Status activity
    }
}

Than you need to define a tabs adapter which you'll bind with your tabs and convert your TabHost to Fragment/Fragment manager type. Titles string array contains strings which you'll show in your tabs indicator. Such as "Status, My Assume Tab, My awesome tab 2

public class DashboardTabsAdapter extends FragmentPagerAdapter {
    private String[] mTitles;

    public DashboardTabsAdapter(FragmentManager fm, String[] titles) {
        super(fm);
        this.mTitles = titles;
    }

    @Override
    public Fragment getItem(int position) {
        return new StatusFragment();
        // You can define some other fragments if you want to do different types of operations in your tabs and switch this position and return that kind of fragment.
    }

    @Override
    public int getCount() {
        return mTitles.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mTitles[position];
    }
}

And finally in your Main activity find your view pager, tabs create a new adapter and bind them.

        final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
        final DashboardTabsAdapter dashboardTabsAdapter = new DashboardTabsAdapter(getSupportFragmentManager(), getResources().getStringArray(R.array.tab_titles));
        mViewPagerMain = (ViewPager) findViewById(R.id.viewpager_main);
        mViewPagerMain.setOffscreenPageLimit(3);
        mViewPagerMain.setAdapter(dashboardTabsAdapter);
        tabLayout.setupWithViewPager(mViewPagerMain);

Edit: You'll no longer need TabHost and TabActivity any more. Your tab grup activity will be your ViewPager which handles screen changes and lifecycle of fragments inside. If you need to get this activity from fragments you can use getActivity() method and cast it to your activity and use it's public methods.



来源:https://stackoverflow.com/questions/38081842/converting-activitygroup-app-to-use-fragments-fragmentgroup

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!