Android Fragment学习笔记(1)———简单Fragment实现

我们使用某些app的时候可能会有类似经历,想连续翻看多个人的空间资料,却只能一个一个点击用户名打开,如果不需要返回,直接滑动翻看各个人的空间就好了。activity自身并不具有这样的灵活性。activity视图可以在运行时切换,但控制视图的代码必须在activity中实现。因此各个activity还是得和特定的用户屏幕紧紧绑定在一起。采用Fragment就可以绕开activity规则的限制。Fragment是一种控制器对象,activity可以委派它完成一些任务。通常这些任务就是管理用户界面。受管的可以是一整屏或是整屏的一部分。

--------------------------------------------------------------------------------我是分割线= =--------------------------------------------------------------------


我采用了《Android编程权威指南》中的例子:通过创建一个管理陋习的app来学习Fragment起初我们只需要简单实现三个类:Crime。CrimeFragment,CrimeAcivity。实例代表了某种陋习,比如乱扔垃圾,插队。一个crime只有一个标题(陋习描述)和标识ID(UUID唯一元素)。CrimeActivity视图由FrameLayout组件构成,FrameLayout组件为CrimeFragment要显示的视图安排了存放位置。CrimeFragment的视图由一个LinearLayout组件及一个EditText组成。CrimeFragment类中有一个存贮editText的成员变量(mTitleField)。mTitleField上设有监听器,当EditText的文字发生变化时,用来更新模型层数据。

一句话:用户界面由UI Fragment进行管理,而Fragment的实例将通过acitvity来托管。


Android Fragment学习笔记(1)———简单Fragment实现_第1张图片

1.创建Crime类(模型层)


import java.util.UUID;

public class Crime {
	private UUID mId;
	private String mTitle;
	
	public Crime(){
		//生成唯一标识
		mId = UUID.randomUUID();
	}

	public String getTitle() {
		return mTitle;
	}

	public void setTitle(String mTitle) {
		this.mTitle = mTitle;
	}

	public UUID getId() {
		return mId;
	}
	
}



2.托管UI Fragment:

为托管UI Fragment,activity必须做到:

在布局文件中为fragment的视图安排位置;

管理fragment实例的生命周期;

Android Fragment学习笔记(1)———简单Fragment实现_第2张图片


因为fragment代表activity在工作,它的状态也应该反映了activity的状态。因而,fragment需要对用的生命周期方法来处理activity工作。

fragment生命周期与activity生命周期的一个关键区别就在于,fragment的生命周期的方法是由activity操作而不是操作系统调用的。操作系统无从知晓activity用来管理视图 的fragment。fragment的使用时activity自己内部的事情

托管的两种方式:

1:添加fragment到activity布局当中去;
2:在activity代码中添加fragment。

我们肯定要优先选择后者,因为第一种等同于把fragment 和activity绑定在一起,且在activity的生命周期的过程中,无法切换fragment视图。
第二种是唯一一种可以在运行时控制fragment方式,可以在任意时刻添加,删除,替换。因此,为了真正获得UI设计的灵活性,我们必须通过代码的方式添加fragment。这也是我们用CrimeActivity托管CrimeFragment的方式。

--------------------------------------------------------------------------我是分割线-----------------------------------------------------------------------------------------------------------------------
虽然我们窑子托管的activity代码中添加UI fragment,但是还是需要子activity视图中给fragment安排一个视图的


注:FrameLayout是服务于CrimeFragment的容器视图。但注意容器视图是通用性视图,不局限于CrimeFragment类,我们可以并且也将使用用一个布局来托管其他的fragment

创建UI fragment

创建UI fragment 的过程和创建一个activity的步骤相同:

1.定义布局文件;

2.创建fragment类并设置其视图为定义的布局;

3.通过代码的方式,连接布局文件中生成的组件

定义CrimeFragment( fragment_crime)的布局:




    

3.创建CrimeFragment类

记得继承的是android.support.v4.app.Fragment包下的Fragment

package com.example.crimialintent;

import android.app.FragmentManager;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

public class CrimeFragment extends Fragment {

	private Crime mCrime;
	private EditText mTitleField;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		mCrime = new Crime();// 新增一个成员变量实例;
		
		
	}

	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {// bundle包含供该方法在保存状态下重建视图所使用的数据
		View v = inflater.inflate(R.layout.fragment_cime, container, false);// 第三个参数是是否将生成的视图添加给父视图
		/**
		 * Fragment.onCreateView(...)方法中的组建引用几乎等同于Activity.onCreate(...)方法的处理。
		 * 唯一的区别是我们调用了fragment视图的View.findViewById(int)方法。
		 * 以前使用Activity.findViewById十分便利,能够在 后台自己调用View.findViewById(int)方法。
		 *而frament类没有对应的便利方法,因此我们必须完成调用
		 **/

		mTitleField = (EditText) v.findViewById(R.id.crime_title);
		mTitleField.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				mCrime.setTitle(s.toString());// 给crime设置陋习标题
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				// TODO Auto-generated method stub

			}

			@Override
			public void afterTextChanged(Editable s) {
				// TODO Auto-generated method stub

			}
		});

		return v;
	}

}
以上代码中注意以下几点:

Fragment.onCreate(Bundle)是公共方法,不同于activity.onCreate()的Protect方法,因此Fragment.onCreate(Bundle)方法及其他Fragment生命周期必须设计为公共方法

在onCreate方法中,并没有生成fragment视图,但是配置了fragment实例,但创建和配置fragment视图都是通过另一个生命周期方法onCreateView()来实现


----------------------------------------------------------我是fragment的分割线= =,下面是托管到activity的部分--------------------------------------------------------------------------

4.利用FragmentManager管理fragment

Android Fragment学习笔记(1)———简单Fragment实现_第3张图片

在activity中,FragmentManager类负责管理fragment并将它们的视图添加到activity的视图层级结构中。

上代码!...

package com.example.crimialintent;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class CrimeActivity extends FragmentActivity { //继承自FragmentActivity
	

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_crime);

		/*
		 * 将Fragment添加到activity中: 1.获取FragmentManager
		 * 2.获取一个Fragment交由FragmentManager管理
		 */
		FragmentManager fm = getSupportFragmentManager();// 获取FragmentManager本身
		Fragment fragment = fm.findFragmentById(R.id.fragmentContainer);//通过资源ID向FragmentMananger请求获取Fragment

		if (fragment == null) {
			fragment = new CrimeFragment();
			
			//创建一个新的Fragment事务,加入一个添加操作,然后提交事务
			fm.beginTransaction().add(R.id.fragmentContainer, fragment)
					.commit();
		}

	}

}
提示一点:FragmentManager是使用FrameLayout的资源ID去识别CrimeFragment的,资源ID主要有两点作用:一是告知FragmentManager视图 应该出现在activity视图什么地方;二是ID为FragmentManager队列中fragment的唯一标识符。


好了,一个简单的fragment就实现了,文字细节描述有点多,但是很精华(自认为)。。。

Android Fragment学习笔记(1)———简单Fragment实现_第4张图片
注:本文参考《Android编程权威指南》







你可能感兴趣的:(android,fragment,界面,android)