Fragment基礎

Fragment知識概要

  1. Fragment能夠做爲Activity界面的一部分組成出現
  2. 能夠在一個Activity中同時出現多個Fragment,一個Fragment也能夠在多個Activity中使用
  3. 在Activity運行過程當中,能夠添加、移除或替換Fragment
  4. Fragment能夠響應本身的輸入事件,而且有本身的生命週期,其生命週期會受宿主Activity的生命週期影響

建立片斷

onCreateView()

系統會在片斷首次繪製其界面時調用此方法。如要爲您的片斷繪製界面,您今後方法中返回的 View 必須是片斷佈局的根視圖。若是片斷未提供界面,您能夠返回 null。android

Fragment生命週期

fragment_lifecycle.png

  • onAttach() 當Fragment被添加到Activity的時候回調這個方法,而且只調用一次
  • onCreate() 建立Fragment時會回調,只會調用一次
  • onCreateView() 每次建立都會繪製Fragment的View組件時回調的方法
  • onActivityCreate() 當Fragment所在的Activity啓動完成後調用(在相關聯的 Activity 的 onCreate() 方法已返回時調用)
  • onStart() 啓動Fragment
  • onResume() 恢復Fragment時會被回調,調用onStart() 方法後面必定會調用onResume()方法
  • onPause() 暫停Fragment
  • onStop() 中止Fragment
  • onDestroyView() 當Fragment中的視圖被移除時調用
  • onDestroy() 銷燬Fragment時調用
  • onDetach() 當Fragment 和 Activity 取消關聯時調用

Fragment加載方式

  • (1) 靜態加載
  • (2) 動態加載

靜態加載

在Activity的layout文件中聲明Fragment,須要特別注意的是 中的android: name屬性指定了在layout中實例化的Fragment類bash

標識Fragment的方法

每一個片斷都須要惟一標識符,重啓 Activity 時,系統可以使用該標識符來恢復片斷(您也可使用該標識符來捕獲片斷,從而執行某些事務,如將其移除)。能夠經過兩種方式爲片斷提供 ID:app

  • 爲 android:id 屬性提供惟一 ID。
  • 爲 android:tag 屬性提供惟一字符串。
xml佈局文件
Activity佈局

activity_fragment.xmlide

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".Fragment學習.FragmentActivity">

    <!--靜態加載必須指定id或tag-->
    <fragment
        android:id="@+id/ft_load_static"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.fr.myapplication.Fragment學習.BlankFragment"/>

</androidx.constraintlayout.widget.ConstraintLayout>
複製代碼
Fragment佈局

fragment_blank.xml佈局

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".Fragment學習.BlankFragment">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="@string/app_name" />

    <Button
        android:id="@+id/bt_click"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
複製代碼
Java代碼

FragmentActivity學習

public class FragmentActivity extends AppCompatActivity {

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

        final TextView textView = findViewById(R.id.textView);
        Button button = findViewById(R.id.bt_click);

        button.setText("點擊");
        button.setOnClickListener(new View.OnClickListener() {
            @SuppressLint("SetTextI18n")
            @Override
            public void onClick(View v) {
                textView.setText("Activity內點擊");
            }
        });
    }
}
複製代碼

BlankFragmentui

public class BlankFragment extends Fragment {


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


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //layout佈局文件轉換成View對象
        /*
          Inflate the layout for this fragment
          resource: Fragment須要加載的佈局文件
          root: 加載layout的父ViewGroup
          attachToRoot: false, 不返回父ViewGroup
         */
        View view = inflater.inflate(R.layout.fragment_blank, container, false);
        TextView textView = view.findViewById(R.id.textView);
        textView.setText("靜態加載Fragment");
        return view;
    }

}
複製代碼

靜態加載Fragment.png
點擊Button.png

動態加載

使用代碼將Fragment添加到一個Activity layout中this

  • add():添加一個Fragment(指定要添加的fragment和插入的View)
  • 相似的操做還有remove()、replace()
處理Fragment事務

根據用戶的交互狀況,對Fragment進行添加、移除、替換,以及執行其餘動做,提交給Activity的每一套變化被稱做一個事務。spa

注意:每一個事務都是您想要同時執行的一組更改。可使用 add()、remove() 和 replace() 等方法,爲給定事務設置您想要執行的全部更改。而後,如要將事務應用到 Activity,必須調用 commit()code

若是容許用戶經過Back按鍵返回到前一個Fragment狀態,調用commit()以前能夠加入addToBackStack()方法

動態加載Fragment只需在Activity中寫以下代碼便可:

//須要動態加入的Fragment
    MoveFragment moveFragment = new MoveFragment();
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.add(R.id.frame, moveFragment);
    transaction.addToBackStack(null);
    transaction.commit();
複製代碼

Fragment與Activity通訊

  • Fragment可調用getActivity()方法獲取它所在的Activity
  • Activity可調用FragmentManager的findFragmentById()或findFragmentByTag()方法獲取Fragment
  • Activity ——> Fragment: 在Activity中建立Bundle數據包,並調用Fragment的setArguments(Bundle bundle)方法
  • Fragment ——> Activity: 在Fragment中定義一個內部回調接口,再讓含該Fragment的Activity實現該回調接口。這樣Fragment可調用該回調方法將數據傳遞給Activity
Activity向Fragment傳遞數據
1.動態加載Fragment時

Activity中代碼

MoveFragment moveFragment = new MoveFragment();
    Bundle bundle = new Bundle();
    bundle.putString("name","Activity向Fragment傳遞數據");
    moveFragment.setArguments(bundle);
    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.add(R.id.frame,moveFragment,"fragment_move");
    transaction.addToBackStack(null);
    transaction.commit();
複製代碼

Fragment中代碼

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //layout佈局文件轉換成View對象
        /*
          Inflate the layout for this fragment
          resource: Fragment須要加載的佈局文件
          root: 加載layout的父ViewGroup
          attachToRoot: false, 不返回父ViewGroup
         */
        View view = inflater.inflate(R.layout.fragment_blank, container, false);
        TextView textView = view.findViewById(R.id.textView);
        String text = getArguments() != null ? getArguments().getString("name") : null;
        textView.setText(text);
        return view;
    }
複製代碼
2.靜態加載Fragment時

調用FragmentManager的findFragmentById()或findFragmentByTag()方法獲取Fragment

Activity中代碼

FragmentManager fm = getSupportFragmentManager();
    Fragment fragmentById = fm.findFragmentById(R.id.ft_load_static);
    BlankFragment fragment = (BlankFragment) fragmentById;
    fragment.setTransfer("Activity向靜態加載的Fragment發送消息");
複製代碼

Fragment中代碼

private String transfer;

    public String getTransfer() {
        return transfer;
    }

    public void setTransfer(String transfer) {
        this.transfer = transfer;
    }

     view.findViewById(R.id.receive).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "Fragment接收消息:" + getTransfer(), Toast.LENGTH_SHORT).show();
            }
        });
複製代碼
Fragment向Activity傳遞數據
Fragment

1.Fragment中定義接口

public interface MyListener{
        void send(String text);
    }
複製代碼

2.onAttach中

@Override
    public void onAttach(@NonNull Context context) {
        listener = (MyListener) context;
        super.onAttach(context);
    }
複製代碼

3.onCreateView中調用接口發送消息

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

        listener.send("Fragment向Activity傳遞數據");
        return view;
    }
複製代碼
Activity

實現Fragment中定義的接口來接收數據

@Override
    public void send(String text) {
        Toast.makeText(this,"來自Fragment:"+ text,Toast.LENGTH_SHORT).show();
    }
複製代碼
相關文章
相關標籤/搜索