Android_Fragment

一. Fragment的简介

    Fragment在Android 3.0( API 11)引入,是为了支持在大屏上显示更加动态、灵活的UI,比如在平板和电视上。Fragment可以看作是嵌套的Activity,类似ActivityGroup,但是开销肯定没有ActivityGroup那么大,每一个Fragment管理着一个View,Fragment彼此之间相互独立,有自己的生命周期,这个生命周期是在Activity生命周期中的。Fragment可以用来解决屏幕适配和动态创建View的问题。


二.Fragment的生命周期

       Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。

Android_Fragment_第1张图片


可以看到FragmentActivity多了几个额外的生命周期回调方法:
onAttach(Activity)

       当FragmentActivity发生关联时调用。
onCreateView(LayoutInflater,ViewGroup,Bundle)

       创建该Fragment的视图
onActivityCreated(Bundle)

       当ActivityonCreate方法返回时调用
onDestoryView()

       与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()

       与onAttach相对应,当FragmentActivity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现!


三.Fragment常用的API

Fragment常用的三个类:

android.app.Fragment主要用于定义Fragment


android.app.FragmentManager主要用于在Activity中操作Fragment

   (1)获取FragmentManage的方式:getFragmentManager()// v4中,getSupportFragmentManager

   (2)使用findFragmentById() (用于在activity layout中提供一个UI的fragment)或findFragmentByTag()(适用于有或没有UI的fragment)获取activity中存在的fragment
   (3)将fragment从后台堆栈中弹出, 使用 popBackStack() (模拟用户按下BACK 命令).
   (4)使用addOnBackStackChangeListener()注册一个监听后台堆栈变化的listener.

android.app.FragmentTransaction每一个事务都是同时要执行的一套变化.可以在一个给定的事务中设置你想执行的所有变化,

FragmentTransaction的主要的操作方法

FragmentTransactiontransaction = fm.benginTransatcion();//开启一个事务

transaction.add() 

    往Activity中添加一个Fragment

transaction.remove()

    从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。

transaction.replace()

    使用另一个Fragment替换当前的,其实就是remove()然后add()

transaction.hide()

    隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

transaction.show()

    显示之前隐藏的Fragment

detach()

    会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

attach()

    重建view视图,附加到UI上并显示。

transatcion.commit()//提交一个事务

注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。还有就是在一个事务开启到提交可以进行多个的添加、移除、替换等操作。

 

四.Fragment的使用

静态使用Fragment

        1.继承Fragment,重写onCreateView决定Fragemnt的布局(加载Fragment的布局)

         2.Activity中声明此Fragment,就当和普通的View一样

       ( 注意:要给Fragment设置ID,要不无法初始化报错)

先看看布局:

Android_Fragment_第2张图片



静态使用Fragment的下载地址:http://download.csdn.net/detail/two_water/9279253


动态使用Fragment

1.效果图:

.Android_Fragment_第3张图片


代码上主界面的代码,其他的想看就下载来看看:

<span style="font-size:12px;"><pre name="code" class="java">package com.liangdianshui.fragment2;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity implements OnClickListener {

	private Button mBtNews;
	private Button mBtEntertainment;
	private Button mBtSports;
	private Button mBtInternational;
	private FrameLayout mContent;
	private MyFragmentNews frNews;
	private MyFragmentEntertainment myFragmentEntertainment;
	private MyFragmentInternational myFragmentInternational;
	private MyFragmentSports myFragmentSports;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		init();

	}

	private void init() {
		mContent = (FrameLayout) findViewById(R.id.fm_content);
		mBtNews = (Button) findViewById(R.id.bt_news);
		mBtEntertainment = (Button) findViewById(R.id.bt_entertainment);
		mBtSports = (Button) findViewById(R.id.bt_sports);
		mBtInternational = (Button) findViewById(R.id.bt_International);
		mBtNews.setOnClickListener(this);
		mBtEntertainment.setOnClickListener(this);
		mBtSports.setOnClickListener(this);
		mBtInternational.setOnClickListener(this);
		setDefaultContent();
	}

	private void setDefaultContent() {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction beginTransaction = fm.beginTransaction();
		frNews = new MyFragmentNews();
		beginTransaction.replace(R.id.fm_content, frNews);
		beginTransaction.commit();
	}

	public void onClick(View view) {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction beginTransaction = fm.beginTransaction();
		switch (view.getId()) {
		case R.id.bt_news:
			if (frNews == null) {
				frNews = new MyFragmentNews();
			}
			beginTransaction.replace(R.id.fm_content, frNews);
			beginTransaction.commit();
			break;
		case R.id.bt_entertainment:
			if (myFragmentEntertainment == null) {
				myFragmentEntertainment = new MyFragmentEntertainment();
			}

			beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);
			beginTransaction.commit();
			break;
		case R.id.bt_sports:
			if (myFragmentSports == null) {
				myFragmentSports = new MyFragmentSports();
			}
			beginTransaction.replace(R.id.fm_content, myFragmentSports);
			beginTransaction.commit();
			break;
		case R.id.bt_International:
			if (myFragmentInternational == null) {
				myFragmentInternational = new MyFragmentInternational();
			}
			beginTransaction.replace(R.id.fm_content, myFragmentInternational);
			beginTransaction.commit();
			break;
		default:
			break;
		}
	}

}
</span>

