• Fragment的粗浅理解


    Fragment:

    1.它是对于Activity界面实现的一种途径,相对于已经绑定的Layout,他更轻便,更灵活,更具有自由度和可设计性。

    2.Fragment的功能正如他的正文意思所言,他是一个片段,不同于Layout的整体界面设计,Layout是一个整体,而Fragment相当于Layout的一部分

    3.Activity只能绑定一个Layout界面,但一个Activity可以添加很多个Fragment界面。

    4.Fragment拥有类似于Activity的生命周期,用以配合界面显示和交互

    优势:相比于Activity跟轻量级,更加地高效和方便,无需在manifests文件中注册信息

    劣势:设计的界面无法像Activity一样,通过网络和包名调用,也就是说,它只能应用于本地开发

    Fragment的生命周期与Activity的生命周期对比:

    注:此图来自网络

    Fragment的方法执行顺序:

    1.在Activity执行onCreate()的时候,添加此Fragment界面,此时进入Fragment的生命周期

    2.生命周期执行顺序:(如图所示,以下是对于每个函数的调用时机和函数的作用)

    1.初始化阶段:

    onAttach(Activity)(当Fragment关联Activity时调用)>>>onCreate()>>>onCreateView(){此方法用来设计Fragment的界面}>>>onActivityCreated(){当Activity的onCreate()方法执行后返回时调用}
    2.运行阶段:

    基本与Activity一致,但Fragment的生命周期受制于Activity的周期:只有当Activity的生命周期处于onResumed()时,Fragment才能正常运行

    3.摧毁阶段:

    onDestoryedView(){摧毁Fragment的界面视图}>>>onDestoryed()>>>onDattch(){和Activity断开关联的时候调用此方法}

    Fragment的使用方法:

    1.在现在的Andtoid Studio中有默认的Fragment新建方法,

    2.也可以自行创立Fragment方法,完成绑定,方法基本一致,默认的新建方法已经自行添加了对应的重写方法和界面绑定。

    而自定义Fragment的步骤一般如下:

    1.新建一个自定义的class类,继承Frament类,在Layout文件夹下新建一个XML界面文件;

    (注:继承的Fragment来自的包邮几种,v4/app,当你使用你自己定义的Fragment的时候,一定要在使用的Activity中导入对应的Fragment包,否则会报错!)

    2.在自定义的class类中重写onCreateView()方法,找到新建的xml界面文件,绘制Fragment的界面,并且对于此Fragment中控件的监听也在这里设置,其他的方法根据需求重写(如果继承的是v4的Fragment,那么你还需要申明onFragmentInterActionListener接口,留待调用的Activity实现)

    3.在调用的Activity中添加此Fragment界面,并实现onFragmentInterActionListener接口(此接口可以空着不必书写任何内容,而具体他是用来干什么的,也并未弄清,以后看到此处,不懂去看,懂了补充)

    注:这个自定义的步骤过程,使用默认的Fragment创建,会自动添加和绑定,很是方便,即使新建的结果并不符合要求,也可以很轻松的修改。

    以上步骤的具体代码体现:

    package andrew.com.custompaintdemo;
    
    import android.content.Context;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v4.app.Fragment;          //在此使用的是V4包的Fragment类
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    public class BlankFragment extends Fragment {
        
        private static final String ARG_PARAM1 = "param1";      //这两个参数还没有弄明白具体用途
        private static final String ARG_PARAM2 = "param2";
    
        // TODO: Rename and change types of parameters
        private String mParam1;
        private String mParam2;
    
        private OnFragmentInteractionListener mListener;
    
        public BlankFragment() {                      //使用自定义的Fragment必须要给出一个空的构造方法
            // Required empty public constructor
        }
    
        public static BlankFragment newInstance(String param1, String param2) {
            BlankFragment fragment = new BlankFragment();
            Bundle args = new Bundle();
            args.putString(ARG_PARAM1, param1);
            args.putString(ARG_PARAM2, param2);
            fragment.setArguments(args);
            return fragment;              //这是返回Fragment对象的方法,这个方法将两个参数打包放入一个叫Argmentss属性中,
        }                         //此属性在源码中解释是construction Argments的bundle对象,但未发现与Fragment有何关联
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            if (getArguments() != null) {
                mParam1 = getArguments().getString(ARG_PARAM1);
                mParam2 = getArguments().getString(ARG_PARAM2);
            }
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment               //这里用来绑定Fragment的界面和空间监听事件
            return inflater.inflate(R.layout.fragment_main, container, false);
        }
    
        // TODO: Rename method, update argument and hook method into UI event
        public void onButtonPressed(Uri uri) {
            if (mListener != null) {
                mListener.onFragmentInteraction(uri);
            }
        }
    
        @Override
        public void onAttach(Context context) {
            super.onAttach(context);
            if (context instanceof OnFragmentInteractionListener) {
                mListener = (OnFragmentInteractionListener) context;
            } else {
                throw new RuntimeException(context.toString()
                        + " must implement OnFragmentInteractionListener");
            }
        }
    
        @Override
        public void onDetach() {
            super.onDetach();
            mListener = null;
        }
    
        public interface OnFragmentInteractionListener {      //此接口必须在调用此Fragment的界面的Activity中实现,但可以在实现时,不做任何处理
            // TODO: Update argument type and name
            void onFragmentInteraction(Uri uri);
        }
    }

    Activity界面中的代码:

    package andrew.com.custompaintdemo;
    
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;        //这里使用的是V7包中的AppCompatActivity,貌似V7兼容V4包的Fragment
                    //但需要注意的是,AppCompatActivity与一些控件存在版本差距,导致不兼容,如出现不兼容情况,可选择直接继承Activity
    public class MainActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState ==null){   getSupportFragmentManager()            //V7包中为getFragmentManager(),获取Fragment的管理
                           .beginTransaction()  //开始Fragment操作
                           .add(R.id.container ,
    new BlankFragment())  //从父容器添加Fragment界面,另一种方法是replace(),此方法包含了一个界面remove()和add()方法
                           .commit();                      //提交修改 } } @Override
    public void onFragmentInteraction(Uri uri) {    //这是声明后对于Fragment方法中的接口实现                                  //可以完全不写任何内容 } }


     

    以上是基本的Fragment实现方法,

    在基本方法的实现基础上,对于Fragment开发后出现了两种非常实用和美观的界面:SliderMenu Activity(侧滑界面),Tabbed (横向拉动切换界面)Activity。

    SliderMenuActivity 源代码组成解析:

    import android.os.Bundle;
    import android.support.design.widget.FloatingActionButton;
    import android.support.design.widget.Snackbar;
    import android.view.View;
    import android.support.design.widget.NavigationView;
    import android.support.v4.view.GravityCompat;
    import android.support.v4.widget.DrawerLayout;
    import android.support.v7.app.ActionBarDrawerToggle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    
    public class SliderViewDemo extends AppCompatActivity
            implements NavigationView.OnNavigationItemSelectedListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_slider_view_demo);        //控件组成:背景容器
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);      //控件组成:toolBar()这是一个处于顶部的横条控件
            setSupportActionBar(toolbar);
    
            FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);    //控件组成:右下角的邮箱按钮,
            fab.setOnClickListener(new View.OnClickListener() {                  //该邮箱按钮的点击监听事件
                @Override
                public void onClick(View view) {
                    Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                            .setAction("Action", null).show();
                }
            });
    
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);      //这是SliderMenu的主界面,绑定后设置一个ActionBarDrawerToggle
            ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(              //这里设置的navigation_drawer_open/close用于在onBackPressed中判断
                    this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
            drawer.setDrawerListener(toggle);
            toggle.syncState();      //可能这里有反复调用的同步逻辑,尚未研究透彻
    
            NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);  //控件组成:左侧列表的选项视图
            navigationView.setNavigationItemSelectedListener(this);                //由于本Activity实现了本方法,所以可以直接使用this
        }
    
        @Override
        public void onBackPressed() {                                //此函数是当界面处于左侧菜单列表时,
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);     //用于按下返回键后,回到主界面的,其中具体的函数逻辑暂时不清楚
            if (drawer.isDrawerOpen(GravityCompat.START)) {                    
                drawer.closeDrawer(GravityCompat.START);
            } else {
                super.onBackPressed();
            }
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {                     //这里绑定右上角设置的menu内容
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.slider_view_demo, menu);
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {                  //这里添加对右上角setting内容的监听事件
            // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
            // as you specify a parent activity in AndroidManifest.xml.
            int id = item.getItemId();
    
            //noinspection SimplifiableIfStatement
            if (id == R.id.action_settings) {
                return true;
            }
    
            return super.onOptionsItemSelected(item);
        }
    
        @SuppressWarnings("StatementWithEmptyBody")
        @Override
        public boolean onNavigationItemSelected(MenuItem item) {              //这里添加对左侧菜单选项的监听事件
            // Handle navigation view item clicks here.
            int id = item.getItemId();
    
            if (id == R.id.nav_camera) {
                // Handle the camera action
            } else if (id == R.id.nav_gallery) {
    
            } else if (id == R.id.nav_slideshow) {
    
            } else if (id == R.id.nav_manage) {
    
            } else if (id == R.id.nav_share) {
    
            } else if (id == R.id.nav_send) {
    
            }
    
            DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
            drawer.closeDrawer(GravityCompat.START);
            return true;              //经测试,这里设置为false则所有的选项监听不执行
        }
    }

    在以上的SliderMenu Activity中使用了很多Frament的碎片化布局相互配合,共同实现了整体的界面效果,接下来解析Fragment部分的运行方式。

    在XML文档中设置的Fragment界面中,共有四个界面组成部分:

    1.activity_slider_view_demo(这是左侧菜单栏的Fragment)

    代码分析:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
      // include是一种优化布局的方式,将app_bar_slider_view_demo这个界面在背后显示,产生层次效果 <include layout="@layout/app_bar_slider_view_demo" android:layout_width="match_parent" android:layout_height="match_parent" />    
    //这是实际的左侧菜单栏的界面 <android.support.design.widget.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true"
         
         //这段代码绑定了nav_header_slider_view_demo的Fragment内容,该内容设计了左侧菜单栏的个人信息内容  app:headerLayout
    ="@layout/nav_header_slider_view_demo"   //这段代码用于绑定menu中的activity_slider_view_demo_drawer界面,该界面设计了左侧菜单具体的选项内容
         app:menu
    ="@menu/activity_slider_view_demo_drawer" />       (注:为结构清晰明了,在res目录下新建了menu文件夹,在此文件夹下添加的Fragment界面内容)

    </android.support.v4.widget.DrawerLayout>


    2.app_bar_slider_view_demo

    具体代码分析:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.design.widget.CoordinatorLayout 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"
        android:fitsSystemWindows="true"
        tools:context="andrew.com.custompaintdemo.SliderViewDemo">
    
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/AppTheme.AppBarOverlay">
    
            <android.support.v7.widget.Toolbar              //这是一段系统给出的自定义控件界面,其中只有一个ToolBar,用来显示标题
                android:id="@+id/toolbar"                 //此AppBarLayout仅仅占用了一个标题栏的内容
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>           <include layout="@layout/content_slider_view_demo" />    //在标题存在的情况下,使用include标签显示content_slider_view_demo界面中的内容            //此Fragment是作为正式的显示内容,默认为空,可以由我们自己设置,使用默认的建立方法后,若想设置自己的内容样式,就是在此Fragment中设计

      <android.support.design.widget.FloatingActionButton      //这是右下角的邮箱图标的控件 android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="@dimen/fab_margin" android:src="@android:drawable/ic_dialog_email" /> </android.support.design.widget.CoordinatorLayout>

    3.content_slider_view_demo

    代码分析:

    <?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"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="andrew.com.custompaintdemo.SliderViewDemo"
        tools:showIn="@layout/app_bar_slider_view_demo">

      //这是默认的正文显示内容,新建的时候,默认为空白
      //可以当做这里就是Activity的绑定界面,自定义一切可用控件
      //整个SliderMenu Activity只是一个框架,他提供了一个相对美观和具有良好交互体验的一个界面模板,而我们真正的设计,在这个Fragment中开始 </RelativeLayout>

    4.nav_header_slider_view_demo

    代码分析:

    <?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="@dimen/nav_header_height"
        android:background="@drawable/side_nav_bar"
        android:gravity="bottom"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        android:theme="@style/ThemeOverlay.AppCompat.Dark">
      

      //这里正式先前提到的左侧聊表的个人信息模块设计面板
      //其中包括了头像,名称,邮箱
      //若我们需要显示不同的信息内容,也可以在这里进行自定义开发 <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" android:src="@android:drawable/sym_def_app_icon" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingTop="@dimen/nav_header_vertical_spacing" android:text="Android Studio" android:textAppearance="@style/TextAppearance.AppCompat.Body1" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android.studio@android.com" /> </LinearLayout>


    另外在res目录下,默认创建的menu文件中存在两个辅助文件:

    1.activity_slider_view_demo_drawer(这是左侧菜单栏的选项设计)

    具体代码:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <group android:checkableBehavior="single">
            <item
                android:id="@+id/nav_camera"                
                android:icon="@drawable/ic_menu_camera"
                android:title="Import" />            //选项名称:import
            <item
                android:id="@+id/nav_gallery"
                android:icon="@drawable/ic_menu_gallery"
                android:title="Gallery" />          
            <item
                android:id="@+id/nav_slideshow"
                android:icon="@drawable/ic_menu_slideshow"
                android:title="Slideshow" />
            <item
                android:id="@+id/nav_manage"
                android:icon="@drawable/ic_menu_manage"
                android:title="Tools" />
        </group>
    
        <item android:title="Communicate">
            <menu>
                <item
                    android:id="@+id/nav_share"
                    android:icon="@drawable/ic_menu_share"
                    android:title="Share" />
                <item
                    android:id="@+id/nav_send"
                    android:icon="@drawable/ic_menu_send"
                    android:title="Send" />
            </menu>
        </item>
    
    </menu>
    //注:这里不再是Fragment的内容,而是资源文件


    2.slider_view_demo(这里设计的是右上角的设置内容)

    具体代码:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/action_settings"      //这里只设计了一个setting选项
            android:orderInCategory="100"
            android:title="@string/action_settings"
            app:showAsAction="never" />
    </menu>


    PS:

    Tabbed Activity有时间或又需要再具体分析!

  • 相关阅读:
    Arch Linux 安装 ibus-rime
    macOS安装Python MySQLdb
    CentOS 7 安装 gcc 4.1.2
    Windows 10安装Python 2.7和MySQL-python
    小米Air安装Arch Linux之图形界面配置(Gnome 和 sway)持续更新中……
    小米Air 13.3 安装Arch Linux
    Linux Shell脚本攻略总结(1)
    Ubuntu下删除配置错误或者失败的安装包
    oProfile的安装与使用
    动态链接库VS静态链接库
  • 原文地址:https://www.cnblogs.com/thinfog/p/5707743.html
Copyright © 2020-2023  润新知