Using FragmentActivity to Make Homepage Framework in Android

Different from the previous two ways of making homepage frameworks, whether it was TabActivity or ActivityGroup, the content page was carried by Activity before, but FragmentActivity was a homepage framework built by combining Activity and Fragment, and the content part was carried by Fragment. This article explains the use of FragmentActivity.

1. First is the content of MainActivity

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "TabFragmentActivity";
    private FragmentTabHost tabHost; // 声明一个碎片标签栏对象

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Bundle bundle = new Bundle(); // 创建一个包裹对象
        bundle.putString("tag", TAG); // 往包裹中存入名叫tag的标记
        // 从布局文件中获取名叫tabhost的碎片标签栏
        tabHost = findViewById(android.R.id.tabhost);
        // 把实际的内容框架安装到碎片标签栏
        tabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
        // 往标签栏添加第一个标签,其中内容视图展示TabFirstFragment
        tabHost.addTab(getTabView(R.string.menu_first, R.drawable.tab_first_selector),
                TabFirstFragment.class, bundle);
        // 往标签栏添加第二个标签,其中内容视图展示TabSecondFragment
        tabHost.addTab(getTabView(R.string.menu_second, R.drawable.tab_second_selector),
                TabSecondFragment.class, bundle);
        // 往标签栏添加第三个标签,其中内容视图展示TabThirdFragment
        tabHost.addTab(getTabView(R.string.menu_third, R.drawable.tab_third_selector),
                TabThirdFragment.class, bundle);
        // 不显示各标签之间的分隔线
        tabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE);
    }

    // 根据字符串和图标的资源编号,获得对应的标签规格
    private TabHost.TabSpec getTabView(int textId, int imgId) {
        // 根据资源编号获得字符串对象
        String text = getResources().getString(textId);
        // 根据资源编号获得图形对象
        Drawable drawable = getResources().getDrawable(imgId);
        // 设置图形的四周边界。这里必须设置图片大小,否则无法显示图标
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight());
        // 根据布局文件item_tabbar.xml生成标签按钮对象
        View item_tabbar = getLayoutInflater().inflate(R.layout.item_tabbar, null);
        TextView tv_item = item_tabbar.findViewById(R.id.tv_item_tabbar);
        tv_item.setText(text);
        // 在文字上方显示标签的图标
        tv_item.setCompoundDrawables(null, drawable, null, null);
        // 生成并返回该标签按钮对应的标签规格
        return tabHost.newTabSpec(text).setIndicator(item_tabbar);
    }
}

2. Next is the content of the layout file activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- 这是实际的内容框架,内容页面都挂在这个框架布局下面。
        把FragmentLayout放在FragmentTabHost上面,标签栏就在页面底部;
        反之FragmentLayout在FragmentTabHost下面,标签栏就在页面顶部。 -->
    <FrameLayout
        android:id="@+id/realtabcontent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <!-- 碎片标签栏的id必须是@android:id/tabhost -->
    <androidx.fragment.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="50dp">

        <!-- 这是例行公事的选项内容,实际看不到 -->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />
    </androidx.fragment.app.FragmentTabHost>
</LinearLayout>

3. Add the text information of three tags in strings.xml

<string name="menu_first">首页</string>
<string name="menu_second">分类</string>
<string name="menu_third">购物车</string>

4. Then we introduce the status list file of the three tags

First, we import six pictures of three buttons (three normal states, three selected states), and then write the following code

tab_first_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@mipmap/tab_first_pressed" />
    <item android:drawable="@mipmap/tab_first_normal" />
</selector>
tab_second_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@mipmap/tab_second_pressed" />
    <item android:drawable="@mipmap/tab_second_normal" />
</selector>
tab_third_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@mipmap/tab_third_pressed" />
    <item android:drawable="@mipmap/tab_third_normal" />
</selector>

These three files are the state list of the three buttons

5. At this time we start to create three Fragments, these three Fragments are the bearers of the subsequent content.

TabFirstFragment.java
public class TabFirstFragment extends Fragment {
    private static final String TAG = "TabFirstFragment";
    protected View mView; // 声明一个视图对象
    protected Context mContext; // 声明一个上下文对象

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContext = getActivity(); // 获取活动页面的上下文
        // 根据布局文件fragment_tab_first.xml生成视图对象
        mView = inflater.inflate(R.layout.fragment_tab_first, container, false);
        // 根据碎片标签栏传来的参数拼接文本字符串
        String desc = String.format("我是%s页面,来自%s",
                "首页", getArguments().getString("tag"));
        TextView tv_first = mView.findViewById(R.id.tv_first);
        tv_first.setText(desc);

