1. 程式人生 > >【Android】從無到有:手把手一步步教你使用最簡單的 Fragment(一)

【Android】從無到有:手把手一步步教你使用最簡單的 Fragment(一)

轉載請註明出處,原文連結:https://blog.csdn.net/u013642500/article/details/80515227

【本文適用讀者】

        知道 Fragment 是什麼,不知道如何用程式碼建立者。

【AS版本】


【前言】

        在 Android 中有兩個包含有 Fragment 類,分別是 android.support.v4.app.Fragment 和 android.app.Fragment。

        他們的區別是相容性問題,在最低版本 minSdkVersion 大於等於26時,大可以使用 android.app.Fragment,而最低版本 minSdkVersion 小於26時,強烈推薦使用 android.support.v4.app.Fragment,因為該包正是為了相容低版本 Android 而出現的。

        相信你們在網上查到了以下兩點:

        1、android.app.Fragment 相容的最低版本 minSdkVersion 是 11,即Android 3.0。

        2、android.support.v4.app.Fragment 相容的最低版本 minSdkVersion 是 4,即 Android 1.6。

        而現在的 Android Studio 新建專案時,可選擇的最低版本 minSdkVersion 最少是 14,即 Android 4.0。即使你的專案的最低版本 minSdkVersion 大於 11,小於 26,卻還是推薦使用 android.support.v4.app.Fragment 呢?

        還是因為相容性,FragmentManager 物件的諸如 getFragments 方法、unregisterFragmentLifecycleCallbacks 方法、registerFragmentLifecycleCallbacks 方法、getPrimaryNavigationFragment 方法、isStateSaved 方法等,都需要最低版本 minSdkVersion 大於等於 26。如果不使用這些方法,也大可以使用 android.app.Fragment。

【新建Fragment】

第一種方法:

1、右鍵單擊目錄,或者開啟選單欄 File,然後 new → Fragment → Fragment(Blank)。



2、因為要使用最簡單的 Fragment,所以取消勾選以下兩個選項:

Include fragment factory method?

Include interface callbacks?

3、新建完畢,預設程式碼如下(繼承自 android.support.v4.app.Fragment):

package com.test.myapplication;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

/**
 * A simple {@link Fragment} subclass.
 */
public class BlankFragment extends Fragment {

    public BlankFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_blank, container, false);
    }
}

第二種方法:

1、右鍵單擊目錄,或者開啟選單欄 File,然後 new → Java Class。



2、Name 處寫 BlankFragment,Superclass 寫 Fragment,然後選擇 Fragment (android.support.v4.app)。


3、新建一個 Fragment 佈局,命名為 fragment_blank.xml。


【使用Fragment】

1、修改隨 Fragment 一起新建出來的(第一種方法),或自己新建出來的佈局檔案 fragment_blank.xml(第一種方法)。給其新增兩個控制元件:一個 TextView,一個 Button。

<?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">

    <TextView
        android:id="@+id/txtFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />

    <Button
        android:id="@+id/btnFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕" />
</LinearLayout>

2、回到我們新建 BlankFragment.java 檔案中,修改其中的 onCreateView 方法。首先例項化一個 View 物件,最後返回這個 View 物件。其中的佈局檔案 fragment_blank 就是系統自帶的(第一種方法)或自己新建的(第二種方法)。

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

        return view;
    }

3、在 onCreateView 方法,通過 view.findViewById 方法,獲取佈局檔案 fragment_blank.xml 中的控制元件。

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

        TextView textView = view.findViewById(R.id.txtFragment);
        Button button = view.findViewById(R.id.btnFragment);

        return view;
    }

4、使用兩個控制元件,這裡我們寫一個按鈕點選事件監聽。

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

        final TextView textView = view.findViewById(R.id.txtFragment);
        Button button = view.findViewById(R.id.btnFragment);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("點選了按鈕");
            }
        });

        return view;
    }

5、修改 MainActivity 的佈局檔案 activity_main.xml ,給最外層佈局一個 id 為 container,然後新增一個按鈕控制元件。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btnActivity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="呈現Fragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

6、回到 MainActivity.java(要繫結 Fragment 的 Activity),在 onCreate 方法中,寫一個按鈕的點選事件監聽。

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

        findViewById(R.id.btnActivity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });
    }

7、在點選事件監聽中,首先獲取 FragmentManager。

     這裡有兩個方法:getFragmentManager 和 getSupportFragmentManager。

     其中 getFragmentManager 方法對應的是 android.app.Fragment;

     getSupportFragmentManager 方法對應的是 android.support.v4.app.Fragment。

     這裡使用的方法要與新建的 BlankFragment 繼承的 Fragment 類所在包一致,即 android.support.v4.app.Fragment,所以使用 getSupportFragmentManager 方法。

                FragmentManager fragmentManager = getSupportFragmentManager();

8、獲取 FragmentTransaction。

                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

9、用 add 方法給 FragmentTransaction 新增新建的 BlankFragment。第一個引數傳入 MainActivity 的佈局檔案中最外層佈局的 id,第二個引數傳入一個 BlankFragment 物件。

                fragmentTransaction.add(R.id.container, new BlankFragment());

10、提交 FragmentTransaction。

                fragmentTransaction.commit();

以上 9 - 10 步可以合併到一起寫,這樣就不用一個一個例項化物件了。

                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, new BlankFragment())
                        .commit();

【成果】


【注意事項】

        如果完全按照本文所述操作,會出現一個小問題,詳看下一篇文章:“【Android】從無到有:手把手一步步教你使用最簡單的Fragment(二)”(https://blog.csdn.net/u013642500/article/details/80579389

【原始碼】

MainActivity.java:

package com.test.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {

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

        findViewById(R.id.btnActivity).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.container, new BlankFragment())
                        .commit();
            }
        });
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/btnActivity"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="呈現Fragment"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

BlankFragment.java:

package com.test.myapplication;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

/**
 * A simple {@link Fragment} subclass.
 */
public class BlankFragment extends Fragment {

    public BlankFragment() {
        // Required empty public constructor
    }

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

        final TextView textView = view.findViewById(R.id.txtFragment);
        Button button = view.findViewById(R.id.btnFragment);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText("點選了按鈕");
            }
        });

        return view;
    }
}

fragment_blank.xml:

<?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">

    <TextView
        android:id="@+id/txtFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello_blank_fragment" />

    <Button
        android:id="@+id/btnFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="按鈕" />
</LinearLayout>

【附】

Fragment 生命週期圖


【相關連結】

        從無到有:手把手一步步教你使用最簡單的Fragment(二)

        https://blog.csdn.net/u013642500/article/details/80579389

        從無到有:手把手一步步教你使用最簡單的Fragment(三)
        https://blog.csdn.net/u013642500/article/details/80585416

由於本人安卓知識及技術有限,本文如有錯誤或不足請評論指出,非常感謝!