动态使用Fragment的Demo:http://download.csdn.net/detail/two_water/9279255


五.Fragment和Activity之间的通信

效果图和上面的都是一样的!只是考虑Fragment的重复使用,所以必须降低FragmentActivity的耦合!虽然FragmentActivity可以通过getActivityfindFragmentByTag或者findFragmentById,进行任何操作,甚至在Fragment里面操作另外的Fragment,但是没有特殊理由是不提倡的。Activity担任的是Fragment间类似总线一样的角色,应当由它决定Fragment如何操作。

 
 

因为效果图和上面的动态使用Fragment的效果图差不多!所以不上图了!

贴几个关键的代码:

package com.liangdianshui.fragment2;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MyFragmentSports extends Fragment implements OnClickListener {

	private Button bt_enter_news;

	public interface enterNewsListener {
		void enterNewsOnClick();
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater
				.inflate(R.layout.fragment_sports, container, false);
		bt_enter_news = (Button) view.findViewById(R.id.bt_enter_news);
		bt_enter_news.setOnClickListener(this);
		return view;
	}

	@Override
	public void onClick(View view) {
		if (getActivity() instanceof enterNewsListener) {
			((enterNewsListener) getActivity()).enterNewsOnClick();
		}
	}
}


package com.liangdianshui.fragment2;

import com.liangdianshui.fragment2.MyFragmentSports.enterNewsListener;
import com.liangdianshui.fragment2.MyFragmentTitle.titleBtListener;

import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity implements titleBtListener,
		enterNewsListener {

	private FrameLayout mContent;
	private MyFragmentNews frNews;
	private MyFragmentEntertainment myFragmentEntertainment;
	private MyFragmentInternational myFragmentInternational;
	private MyFragmentSports myFragmentSports;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		setDefaultContent();
	}

	private void setDefaultContent() {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction beginTransaction = fm.beginTransaction();
		frNews = new MyFragmentNews();
		beginTransaction.replace(R.id.fm_content, frNews);
		beginTransaction.commit();
	}

	@Override
	public void titleOnClick(View view) {
		FragmentManager fm = getFragmentManager();
		FragmentTransaction beginTransaction = fm.beginTransaction();
		switch (view.getId()) {
		case R.id.bt_news:
			if (frNews == null) {
				frNews = new MyFragmentNews();
			}
			beginTransaction.replace(R.id.fm_content, frNews);
			beginTransaction.commit();
			break;
		case R.id.bt_entertainment:
			if (myFragmentEntertainment == null) {
				myFragmentEntertainment = new MyFragmentEntertainment();
			}

			beginTransaction.replace(R.id.fm_content, myFragmentEntertainment);
			beginTransaction.commit();
			break;
		case R.id.bt_sports:
			if (myFragmentSports == null) {
				myFragmentSports = new MyFragmentSports();
			}
			beginTransaction.replace(R.id.fm_content, myFragmentSports);
			beginTransaction.commit();
			break;
		case R.id.bt_International:
			if (myFragmentInternational == null) {
				myFragmentInternational = new MyFragmentInternational();
			}
			beginTransaction.replace(R.id.fm_content, myFragmentInternational);
			beginTransaction.commit();
			break;
		default:
			break;
		}
	}

	@Override
	public void enterNewsOnClick() {
		if (frNews == null) {
			frNews = new MyFragmentNews();
		}
		FragmentManager fm = getFragmentManager();
		FragmentTransaction beginTransaction = fm.beginTransaction();
		beginTransaction.replace(R.id.fm_content, frNews);
		beginTransaction.commit();
	}
}


package com.liangdianshui.fragment2;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MyFragmentTitle extends Fragment implements OnClickListener {

	private Button mBtNews;
	private Button mBtEntertainment;
	private Button mBtSports;
	private Button mBtInternational;

	public interface titleBtListener {
		void titleOnClick(View view);
	}

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

	private void init(View view) {
		mBtNews = (Button) view.findViewById(R.id.bt_news);
		mBtEntertainment = (Button) view.findViewById(R.id.bt_entertainment);
		mBtSports = (Button) view.findViewById(R.id.bt_sports);
		mBtInternational = (Button) view.findViewById(R.id.bt_International);
		mBtNews.setOnClickListener(this);
		mBtEntertainment.setOnClickListener(this);
		mBtSports.setOnClickListener(this);
		mBtInternational.setOnClickListener(this);
	}

	@Override
	public void onClick(View view) {
		if (getActivity() instanceof titleBtListener) {
			((titleBtListener) getActivity()).titleOnClick(view);
		}
	}

}


其中点击事件中的if(getActivity() instanceof titleBtListener)判断当前的activity是否实现了该接口~

Fragment和Activity通信Demo: http://download.csdn.net/detail/two_water/9279261


你可能感兴趣的:(Android_Fragment)