• Fragment碎片


    Fragment的生命周期:

      onAttach():onAttach()方法会在Fragment与Activity窗口关联后立刻调用。

      onCreate():在调用完onAttach()执行完之后,立即就会调用onCreate()方法,可以在Bundle对象中获取一些在Activity中传过来的数据。通常会在该方法中读取保存的转态,获取或初始化一些数据。在该方法中不要进行耗时操作,不然Activity窗口不会显示。

      onCreateView():在该方法中创建Fragment显示的View,其中inflater是用来装载布局文件的,container是<fragment>标签的父标签对应对象,saveInstanceState参数可以获取Fragment保存的状态,如果未保存那么就为null。

      onActivityCreated():在Activity的onCreate()方法执行完之后,Android系统会立刻调用该方法,表示Activity窗口已经初始化完成,从这一个时候开始,就可以在Fragment中使用getActivity().findViewById(R.id.xxx);来操作Activity中的view了。

      onStart():当系统调用该方法的时候,fragment已经显示在UI上了,但还不能进行互动,因为onResume()方法还没有执行完。
      onResume():该方法为fragment从创建到显示Android系统调用的最后一个生命周期方法,调用完该方法时候,fragment就可以与用户互动了。
      onPause():fragment由活动状态变成非活跃执行的第一个回调方法,通常可以在这个方法中保存一些需要临时暂停的工作。
      onStop():当onStop()返回的时候,fragment将从屏幕上消失。
      onDestoryView():该方法的调用意味着在onCreateView()中创建的视图都将被移除。
      onDestroy():Android在Fragment不再使用时会调用该方法,此时Activity可以获得Fragment对象,但无法对获得的Fragment进行任何操作。
      onDetach():为Fragment生命周期中的最后一个方法,当该方法执行完后,Fragment与Activity不再有关联。  

    布局文件中添加碎片

    1、在onCteate()方法中调用inflater.inflate()加载Fragment布局

      用创建一个Fragment,必须先创建一个Fragment的子类,至少调用onCreate(),onCreateView(),onPause()。

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

    2、在xml的<fragment>中需要显示指明碎片名称(android:name="com.exmple.fragment.LeftFragment")需要将类的包名加上。

    动态添加碎片

    1、创建待添加的碎片实例

    2、获取FragmentManager,在活动中可以直接掉用getFragmentManager()方法得到。

    3、开启一个事务,通过调用beginTransaction()方法开启。

    4、向容器中加入碎片,使用replace()方法实现,需要传入容器的id和待添加碎片实例。

    5、提交事务,调用commit()方法。

    public void onClick(View v){
      Fragment fragment = new FragmentRightFragment();
      FragmentManager fargmentManager = getFragmentManager();
      FragmentTransaction transaction = fragmentManager.beginTransaction();
      transaction.replace(R.id.right_layout,fragment);
      transaction.commit();
    }

    返回上一个碎片

      transaction.addToBackStack()

    在activity中获得Fragment的实例。

      getFragmentManager.findFragmentById()

    调用activity中的方法

      getActivity()获取activity对象。

    Fragment中附加的回调方法

    1、onAttach():碎片与活动建立关联时调用

    2、onCreateView():碎片创建视图时调用。

    3、onActiviCreated():确保与碎片关联的活动已经创建完毕时调用

    4、onDestroyView():与碎片关联的视图被移除时调用

    5、onDetacd():碎片与活动解除关联时调用。

    在Fragment中也可以使用onSaveInstanceState()保存数据。

    动态加载布局技巧

    1、限定符:实现单双页模式

      大小:small、normal、large、xlarge

      分辨率:ldpi、mdpi、hdpi、xhdpi

      方向:land、port

    Fragment与Activity交互

      1、将Fragment添加到activity之中

        可以通过在activtiy布局文件中声明fragment,用fragment标签把fragment插入到activity的布局中,或者是用应用程序源码将它添加到一个存在的ViewGroup中。但fragment并不是一定要作为activity布局的一部分,fragment也可以为activity隐身工作。
      (1).在activity的布局文件里声明fragment
    <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="match_parent"> 
    
          <fragment android:name="com.example.test.FragmentOne"
                  android:id="@+id/fo"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
      </LinearLayout>
      每个fragment都需要一个唯一的标识,如果重启activity,系统可用来恢复fragment(并且可用来捕捉fragment的事务处理,例如:移除fragment),为fragment提供了ID有三种方法:
        1:>用android:id属性提供一个唯一的标识
        2:>用android:tag属性提供一个唯一的字符串。
        3:>如果上述两种属性都没有,系统会使用其容器视图(view)的ID。
      (2).通过编码将fragment添加到已存在的ViewGroup中
        在activity运行的任何时候,你都可以将fragment添加到activity布局中。要管理activity中的fragment,可以使用FragmentManager。可以通过在activity中调用getFragmentManager()获得。
        FragmentManager的相关方法:
          1>、findFragmentById():用于在activity布局中提供有界面的fragment或者findFragmentByTag()获取activity中存在的fragment。
          2>、popBackStack():从后台栈弹出fragment。
          3>、addOnBackStackChangeListener():注册一个监听后台栈变化的监听器。
        FragmentTransaction:用于Fragment的事务操作。
          1:>显示:add(), replace(), show(), attach()
          2:>隐藏:remove(), hide(), detach()
        获取FragmentTransaction实例
    FragmentManager fragmentManager = getFragmentManager() 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
     说明:调用show() & hide()方法时,Fragment的生命周期方法并不会被执行,仅仅是Fragment的View被显示或者​隐藏。执行replace()时(至少两个Fragment),会执行第二个Fragment的onAttach()方法、执行第一个Fragment的onPause()-onDetach()方法,同时containerView会detach第一个Fragment的View。add()方法执行onAttach()-onResume()的生命周期,相对的remove()就是执行完成剩下的onPause()-onDetach()周期。
    ExampleFragment fragment = new ExampleFragment();
    fragmentTransaction.add(R.id.fragment_container, fragment);
    fragmentTransaction.commit();

      (3).添加没有界面的fragment

        也可以使用fragment为activity提供后台动作,却不呈现多余的用户界面。想要添加没有界面的fragment ,可以使用add(Fragment, String)(为fragment提供一个唯一的字符串“tag”,而不是视图(view)ID)。这样添加了fragment,但是,因为还没有关联到activity布局中的视图(view) ,收不到onCreateView()的调用。所以不需要实现这个方法。对于无界面fragment,字符串标签是唯一识别它的方法。如果之后想从activity中取到fragment,需要使用findFragmentByTag()。 
      
      Fragment与Activity之间的交互可以通过Fragment.setArguments(Bundle args)以及Fragment.getArguments()来实现。
     
    Fragment状态的持久化:

    由于Activity会经常性的发生配置变化,所以依附它的Fragment就有需要将其状态保存起来问题。下面有两种常用的方法去将Fragment的状态持久化。

    • 方法一
      可以通过protected void onSaveInstanceState(Bundle outState),protected void onRestoreInstanceState(Bundle savedInstanceState)状态保存和恢复的方法将状态持久化。
    • 方法二(更为方便,让Android自动帮我们保存Fragment状态)

    • <1>.我们只需要将Fragment在Activity中作为一个变量整个保存,只要保存了Fragment,那么Fragment的状态就得到保存了。

    FragmentManager.putFragment(Bundle bundle, String key, Fragment fragment) 是在Activity中保存Fragment的方法。
    FragmentManager.getFragment(Bundle bundle, String key) 是在Activity中获取所保存的Frament的方法。
        <2>.很显然,上述<1>中的key就传入Fragment的id,fragment就是你要保存状态的fragment,但,我们注意到上面的两个方法,第一个参数都是Bundle,这就意味着FragmentManager是通过Bundle去保存Fragment的。但是,这个方法仅仅能够保存Fragment中的控件状态,比如说:EditText中用户已经输入的文字(注意:在这里,控件需要设置一个id值,否则Android将不会为我们保存该控件的状态),而Fragment中需要持久化的变量依然会丢失,但依然有解决方法,就是利用方法一!
        <3>.下面给出状态的持久化实例代码:
    FragmentB fragmentB;
    
      @Override
      protected void onCreate(@Nullable Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.fragment_activity);
          if( savedInstanceState != null ){
              fragmentB = (FragmentB) getSupportFragmentManager()
                          .getFragment(savedInstanceState,"fragmentB");
          }
          init();
      }
    
      @Override
      protected void onSaveInstanceState(Bundle outState) {
          if( fragmentB != null ){
             getSupportFragmentManager()
               .putFragment(outState,"fragmentB",fragmentB);
          }
          super.onSaveInstanceState(outState);
      }
    
      /** Fragment中保存变量的代码 **/
      @Nullable
      @Override
      public View onCreateView(LayoutInflater inflater, @Nullable 
          ViewGroup container, @Nullable Bundle savedInstanceState) {
          AppLog.e("onCreateView");
          if ( null != savedInstanceState ){
              String savedString = savedInstanceState
                                   .getString("string");
              //得到保存下来的string
          }
          View root = inflater.inflate(R.layout.fragment_a,null);
          return root;
      }
    
      @Override
      public void onSaveInstanceState(Bundle outState) {
          outState.putString("string","anAngryAnt");
          super.onSaveInstanceState(outState);
      }
    管理Fragment回退栈

    跟踪回退栈的状态
    我们通过实现OnBackStackChangedListener接口来实现回退栈状态跟踪,具体代码如下:

    /implements接口
    public class XXX implements FragmentManager.OnBackStackChangedListener 
    //实现接口所要实现的方法
    @Override
    public void onBackStackChanged() {
      //do whatevery you want
    }
    //设置回退栈监听接口
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    管理回退栈
    (1).FragmentTransaction.addToBackStack(String)
    将一个刚刚添加的Fragment加入到回退栈中
    (2).getSupportFragmentManager().getBackStackEntryCount()
    获取回退栈中的实体数量
    (3).getSupportFragmentManager().popBackStack(String name, int flags)
    根据name立刻弹出栈顶的fragment
    (4).getSupportFragmentManager().popBackStack(int id, int flags)
    根据id立刻弹出栈顶的fragment
     
    Activity与Fragment之间的数据传递
    1、Activity传递给Fragment
      采用 Bundle方式。
    • 步骤1:Activity的布局文件
    LinearLayout 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/text"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="我是Activity" />
    
        <FrameLayout
            android:layout_below="@+id/button"
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="500dp"/>
    </LinearLayout>
    • 步骤2:设置 Fragment的布局文件
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorAccent"
        >
    
        <TextView
            android:id="@+id/fragment"
            android:text="我是fragment"
            android:layout_gravity="center"
            android:textSize="30dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            />
    
        <TextView
            android:id="@+id/text"
            android:layout_gravity="center"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="等待Activity发送消息" />
    
        <Button
            android:id="@+id/button"
            android:layout_gravity="center"
            android:text="点击接收Activity消息"
            android:layout_centerInParent="true"
            android:textSize="20dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    • 步骤3:设置Activity的类文件

    Activity2Fragment

    public class Activity2Fragment extends AppCompatActivity {
    
        TextView text;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activcity_2_fragment);
    
            text = (TextView) findViewById(R.id.text);
    
            // 步骤1:获取FragmentManager
            FragmentManager fragmentManager = getFragmentManager();
    
            // 步骤2:获取FragmentTransaction
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            // 步骤3:创建需要添加的Fragment 
            final mFragment fragment = new mFragment();
    
            // 步骤4:创建Bundle对象
            // 作用:存储数据,并传递到Fragment中
            Bundle bundle = new Bundle();
    
            // 步骤5:往bundle中添加数据
            bundle.putString("message", "I love Google");
    
            // 步骤6:把数据设置到Fragment中
            fragment.setArguments(bundle);
    
            // 步骤7:动态添加fragment
            // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
            fragmentTransaction.add(R.id.fragment_container, fragment);
            fragmentTransaction.commit();
    
    
        }
    }
    • 步骤4:设置Fragment的类文件
    public class mFragment extends Fragment {
        Button button;
        TextView text;
        Bundle bundle;
        String message;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View contentView = inflater.inflate(R.layout.fragment, container, false);
            // 设置布局文件
    
            button = (Button) contentView.findViewById(R.id.button);
            text = (TextView) contentView.findViewById(R.id.text);
    
            // 步骤1:通过getArgments()获取从Activity传过来的全部值
            bundle = this.getArguments();
    
            // 步骤2:获取某一值
            message = bundle.getString("message");
    
            // 步骤3:设置按钮,将设置的值显示出来
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    // 显示传递过来的值
                    text.setText(message);
    
                }
            });
    
            return contentView;
        }
    }

    2、Fragment传递给Activity

      采用 接口回调 方式。

    • 步骤1:在Activity的布局文件定义1占位符(FrameLayout
    RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="scut.carson_ho.fragment_2_activity.MainActivity">
    
        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="等待Fragment发送消息" />
    
        <Button
            android:id="@+id/button"
            android:layout_below="@+id/text"
            android:text="点击接收Fragment消息"
            android:layout_centerInParent="true"
            android:textSize="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <FrameLayout
            android:layout_below="@+id/button"
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="500dp"/>
    
    </RelativeLayout>
    • 步骤2:设置Fragment的布局文件
    <?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"
        >
    
        <TextView
            android:id="@+id/fragment"
            android:text="我是fragment"
            android:gravity="center"
            android:textSize="30dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/colorAccent"/>
    
    </LinearLayout>

      步骤3:设置回调接口

    ICallBack.java

    public interface ICallBack {
        void get_message_from_Fragment(String string);
    }
    • 步骤4:设置Fragment的类文件
    public class mFragment extends Fragment {
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View contentView = inflater.inflate(R.layout.fragment, container, false);
            // 设置布局文件
            return contentView;
        }
    
        // 设置 接口回调 方法
        public void sendMessage(ICallBack callBack){
    
            callBack.get_message_from_Fragment("消息:我来自Fragment");
    
        }
    }
    • 步骤5:设置Acticvity的类文件
    public class MainActivity extends AppCompatActivity {
    
        Button button;
        TextView text;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            button = (Button)findViewById(R.id.button);
            text = (TextView)findViewById(R.id.text);
    
            // 步骤1:获取FragmentManager
            FragmentManager fragmentManager = getFragmentManager();
    
            // 步骤2:获取FragmentTransaction
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    
            // 步骤3:创建需要添加的Fragment 
            final mFragment fragment = new mFragment();
    
            // 步骤4:动态添加fragment
            // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
            fragmentTransaction.add(R.id.fragment_container, fragment);
            fragmentTransaction.commit();
    
    
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                    // 通过接口回调将消息从fragment发送到Activity
                    fragment.sendMessage(new ICallBack() {
                        @Override
                        public void get_message_from_Fragment(String string) {
                                text.setText(string);
                        }
                    });
    
                }
            });
        }
    
    
    }

     

    参考文献:http://www.jianshu.com/p/94bede7d6f46
           http://www.jianshu.com/p/825eb1f98c19
      

  • 相关阅读:
    docker 命令(我使用过的)
    docker 概述
    RabbitMq 概述
    spring cloud gateway
    redis-集群(codis和Cluster)
    jdbc 简单示例和优缺点
    git
    Mycat--概述
    线程池
    同步容器和并发容器
  • 原文地址:https://www.cnblogs.com/yl-saber/p/6054823.html
Copyright © 2020-2023  润新知