Android 学习日志02 托管UI Fragment

来源:互联网 发布:linux ssh配置文件详解 编辑:程序博客网 时间:2024/06/05 05:06

写在前面:

  1. 因为Activity代码中添加的Fragment更灵活,所以这里讨论的是在activity代码中添加fragment,不考虑activity布局中添加Fragment.
  2. 这里用的是支持库版的Fragment,原因是支持库版的Fragment兼容性更好.

*1.Gradle依赖设置(app/build.gradle)
(现在的Studio已经帮我们完成了一二步,写在这里作为了解)
目前主流的都是使用支持库版的Fragment,它来自AppCompat库,因此我们在使用时,必须设置依赖.打开build.gradle(Module:app)文件,添加: compile ‘com.android.support:appcompat-v7:26.+’ .需要注意的是,如果是手动修改的话是需要同步项目和Gradle文件已更新修改的内容.

*2.修改模板代码
我们现在就可以把MainActivity.java文件改成

public class MainActivity extends AppCompatActivity {.}

3.创建Fragment容器布局
注意:当前的activity_fragment.xml文件仅由一个服务于单个fragment的容器视图组成,但托管的activity布局本身可以非常复杂.除了本身组建外,托管的activity布局还可以定义多个容器视图.

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"      android:id="@+id/fragment_container"      android:layout_width="match_parent"      android:layout_height="match_parent"/>

4.fragment视图布局文件
创建fragment视图文件就像创建activity的视图文件一样,这里不再赘述.
5.创建TestFragment.java类
注意这里导入的是支持库版的Fragment(android.support.v4.app)而不是android.app的fragment.

import android.support.v4.app.Fragment;public class TestFragment extends Fragment {}

6.覆盖Fragment.onCreate(Bundle)方法

@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {     super.onCreate(savedInstanceState);    }

这里需要说明几点的是:

  1. Fragment.onCreate(Bundle)是public权限,而Activity.onCreate(Bundle)是protected. Fragment.onCreate(Bundle)方法及其他的生命周期方法必须是公共的,因为托管Fragment的Activity需要调用它们.
  2. Fragment和Activity一样具有保存及获取状态的bundle,就像使用Activity.onSaveInstanceState(Bundle)方法那样,你也可以根据你的需求覆盖Fragment.onSaveInstanceState(Bundle)方法.
  3. fragment的视图并没有在Fragment.onCreate(Bundle)方法中生成,虽然我们可以在该方法中配置fragment实例,但是创建和配置fragment视图是Fragment另外一个生命周期完成的. 见下一步.

7.覆盖onCreateView(…)方法

@Override    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {        View v=inflater.inflate(R.layout.fragment_test,container,false);        return v;    }

该方法实例化fragment视图的布局,然后将实例化的View放回给托管的activity. LayoutInflater及ViewGroup是实例化布局的必要参数.Bundle是用来储存和恢复数据,可供该方法从保存状态下重建视图.
在onCreateView(…)方法中,fragment的视图是直接通过LayoutInflater.inflate(…)方法传入布局资源ID生成的.第二个参数container是视图的父视图,我们通常需要父视图来正确配置组件.第三个参数告诉布局生成器是否将生成的视图添加给父视图,这里,传入了false参数,因为我们将以代码的方式添加视图.
8.在fragment中实例化组件
实例化组件,设置监听方法等都在onCreateView(…){…}中进行,和在activity中实例化组件和设置监听方法没有任何区别,在这不再赘述.
9.将TestFragment添加给MianActivity
完成实例化组件之后,运行代码,我们的页面依然是空白的,这是为什么呢?这是因为fragment自己无法再屏幕显示视图,我们要把Fragment添加给Activity完成”托管” .
这里主角FragmentManager就要登场了.这很好理解,因为我们要以代码方式给Activity添加Fragment嘛,那这个代码方式就交给MainActivity的Fragment完成去吧.我们切回到MainActivity类的onCreate(…){…}方法中去,添加如下代码:

FragmentManager fm=getSupportFragmentManager();

FragmentManager就像Activity雇佣者用来管理他的Fragment.
10.给FragmentManager事情做
FragmentManager被雇佣来了,那么我们现在把任务分配给他吧:

Fragment fragment=fm.findFragmentById(R.id.fragment_container);if(fragment==null){    fragment=new TestFragment();                    fm.beginTransaction().add(R.id.fragment_container,fragment).commit();}

以上代码中,获取fragment不难理解.add(…)方法及其相关的代码才是重点.这段代码创建提交一个fragment事务.fragment事务被用来添加,移除,附加,分离或替换Fragment队列中的Fragment.这是使用Fragment动态组装用户界面的关键.FragmentManager.beginTransaction()方法创建并返回FragmentTransaction实例类支持流接口的链式调用,由此配置FragmentTransaction再返回它.因此fm.begin….commit()可以解读为:创建一个新的fragment事务,执行一个fragment添加操作,然后提交该事务.add()方法是整个事务的核心,它有两个参数:容器视图资源ID,和新创建的Fragment.

  1. 容器视图ID的作用:
    1)告诉FragmentManager, fragment视图应该出现在activity的什么位置
    2)唯一标识FragmentManager队列中的fragment.
  2. 使用R.id.fragment_container的视图资源ID,香FragmentManager请求获取fragment.如果要获取的fragment在队列中,FragmentManager就返回它.会出现这这种情况是因为设备旋转或回收内存时,Android会销毁MainActivity,而后来重建时,会调用MainActivity.onCreate(Bundle)方法. Activity被销毁时,他的FragmentManager会将fragment队列保存下来.这样,activity重建时,新的FragmentManager会先回去保存的队列,然后恢复到原有状态,当然,如果指定视图资源的ID的Fragment不在,就会创建新的fragment.
阅读全文
1 0
原创粉丝点击