• Android之Fragment


    (一)

    • Faragment有自己的生命周期

    • Fragment依赖于Activity

    • Fragmen通过getActivity()可以获取所在Activity;Activity通过FragmentManager的findFragmentById()或findFragmentbyTag()获取Fragment

    • Fragment和Activity是多对多的关系

    MainActivity
     1 package com.example.fragmentdemo.UI;
     2 
     3 import androidx.appcompat.app.AppCompatActivity;
     4 
     5 import android.content.Intent;
     6 import android.os.Bundle;
     7 import android.view.View;
     8 import android.widget.Button;
     9 
    10 import com.example.fragmentdemo.R;
    11 
    12 public class MainActivity extends AppCompatActivity {
    13 
    14     private Button mBtnFragment;
    15 
    16     @Override
    17     protected void onCreate(Bundle savedInstanceState) {
    18         super.onCreate(savedInstanceState);
    19         setContentView(R.layout.activity_main);
    20         mBtnFragment = (Button)findViewById(R.id.btn_fragment);
    21         setListeners();
    22     }
    23 
    24     private void setListeners(){
    25         OnClick onclick = new OnClick();
    26         mBtnFragment.setOnClickListener(onclick);
    27     }
    28 
    29     private class OnClick implements View.OnClickListener {
    30 
    31         @Override
    32         public void onClick(View v) {
    33             Intent intent = null;
    34             switch (v.getId()){
    35                 case R.id.btn_fragment:
    36                     intent = new Intent(MainActivity.this,ContainerActivity.class);
    37                     startActivity(intent);
    38                     break;
    39                 default:
    40             }
    41         }
    42     }
    43 }

    ContainerActivity

     1 package com.example.fragmentdemo.UI;
     2 
     3 import android.os.Bundle;
     4 import android.view.View;
     5 import android.widget.Button;
     6 
     7 import androidx.appcompat.app.AppCompatActivity;
     8 import androidx.fragment.app.Fragment;
     9 
    10 import com.example.fragmentdemo.AFragment;
    11 import com.example.fragmentdemo.BFragment;
    12 import com.example.fragmentdemo.R;
    13 
    14 public class ContainerActivity extends AppCompatActivity {
    15 
    16     private AFragment aFragment;
    17     private BFragment bFragment;
    18     private Button mBtnChange;
    19 
    20     @Override
    21     protected void onCreate(Bundle savedInstanceState) {
    22         super.onCreate(savedInstanceState);
    23         setContentView(R.layout.activity_container);
    24         mBtnChange = (Button)findViewById(R.id.btn_change);
    25         mBtnChange.setOnClickListener(new View.OnClickListener(){
    26 
    27             @Override
    28             public void onClick(View v) {
    29                 if (bFragment == null){
    30                     bFragment = new BFragment();
    31                 }
    32                 getSupportFragmentManager().beginTransaction().replace(R.id.fl_container,bFragment).commitNowAllowingStateLoss();
    33             }
    34         });
    35 //        实例化AFragment
    36         aFragment = new AFragment();
    37 //        把aFragment添加到Activity中 记得调用commitAllowingStateLoss
    38 //        getSupportFragmentManager().beginTransaction().add(R.id.fl_container,aFragment).commit();
    39 //        当Fragment出现错误时,使用commit()方法会返回一些错误,而commitAllowingStateLoss()就不会
    40         getSupportFragmentManager().beginTransaction().add(R.id.fl_container,aFragment).commitAllowingStateLoss();
    41 //        getSupportFragmentManager().beginTransaction().replace()替换
    42 //        getSupportFragmentManager().beginTransaction().remove()移除
    43     }
    44 
    45 }

    AFragment

     1 package com.example.fragmentdemo;
     2 
     3 import android.app.Activity;
     4 import android.content.Context;
     5 import android.os.Bundle;
     6 import android.view.LayoutInflater;
     7 import android.view.View;
     8 import android.view.ViewGroup;
     9 import android.widget.TextView;
    10 
    11 import androidx.annotation.NonNull;
    12 import androidx.annotation.Nullable;
    13 import androidx.fragment.app.Fragment;
    14 
    15 public class AFragment extends Fragment {
    16 
    17     private TextView mTvTitle;
    18     private Activity mActivity;
    19 
    20     /**
    21      * 返回一个视图文件,相当于activity中的setContentView()
    22      */
    23     @Nullable
    24     @Override
    25     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    26         View view = inflater.inflate(R.layout.fragment_a,container,false);
    27         return view;
    28     }
    29 
    30     /**
    31      * 当View创建完成之后回调该方法
    32      */
    33     @Override
    34     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    35         super.onViewCreated(view, savedInstanceState);
    36 
    37         mTvTitle = view.findViewById(R.id.tv_title);
    38     }
    39 
    40 }

    BFragment

     1 package com.example.fragmentdemo;
     2 
     3 import android.os.Bundle;
     4 import android.view.LayoutInflater;
     5 import android.view.View;
     6 import android.view.ViewGroup;
     7 import android.widget.TextView;
     8 
     9 import androidx.annotation.NonNull;
    10 import androidx.annotation.Nullable;
    11 import androidx.fragment.app.Fragment;
    12 
    13 public class BFragment extends Fragment {
    14 
    15     private TextView mTvTitle;
    16 
    17     /**
    18      * 返回一个视图文件,相当于activity中的setContentView()
    19      */
    20     @Nullable
    21     @Override
    22     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    23         View view = inflater.inflate(R.layout.fragment_b,container,false);
    24         return view;
    25     }
    26 
    27     /**
    28      * 当View创建完成之后回调该方法
    29      */
    30     @Override
    31     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    32         super.onViewCreated(view, savedInstanceState);
    33 
    34         mTvTitle = view.findViewById(R.id.tv_title);
    35     }
    36 }

    (二)

    • Fragment中getActivity()为null的问题:当手机应用长期位于后台被回收后,当里面一些异步任务完成后回来getActivity时就为null

      •  1 package com.example.fragmentdemo;
         2 
         3 import android.app.Activity;
         4 import android.content.Context;
         5 import android.os.Bundle;
         6 import android.view.LayoutInflater;
         7 import android.view.View;
         8 import android.view.ViewGroup;
         9 import android.widget.TextView;
        10 
        11 import androidx.annotation.NonNull;
        12 import androidx.annotation.Nullable;
        13 import androidx.fragment.app.Fragment;
        14 
        15 public class AFragment extends Fragment {
        16 
        17     private TextView mTvTitle;
        18     private Activity mActivity;
        19 
        20     /**
        21      * 返回一个视图文件,相当于activity中的setContentView()
        22      */
        23     @Nullable
        24     @Override
        25     public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        26         View view = inflater.inflate(R.layout.fragment_a,container,false);
        27         return view;
        28     }
        29 
        30     /**
        31      * 当View创建完成之后回调该方法
        32      */
        33     @Override
        34     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        35         super.onViewCreated(view, savedInstanceState);
        36 
        37         mTvTitle = view.findViewById(R.id.tv_title);
        38         if(getActivity() != null){  //判断当前activity是否为null
        39 
        40         }else{
        41 
        42         }
        43     }
        44 
        45     /**
        46      * 当Fragment重建或者Fragment与Activity重新建立关系时运行这个方法
        47      * @param context
        48      */
        49     @Override
        50     public void onAttach(Context context) {
        51         super.onAttach(context);
        52         mActivity = (Activity)context;
        53     }
        54 
        55 
        56     /**
        57      * 当activity为null时必然运行了这个方法,就是Fragment与Activity脱离关系
        58      */
        59     @Override
        60     public void onDetach() {
        61         super.onDetach();
        62     }
        63 
        64     /**
        65      * Fragment回收
        66      */
        67     @Override
        68     public void onDestroy() {
        69         super.onDestroy();
        70 //        取消异步任务
        71     }
        72 }
    • 向Fragment传递参数

      1 //ContainerActivity:
      2 
      3 aFragment = AFragment.newInstance("我是参数");//传递参数给Fragment
       1 //AFragment:
       2 
       3 
       4     /**
       5      *传参
       6      */
       7     public static AFragment newInstance(String title){
       8         AFragment fragment = new AFragment();
       9         Bundle bundle = new Bundle();
      10         bundle.putString("title",title);
      11         fragment.setArguments(bundle);  //将bundle传入fragment;即便fragment重构,setArguments()方法也会运用反射机制将title重新放入fragment
      12         return fragment;
      13     }
      14 
      15 
      16 
      17     /**
      18      * 当View创建完成之后回调该方法
      19      */
      20     @Override
      21     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
      22         super.onViewCreated(view, savedInstanceState);
      23 //        if(getActivity() != null){  //判断当前activity是否为null
      24 //        }else{}
      25         mTvTitle = view.findViewById(R.id.tv_title);
      26         if(getArguments() != null){
      27             mTvTitle.setText(getArguments().getString("title"));
      28         }
      29     }

    (三)

    • Fragment回退栈

       1  AFragment:
       2 
       3         mBtnChange = view.findViewById(R.id.btn_change);
       4         mBtnReset = view.findViewById(R.id.btn_reset);
       5         mBtnChange.setOnClickListener(new View.OnClickListener() {
       6             @Override
       7             public void onClick(View v) {
       8                 if (bFragment == null) {
       9                     bFragment = new BFragment();
      10                 }
      11                 Fragment fragment = getFragmentManager().findFragmentByTag("a");
      12                 if (fragment != null) {
      13 //                    隐藏aFragment,再添加bFragment
      14                     getFragmentManager().beginTransaction().hide(fragment).add(R.id.fl_container, bFragment).addToBackStack(null).commit();
      15                 } else {
      16 //                  在commitNowAllowingStateLoss()方法之前加addToBackStack(null)将AFragment添加到回退栈里面,这样跳到BFragment再按返回键时,返回到AFragment,而不是MainActivity
      17 //                  replace可以理解为先remove再add,导致前一个fragment的视图没有被保存下来,虽然重新创建fragment视图了,但其视图内容也被重新创建了
      18                     getFragmentManager().beginTransaction().replace(R.id.fl_container, bFragment).addToBackStack(null).commit();
      19                 }
      20             }
      21         });

    (四)

    • Fragment和Activity的通信

    1. 方法一:
       1 AFragment
       2 
       3         mBtnMessage.setOnClickListener(new View.OnClickListener() {
       4             @Override
       5             public void onClick(View v) {
       6 //                通过getActivity()获得Activity,然后将其转换成ContainerActivity,调用它的setData()方法
       7 //                该方法能够向Activity传参,但不推荐
       8                 ((ContainerActivity)getActivity()).setData("你好");  //方法一
       9             }
      10         });
      1 ContainerActivity
      2 
      3   public void setData(String text){
      4         mTvTitle.setText(text);
      5     }

      这个方法可行但不推荐使用

    2. 方法二:在activity中实现fagment中声明的接口,通过回调接口来实现数据的传递

       1 AFragment
       2 
       3 
       4     /**
       5      * 接口
       6      */
       7     public interface IOnMessageClick{
       8         void onClick(String text);
       9     }
      10 
      11     /**
      12      * 当Fragment重建或者Fragment与Activity重新建立关系时运行这个方法
      13      *
      14      * @param context
      15      */
      16     @Override
      17     public void onAttach(Context context) {
      18         super.onAttach(context);
      19 //        mActivity = (Activity)context;
      20         try{
      21             listener = (IOnMessageClick) context;
      22         } catch (ClassCastException e) {
      23             throw  new ClassCastException("Activity 必须实现IOnMessageClick接口");
      24         }
      25 
      26     }
      27 
      28 mBtnMessage.setOnClickListener(new View.OnClickListener() {
      29             @Override
      30             public void onClick(View v) {
      31 //                通过getActivity()获得Activity,然后将其转换成ContainerActivity,调用它的setData()方法
      32 //                该方法能够向Activity传参,但不推荐
      33 //                ((ContainerActivity)getActivity()).setData("你好");  //方法一
      34                 listener.onClick("你好");
      35             }
      36         });
      1 ContainerActivity
      2 
      3 
      4     @Override
      5     public void onClick(String text) {
      6         mTvTitle.setText(text);
      7     }
  • 相关阅读:
    【英语】Bingo口语笔记(40)
    【英语】Bingo口语笔记(38)
    【Python系统学习】基础篇
    【英语】Bingo口语笔记(37)
    [转]linux下ulimit命令详解
    【转】linux read 用法
    【转】Linux下使用locale命令设置语言环境
    【转】基于linux下的变量声明declare的用法
    [转]Linux中set,env和export这三个命令的区别
    linux下echo命令详解(转)
  • 原文地址:https://www.cnblogs.com/jiani/p/11791345.html
Copyright © 2020-2023  润新知