        return mView;
    }

}
TabSecondFragment.java
public class TabSecondFragment extends Fragment {
    private static final String TAG = "TabSecondFragment";
    protected View mView; // 声明一个视图对象
    protected Context mContext; // 声明一个上下文对象

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContext = getActivity(); // 获取活动页面的上下文
        // 根据布局文件fragment_tab_second.xml生成视图对象
        mView = inflater.inflate(R.layout.fragment_tab_second, container, false);
        // 根据碎片标签栏传来的参数拼接文本字符串
        String desc = String.format("我是%s页面,来自%s",
                "分类", getArguments().getString("tag"));
        TextView tv_second = mView.findViewById(R.id.tv_second);
        tv_second.setText(desc);

        return mView;
    }

}
TabThirdFragment.java
public class TabThirdFragment extends Fragment {
    private static final String TAG = "TabThirdFragment";
    protected View mView; // 声明一个视图对象
    protected Context mContext; // 声明一个上下文对象

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContext = getActivity(); // 获取活动页面的上下文
        // 根据布局文件fragment_tab_third.xml生成视图对象
        mView = inflater.inflate(R.layout.fragment_tab_third, container, false);
        // 根据碎片标签栏传来的参数拼接文本字符串
        String desc = String.format("我是%s页面,来自%s",
                "购物车", getArguments().getString("tag"));
        TextView tv_third = mView.findViewById(R.id.tv_third);
        tv_third.setText(desc);

        return mView;
    }

}

6. Then we introduce three Fragment layout files

fragment_tab_first.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_first"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom|center"
        android:textColor="#000000"
        android:textSize="17sp" />

</LinearLayout>
fragment_tab_second.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_second"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom|center"
        android:textColor="#000000"
        android:textSize="17sp" />

</LinearLayout>
fragment_tab_third.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical"
    android:padding="10dp">

    <TextView
        android:id="@+id/tv_third"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom|center"
        android:textColor="#000000"
        android:textSize="17sp" />

</LinearLayout>

At this time Fragment introduction is complete

7. We still lack the layout of a tab bar, that is, the layout of the buttons below, we add

item_tabbar.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tv_item_tabbar"
        style="@style/TabButton" />

</LinearLayout>

8. Itme_tabbar.xml needs a style, we add the following code in styles.xml

<style name="TabButton">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">match_parent</item>
    <item name="android:padding">5dp</item>
    <item name="android:layout_gravity">center</item>
    <item name="android:gravity">center</item>
    <item name="android:background">@drawable/tab_bg_selector</item>
    <item name="android:textSize">12sp</item>
    <item name="android:textStyle">normal</item>
    <item name="android:textColor">@drawable/tab_text_selector</item>
</style>

9. Let's add the tab_text_selector.xml and tab_bg_selector.xml resources in the TabButton style

tab_text_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="#0084e8" />
    <item android:color="#7597b3" />
</selector>

tab_bg_selector.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@mipmap/tab_bg_selected" />
    <item android:drawable="@mipmap/tab_bg_normal" />
</selector>

Two background images are used here, let’s add them

Here we have completed the home page construction work.

Our focus is naturally the content of the first and second steps. Briefly explain the main steps of our structure.

  1. First of all, we need to have a layout, this layout is a FrameLayout, we can define the id at will; second is a FragmentTabHost, this control needs to be written in accordance with the layout in our step 2.
  2. Next is the code in Activity, we get the FragmentTabHost object

    FragmentTabHost tabHost = findViewById(android.R.id.tabhost);
     
  3.  Next is the preparation of the getTabView method. The first parameter is the id of the button text, and the second parameter is the image of the button, which is then assembled into a TabSpec object through the code in the method. The core of this method is actually
    tabHost.newTabSpec(text).setIndicator(item_tabbar) 
    text is the text content of the corresponding button, and item_tabbar is the View generated by introducing the button layout. The parameters we pass in getTabView are all to generate this View.

  4. Next is to call the tabHost.addTab method. The first parameter of this method is the TabSpec object generated in the previous step, the second parameter is the class object of the Fragment, and the third parameter is the Buddle passed into the Fragment.

  5. Finally, call tabHost.getTabWidget().setShowDividers(LinearLayout.SHOW_DIVIDER_NONE); in order not to display the dividing line.

     

Guess you like

Origin blog.csdn.net/weixin_38322371/article/details/114080648