Android实现Activity+fragment的APP流行框架

简介

现如今的安卓app基本都采用了activity+fragment的模式来搭建框架;
而四大组件之一的activity和自带生命周期控件的fragment就自然而然的成为了众多产品经理的青睐,今天就来搭建一个简单的activity+fragment框架。。

  • 控件简介
  • Activity:一个负责与用户交互的组件
  • Fragment:一个应用适配不同设备的大屏幕、支持更加动态和灵活的UI设计所提供的一个组件。
  • 必须说明的是:fragment必须依赖于activity生存

1.首先,既然fragment必须依赖activity生存,那么就先创建一个启动的activity。

activity_main.xml
<?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"
    tools:context="com.cc.activity.MainActivity">

    <FrameLayout
        android:id="@+id/fragment_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/view"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">
    </FrameLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:layout_above="@+id/include"
        android:background="@color/grey"
        android:id="@+id/view" />
    
    <include
        layout="@layout/public_bottom"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:id="@+id/include" />

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:background="@android:color/white"
        android:baselineAligned="false"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/Lin_one"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center">

            <ImageView
                android:id="@+id/img_one_bottom"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@mipmap/xiao"/>

            <TextView
                android:id="@+id/txt_one_bottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第一个"
                android:textColor="@drawable/main_tab_text_color"
                android:textSize="15dp"/>

        </LinearLayout>


        <LinearLayout
            android:id="@+id/Lin_two"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center">

            <ImageView
                android:id="@+id/img_two_bottom"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@mipmap/ws"/>

            <TextView
                android:id="@+id/txt_two_bottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第二个"
                android:textColor="@drawable/main_tab_text_color"
                android:textSize="15dp"/>

        </LinearLayout>

        <LinearLayout
            android:id="@+id/Lin_three"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center">

            <ImageView
                android:id="@+id/img_three_bottom"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@mipmap/ws"/>

            <TextView
                android:id="@+id/txt_three_bottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第三个"
                android:textColor="@drawable/main_tab_text_color"
                android:textSize="15dp"/>

        </LinearLayout>

        <LinearLayout
            android:id="@+id/Lin_four"
            android:layout_width="0dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            android:orientation="vertical"
            android:gravity="center">

            <ImageView
                android:id="@+id/img_four_bottom"
                android:layout_width="30dp"
                android:layout_height="30dp"
                android:src="@mipmap/nu"/>

            <TextView
                android:id="@+id/txt_four_bottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="第四个"
                android:textColor="@drawable/main_tab_text_color"
                android:textSize="15dp" />

        </LinearLayout>
    </LinearLayout>

</LinearLayout>
注:需要在activity的xml文件中定义一个Fragment控件,并声明ID。

2.activity声明之后,需要声明fragment所要加载的xml文件(一般为四个fragment的xml文件):

<!--第一个-->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
	<TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textColor="@color/black"
        android:text="第1个" />

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textColor="@color/black"
        android:text="第2个" />

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textColor="@color/black"
        android:text="第3个" />

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

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textColor="@color/black"
        android:text="第4个" />

</RelativeLayout>
注:四个fragment是最终要显示的界面

3.当xml都声明完之后,需要通过代码把他们加载出来,让fragment依赖于activity之上。

package com.cc.activity;

import android.graphics.Color;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.cc.fragment.FourFragment;
import com.cc.fragment.OneFragment;
import com.cc.fragment.ThreeFragment;
import com.cc.fragment.TwoFragment;

import java.util.HashMap;

