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有时间或又需要再具体分析!
Fragment的粗浅理解的更多相关文章
- 对于Fragment的一些理解
前言 Fragment想必大家不陌生吧,在日常开发中,对于Fragment的使用也很频繁,现在主流的APP中,基本的架构也都是一个主页,然后每个Tab项用Fragment做布局,不同选项做切换,使用起 ...
- paxos算法之粗浅理解
paxos出身 paxos出身名门,它爹是没多久前获得图灵奖的在分布式领域大名鼎鼎的LeslieLamport. paxos为何而生 那么Lamport他老人家为什么要搞这个东东呢,不是吃饱了撑的,而 ...
- 对js闭包的粗浅理解
只能是粗浅的,毕竟js用法太灵活. 首先抛概念:闭包(closure)是函数对象与变量作用域链在某种形式上的关联,是一种对变量的获取机制.这样写鬼能看懂. 所以要大致搞清三个东西:函数对象(funct ...
- C#高级编程笔记 Delegate 的粗浅理解 2016年9月 13日
Delegate [重中之重] 委托 定义一:(参考)http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html 完全可 ...
- 对Java框架spring、hibernate、Struts的粗浅理解
对 Struts 的理解:1. struts 是一个按 MVC 模式设计的 Web 层框架,其实它就是一个大大的 servlet,这个Servlet 名为 ActionServlet,或是 Actio ...
- UNITY 画布的粗浅理解
画布:当画布是screen-space overlay时,这个好理解,画布可以控制如分辨率,层次等.但当画布是 world-space时,这个严格来说就不算是一个画布了,屏幕空间或相机空间的画布是先绘 ...
- 关于</div>的粗浅理解
</div>作为c#中常用的一个标签,在写多个区域的内容时有着十分重要的作用.如果写简单的网页时不用div可能感受不到太大的影响,但是在写较为复杂的程序时div的分隔作用就很明显了,改动大 ...
- function的粗浅理解
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 关于JavaScript闭包的粗浅理解
在JavaScript中,使用var创建变量,会创建全局变量或局部变量. 只有在非函数内创建的变量,才是全局变量,该变量可以在任何地方被读取. 而在函数内创建变量时,只有在函数内部才可读取.在函数外部 ...
随机推荐
- ubuntu16.04下python2、python3环境选择与python升级(pip版本切换)
参考链接:https://www.jianshu.com/p/63c1f22e1fed Ubuntu中python版本问题: 添加PPA: sudo add-apt-repository ppa:jo ...
- SQL注入之Sqli-labs系列第三十三关(基于宽字符逃逸注入)
开始挑战第三十三关(Bypass addslashes) 0x1查看源码 本关和第三十二关其实是一样的,只是这里用到了addslashes()函数 function check_addslashes( ...
- springboot中get post put delete 请求
组合注解(RequestMapping的变形) @GetMapping = @RequestMapping(method = RequestMethod.GET) @PostMapping = @Re ...
- 通用base.css —— 《编写高质量代码 web前端开发修炼之道》
@charset "utf-8"; /*CSS reset*/ html{color:#000;background:#FFF;} body,div,dl,dt,dd,ul,ol, ...
- 使用try和catch捕获异常
Java程序在执行过程中如果出现异常,会自动生成一个异常对象,该异常对象将被自动提交给JVM,当JVM接收到异常对象时,会寻找能处理这一异常的代码,并把当前异常对象交给其处理,这一过程称为捕获(cat ...
- alpha冲刺(6/10)
前言 队名:旅法师 作业链接 队长博客 燃尽图 会议 会议照片 会议内容 陈晓彬(组长) 今日进展: 召开会议 撰写博客 召集大家分析了一下后续的问题 问题困扰: 工程量太大,这周考试又很多,周末我让 ...
- python------面向对象进阶 异常处理
一. 异常处理 try: pass except KeyError as e : #注3.x用as ,except KeyError, e ,2.x 用逗号. print("No this ...
- 支持Oracle的模糊查询和精准查询
相信所有的软件开发者都做过页面上的查询功能,而且很多都需要既支持模糊查询的,也需要支持精准查询的,而且不需要增加多余的功能,只需要在文本框中输入包含类似*之类的符号即可. 下面的方法就是通过*来判断到 ...
- Javascript 将一个句子中的单词首字母转成大写
Javascript 将一个句子中的单词首字母转成大写 先上代码 function titleCase(str) { str = str.toLowerCase().split(" &quo ...
- Java虚拟机的内部体系结构
1.Java程序执行流程 Java程序的执行依赖于编译环境和运行环境.源码代码转变成可执行的机器代码,由下面的流程完成: Java技术的核心就是Java虚拟机,因为所有的Java程序都在虚拟机上运行. ...