/**
 * fragment 的 add和replace方法
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    /** 底部导航栏 */
    LinearLayout Lin_one, Lin_two, Lin_three, Lin_four;

    //获取底部导航栏的ImageView
    ImageView img_one_bottom, img_two_bottom, img_three_bottom, img_four_bottom;

    /** 第一个fragment */
    public static final int PAGE_COMMON = 0;
    /** 第二个fragment */
    public static final int PAGE_TRANSLUCENT = 1;
    /** 第三个fragment */
    public static final int PAGE_COORDINATOR = 2;
    /** 第四个fragment */
    public static final int PAGE_COLLAPSING_TOOLBAR = 3;

    /** 管理fragment */
    private HashMap<Integer,Fragment> fragments = new HashMap<>();

    //当前activity的fragment控件
    private int fragmentContentId = R.id.fragment_content;

    /** 设置默认的fragment */
    private int currentTab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initFrag();
        initView();
        // 设置默认的Fragment
        defaultFragment();
        SelectColor(0);
    }

    private void initFrag() {
        fragments.put(PAGE_COMMON, new OneFragment());
        fragments.put(PAGE_TRANSLUCENT, new TwoFragment());
        fragments.put(PAGE_COORDINATOR, new ThreeFragment());
        fragments.put(PAGE_COLLAPSING_TOOLBAR, new FourFragment());
    }

    private void defaultFragment() {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.add(fragmentContentId,fragments.get(PAGE_COMMON));
        currentTab = PAGE_COMMON;
        ft.commit();
    }

    private void initView() {
        //底部导航栏的父控件
        Lin_one = (LinearLayout) findViewById(R.id.Lin_one);
        Lin_two = (LinearLayout) findViewById(R.id.Lin_two);
        Lin_three = (LinearLayout) findViewById(R.id.Lin_three);
        Lin_four = (LinearLayout) findViewById(R.id.Lin_four);

        img_one_bottom = (ImageView) findViewById(R.id.img_one_bottom);
        img_two_bottom = (ImageView) findViewById(R.id.img_two_bottom);
        img_three_bottom = (ImageView) findViewById(R.id.img_three_bottom);
        img_four_bottom = (ImageView) findViewById(R.id.img_four_bottom);


        Lin_one.setOnClickListener(this);
        Lin_two.setOnClickListener(this);
        Lin_three.setOnClickListener(this);
        Lin_four.setOnClickListener(this);
    }

    /**
     * 当页面选中时改变当前的导航栏蓝色和图片的状态
     * @param position 当前页面
     */
    public void SelectColor(int position) {
        if(position == 0){
            //给底部到导航栏的image更换图片
            img_one_bottom.setImageResource(R.mipmap.xiao);
            img_two_bottom.setImageResource(R.mipmap.ws);
            img_three_bottom.setImageResource(R.mipmap.ws);
            img_four_bottom.setImageResource(R.mipmap.nu);

            //给底部导航栏更换背景色
            Lin_one.setBackgroundResource(R.color.blue);
            Lin_two.setBackgroundResource(R.color.white);
            Lin_three.setBackgroundResource(R.color.white);
            Lin_four.setBackgroundResource(R.color.white);
        } else if (position == 1){
            //给底部到导航栏的image更换图片
            img_one_bottom.setImageResource(R.mipmap.ws);
            img_two_bottom.setImageResource(R.mipmap.xiao);
            img_three_bottom.setImageResource(R.mipmap.ws);
            img_four_bottom.setImageResource(R.mipmap.nu);

            //给底部导航栏更换背景色
            Lin_one.setBackgroundResource(R.color.white);
            Lin_two.setBackgroundResource(R.color.blue);
            Lin_three.setBackgroundResource(R.color.white);
            Lin_four.setBackgroundResource(R.color.white);
        } else if (position == 2){
            //给底部到导航栏的image更换图片
            img_one_bottom.setImageResource(R.mipmap.nu);
            img_two_bottom.setImageResource(R.mipmap.ws);
            img_three_bottom.setImageResource(R.mipmap.xiao);
            img_four_bottom.setImageResource(R.mipmap.ws);

            //给底部导航栏更换背景色
            Lin_one.setBackgroundResource(R.color.white);
            Lin_two.setBackgroundResource(R.color.white);
            Lin_three.setBackgroundResource(R.color.blue);
            Lin_four.setBackgroundResource(R.color.white);
        } else if (position == 3){
            //给底部到导航栏的image更换图片
            img_one_bottom.setImageResource(R.mipmap.nu);
            img_two_bottom.setImageResource(R.mipmap.ws);
            img_three_bottom.setImageResource(R.mipmap.ws);
            img_four_bottom.setImageResource(R.mipmap.xiao);

            //给底部导航栏更换背景色
            Lin_one.setBackgroundResource(R.color.white);
            Lin_two.setBackgroundResource(R.color.white);
            Lin_three.setBackgroundResource(R.color.white);
            Lin_four.setBackgroundResource(R.color.blue);
        }
    }

    /**
     * 点击切换下部按钮
     * @param page
     */
    private void changeTab(int page) {
        //默认的currentTab == 当前的页码,不做任何处理
        if (currentTab == page) {
            return;
        }

        //获取fragment的页码
        Fragment fragment = fragments.get(page);
        //fragment事务
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        //如果该Fragment对象被添加到了它的Activity中,那么它返回true,否则返回false。
        //当前activity中添加的不是这个fragment
        if(!fragment.isAdded()){
            //所以将他加进去
            ft.add(fragmentContentId,fragment);
        }
        //隐藏当前currentTab的
        ft.hide(fragments.get(currentTab));
        //显示现在page的
        ft.show(fragments.get(page));
        //设置当前currentTab底部的状态
        SelectColor(currentTab);
        //当前显示的赋值给currentTab
        currentTab = page;
        //设置当前currentTab底部的状态
        SelectColor(currentTab);
        //activity被销毁?  !否
        if (!this.isFinishing()) {
            //允许状态丢失
            ft.commitAllowingStateLoss();
        }
    }

    /**
     * 所有的控件在这里进行点击(单击)事件
     * @param v
     */
    @Override
    public void onClick(View v) {
        int temdId = v.getId();
        if(temdId == R.id.Lin_one){
            changeTab(PAGE_COMMON);
        } else if (temdId == R.id.Lin_two){
            changeTab(PAGE_TRANSLUCENT);
        } else if (temdId == R.id.Lin_three){
            changeTab(PAGE_COORDINATOR);
        } else if (temdId == R.id.Lin_four){
            changeTab(PAGE_COLLAPSING_TOOLBAR);
        }
    }
}

注:这个是真个activity里面的代码。主要用于在代码中注释的很清楚了,可以阅读一下代码。

4.activty设置好之后,也需要在fragment加载出最终运行的fragment.xml文件。具体如下:

package com.cc.fragment;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.cc.activity.R;
/**
 * Created by admin on 2018/4/10.
 */

public class TwoFragment extends Fragment {

    View view;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_one, container, false);
        return view;
    }
}
注:四个fragment的写法都是一样,这里写一个就可以了,其他三个只需要换掉加载的layout就可以。

重要提醒:

  1. activity的xml文件中需要声明一个fragment控件;
  2. fragment的声明周期受activity影响。当activity暂停时,依赖它的所有fragment随之暂停;销毁随之全部销毁。

如需使用demo,请前往下载:

点我点我下载

期待互动留言,支持email交互:

邮箱地址:[email protected]。希望各位大佬来骚扰。

感谢,今天的表演就到这里结束了,我们下次再见!

																			---财财亲笔

Guess you like

Origin blog.csdn.net/qq_35840038/article/details/80271090