天天看点

安卓基础学习_Activity与Fragment

一、建立、配置和使用Activity
/*********************配置Activity********************/
<activity 
    android:name=".mainActivity"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:exported="true"
    android:launchMode="standard">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
	<meta-data 
		android:name="com.zouyong.name" 
		android:value="zouyong"/>
</activity>
<meta-data>节点的使用
该节点可以包含在<activity><activity-alias><service><receiver>四个元素中,用于为组件提供额外的参数数据。
<activity android:name=".MainActivity">
	. . . . . .
	<meta-data android:name="com.zouyong.name" android:value="zouyong"/>
	<meta-data android:name="com.zouyong.age" android:value="5"/>
	<meta-data android:name="com.zouyong.app" android:value="@string/hello"/>
	<meta-data android:name="com.zouyong.id" android:resource="@string/hello"/>
</activity>
Activity中获取参数:
try
{
	ActivityInfo activityInfo = this.getPackageManager().getActivityInfo(new ComponentName(this, MainActivity.class), PackageManager.GET_META_DATA);
	Bundle bundle = activityInfo.metaData;
	String name = bundle.getString("com.zouyong.name");
	String app = bundle.getString("com.zouyong.app");
	int age = bundle.getInt("com.zouyong.age");
	int sourceid = bundle.getInt("com.zouyong.id");
	Toast.makeText(this, "name="+ name+ ",age="+ age+ ",app="+ app+ ",sourceid="+ sourceid, 1).show();
} 
catch (NameNotFoundException e) 
{
	e.printStackTrace();
}

/*********************使用Activity********************/
// LauncherActivity
public class MainActivity extends LauncherActivity
{
	//定义两个Activity的名称
	String[] names = {"设置程序参数" ,  "查看星际兵种"};
	//定义两个Activity对应的实现类
	Class<?>[] clazzs = {PreferenceActivityTest.class
		, ExpandableListActivityTest.class};
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
			android.R.layout.simple_list_item_1 , names);
		// 设置该窗口显示的列表所需的Adapter
		setListAdapter(adapter);
	}
	//根据列表项来返回指定Activity对应的Intent
	@Override 
	public Intent intentForPosition(int position)
	{
		return new Intent(MainActivity.this , clazzs[position]);
	}
}
//ExpandableListActivity可展开的Activity
public class ExpandableListActivityTest extends ExpandableListActivity
{
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		ExpandableListAdapter adapter = new BaseExpandableListAdapter()
		{
			int[] logos = new int[]
			{
				R.drawable.p,
				R.drawable.z,
				R.drawable.t
			};
			private String[] armTypes = new String[]
				{ "神族兵种", "虫族兵种", "人族兵种"};
			private String[][] arms = new String[][]
			{
				{ "狂战士", "龙骑士", "黑暗圣堂", "电兵" },
				{ "小狗", "刺蛇", "飞龙", "自爆飞机" },
				{ "机枪兵", "护士MM" , "幽灵" }
			};
			//获取指定组位置、指定子列表项处的子列表项数据
			@Override
			public Object getChild(int groupPosition, int childPosition)
			{
				return arms[groupPosition][childPosition];
			}
			@Override
			public long getChildId(int groupPosition, int childPosition)
			{
				return childPosition;
			}
			@Override
			public int getChildrenCount(int groupPosition)
			{
				return arms[groupPosition].length;
			}
			private TextView getTextView()
			{
				AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
						ViewGroup.LayoutParams.MATCH_PARENT, 64);
				TextView textView = new TextView(ExpandableListActivityTest.this);
				textView.setLayoutParams(lp);
				textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
				textView.setPadding(36, 0, 0, 0);
				textView.setTextSize(20);
				return textView;
			}
			//该方法决定每个子选项的外观
			@Override
			public View getChildView(int groupPosition, int childPosition,
					boolean isLastChild, View convertView, ViewGroup parent)
			{
				TextView textView = getTextView();
				textView.setText(getChild(groupPosition, childPosition).toString());
				return textView;
			}
			//获取指定组位置处的组数据
			@Override
			public Object getGroup(int groupPosition)
			{
				return armTypes[groupPosition];
			}
			@Override
			public int getGroupCount()
			{
				return armTypes.length;
			}
			@Override
			public long getGroupId(int groupPosition)
			{
				return groupPosition;
			}
			//该方法决定每个组选项的外观
			@Override
			public View getGroupView(int groupPosition, boolean isExpanded,
					View convertView, ViewGroup parent)
			{
				LinearLayout ll = new 
LinearLayout(ExpandableListActivityTest.this);
				ll.setOrientation(0);
				ImageView logo = new ImageView(ExpandableListActivityTest.this);
				logo.setImageResource(logos[groupPosition]);
				ll.addView(logo);
				TextView textView = getTextView();
				textView.setText(getGroup(groupPosition).toString());
				ll.addView(textView);
				return ll;
			}
			@Override
			public boolean isChildSelectable(int groupPosition, int childPosition)
			{
				return true;
			}
			@Override
			public boolean hasStableIds()
			{
				return true;
			}
		};
		// 设置该窗口显示列表
		setListAdapter(adapter);
	}
}
//PreferenceActivityTest
public class PreferenceActivityTest extends PreferenceActivity
{
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 该方法用于为该界面设置一个标题按钮
		if (hasHeaders())
		{
			Button button = new Button(this);
			button.setText("设置操作");
			// 将该按钮添加到该界面上
			setListFooter(button);
		}
	}
	// 重写该该方法,负责加载页面布局文件
	@Override
	public void onBuildHeaders(List<Header> target)
	{
		// 加载选项设置列表的布局文件
		loadHeadersFromResource(R.xml.preference_headers, target);
	}
	public static class Prefs1Fragment extends PreferenceFragment
	{
		@Override
		public void onCreate(Bundle savedInstanceState)
		{
			super.onCreate(savedInstanceState);
			addPreferencesFromResource(R.xml.preferences);
		}
	}
	public static class Prefs2Fragment extends PreferenceFragment
	{
		@Override
		public void onCreate(Bundle savedInstanceState)
		{
			super.onCreate(savedInstanceState);
			addPreferencesFromResource(R.xml.display_prefs);
			// 获取传入该Fragment的参数
			String website = getArguments().getString("website");
			Toast.makeText(getActivity()
				, "网站域名是:" + website , Toast.LENGTH_LONG).show();
		}
	}	
}
-------------------preference_headers.xml---------------
<preference-headers 
    xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 指定启动指定PreferenceFragment的列表项 -->
	<header android:fragment=
	    "org.crazyit.app.PreferenceActivityTest$Prefs1Fragment"
		android:icon="@drawable/ic_settings_applications"
		android:title="程序选项设置"
		android:summary="设置应用的相关选项" />
<!-- 指定启动指定PreferenceFragment的列表项 -->	
	<header android:fragment=
		"org.crazyit.app.PreferenceActivityTest$Prefs2Fragment"
		android:icon="@drawable/ic_settings_display"
		android:title="界面选项设置 "
		android:summary="设置显示界面的相关选项">
		<!-- 使用extra可向Activity传入额外的数据 -->
		<extra android:name="website"
			android:value="www.crazyit.org" />
	</header>
	<!-- 使用Intent启动指定Activity的列表项 -->
	<header
		android:icon="@drawable/ic_settings_display"
		android:title="使用Intent"
		android:summary="使用Intent启动某个Activity">
		<intent	android:action="android.intent.action.VIEW"
			android:data="http://www.crazyit.org" />
	</header>
</preference-headers>
--------------------display_prefs.xml--------------------
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android">
	<PreferenceCategory android:title="背景灯光组">
		<!-- 通过列表框选择灯光强度 -->
		<ListPreference
			android:key="light"
			android:title="灯光强度"
			android:summary="请选择灯光强度(测试ListPreference)"
			android:dialogTitle="请选择灯光强度"
			android:entries="@array/light_strength_list"
			android:entryValues="@array/light_value_list" />
	</PreferenceCategory>
	<PreferenceCategory android:title="文字显示组 ">
		<!-- 通过SwitchPreference设置是否自动滚屏 -->
		<SwitchPreference
			android:key="autoScroll"
			android:title="自动滚屏"
			android:summaryOn="自动滚屏: 开启"
			android:summaryOff="自动滚屏: 关闭"
			android:defaultValue="true" />
	</PreferenceCategory>
</PreferenceScreen>
--------------------preferences.xml--------------------
<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android">
	<!-- 设置系统铃声 -->
	<RingtonePreference
		android:ringtoneType="all"
		android:title="设置铃声"
		android:summary="选择铃声(测试RingtonePreference)"
		android:showDefault="true"
		android:key="ring_key"
		android:showSilent="true">
	</RingtonePreference>
	<PreferenceCategory android:title="个人信息设置组">
		<!-- 通过输入框填写用户名 -->
		<EditTextPreference
			android:key="name"
			android:title="填写用户名"
			android:summary="填写您的用户名(测试EditTextPreference)"
			android:dialogTitle="您所使用的用户名为:" />
		<!-- 通过列表框选择性别 -->
		<ListPreference
			android:key="gender"
			android:title="性别"
			android:summary="选择您的性别(测试ListPreference)"
			android:dialogTitle="ListPreference"
			android:entries="@array/gender_name_list"
			android:entryValues="@array/gender_value_list" />
	</PreferenceCategory>
	<PreferenceCategory android:title="系统功能设置组 ">
		<CheckBoxPreference
			android:key="autoSave"
			android:title="自动保存进度"
			android:summaryOn="自动保存: 开启"
			android:summaryOff="自动保存: 关闭"
			android:defaultValue="true" />
	</PreferenceCategory>	
</PreferenceScreen>

/*********************Activity参数传递****************/
方法1:
intent.putExtra("name", "zhangsan");
startActivity(intent);
-----
String name=intent.getStringExtra("name");
方法2:
Bundle bundle=new Bundle();
bundle.putString("name", "zhangsan");
bundle.putInt("age", 22);
intent.putExtras(bundle);
startActivity(intent);
-----
Intent intent=getIntent();
Bundle bundle=intent.getExtras();
String name=bundle.getString("name");
int age=bundle.getInt("age");
方法3:
Bundle data = new Bundle();
data.putSerializable("person", p);
//Person p=new Person(..);
/*Person类实现了Serializable接口
public class Person implements Serializable
{
	private static final long serialVersionUID = 1L;
	...
}
*/
Intent intent = new Intent(BundleTest.this,ResultActivity.class);
intent.putExtras(data);
startActivity(intent);
-----
// 获取启动该Result的Intent
Intent intent = getIntent();
// 直接通过Intent取出它所携带的Bundle数据包中的数据
Person p = (Person) intent.getSerializableExtra("person");
在Activity关闭时返回数据给main Activity:
启动Activity方式:startActivityForResult(intent, 100);
关闭Activity时调用方法:
public void closeActivity(View view)//定义的按钮点击事件
{
	Intent intent=new Intent();
	intent.putExtra("result", "Li Si");
	setResult(20,intent);
	finish();
}
接收结果数据:
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
	String result=data.getStringExtra("result");
	super.onActivityResult(requestCode, resultCode, data);
}

/*********************启动Activity********************/
显式Intent方式:
第1种:
Intent intent=new Intent(this,otheractivity.class);
startActivity(intent);
第2种:
Intent intent=new Intent();
intent.setClass(this, otheractivity.class);
startActivity(intent);
第3种:
Intent intent=new Intent();
intent.setClassName(this, "com.zouyong.zouyong.otheractivity");
startActivity(intent);
第4种:
Intent intent=new Intent();
intent.setComponent(new ComponentName(this, otheractivity.class));
startActivity(intent);
隐式Intent方式:
 (没设数据参数的情况下)只要Intent中的Action和Category都出现在Intent-Filter中,就能与之匹配,否则匹配失败
Intent intent = new Intent();//隐式意图激活Activity
intent.setAction("com.zouyong.intentaction0");
intent.addCategory("com.zouyong.category.java");
intent.setDataAndType(Uri.parse("zouyong://www.zouyong.cn/hello"), "image/jpeg");
startActivity(intent);//方法内部为Intent添加了android.intent.category.DEFAULT类别

/*********************关闭Activity********************/
1>.finish():结束当前Activity.
2>.finishActivity(int requestCode):
结束以startActivityForResult(Intent intent,int requestCode)方法启动的Activity.
/*******************关闭应用的几种方法******************/
第一种:首先获取当前进程的id,然后杀死该进程(建议使用)
	android.process.killProcess(android.os.Process.myPid());
第二种:终止当前正在运行的java虚拟机,导致程序终止
	System.exit(0);
第三种:强制关闭与该包有关联的一切执行
	ActivityManager manager=(ActivityManager)getSystemService
(Context.ACTIVITY_SERVICE);
	manager.restartPackage(getPackageName());
<uses-permission android:name="android.permission.RESTART_PACKAGES" />

二、Activity的生命周期与加载模式
Activity有3个状态:运行状态、暂停状态、停止状态
运行(激活)状态:处于栈顶(屏幕前台时,可以响应用户操作);
暂停状态:当Activity上面有另一个Activity,上面的activity没有完全覆盖它,或者上面的activity是透明的,下方的activity仍然对用户可见(对话框);是存活状态,如果内存不足时,会杀死这个activity;
停止状态:当activity完全被令一个activity覆盖时,处于停止状态。它仍然保留所有的状态和成员信息,然而对用户是不可见的,所以它的窗口将被隐藏,如果其他地方需要内存,系统经常会杀死这个activity。

当Activity从一种状态转变到另一种状态时,会调用以下保护方法来通知这种变化:
void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()

1.启动Activity:系统会先调用onCreate方法(适合做初始化操作),然后调用onStart方法,最后调用onResume,Activity进入运行状态。
2.当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
3.当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
4.当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
5.用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
6.当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
7.用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。

Activity的完整生命周期:自第一次调用onCreate()开始,直至调用onDestrory()为止。Activity在onCreate()设置所有“全局”状态以完成初始化,而在onDestrory()中释放所有的系统资源。
Activity的可视生命周期:自onStart()调用开始直到响应的onStop()调用结束。在此期间,用户可以在屏幕上看到activity,尽管它也许并不是位于前台或者也不与用户进行交互。在这两个方法之间,我们可以保留用来向用户显示这个activity所需要的资源。
Activity的前台生命周期:自onResume()调用起,至相应的onPause()调用为止,在此期间,Activity位于前台最上面并于用户进行交互。Activity会经常在暂停和恢复之间进行状态转换。      
安卓基础学习_Activity与Fragment
    onSaveInstanceState()和onRestoreInstanceState并不是生命周期方法,它们不同于onCreate(),onPause()等生命周期方法,它们并不一定被触发。当遇到意外情况(内存不足,用户直接按Home键)由系统销毁一个Activity时,onSaveInstanceState()会被调用,另外Activity由于运行状态进入暂停状态或停止状态也会调用该方法。但是当用户主动去销毁一个Activity时,例如在应用中按返回键,onSaveInstanceState()就不会被调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用户数据的持久化保存。
    另外,当屏幕方向发生了改变,Activity会被摧毁并且被重新创建,如果你想在Activity被摧毁前缓存一些数据,并且在Activity被重新创建后恢复缓存的数据,可以重写Activity的onSaveInstanceState()和onRestoreInstanceStance()方法。
//被摧毁前缓存一些数据
protected void onSaveInstanceState(Bundle outState)
{
	outState.putString("name", "zhangsan");
	super.onSaveInstanceState(outState);
}
//被重新创建后恢复缓存的数据
protected void onRestoreInstanceState(Bundle savedInstanceState) 
{
	String name=savedInstanceState.getString("name");
	super.onRestoreInstanceState(savedInstanceState);
}

默认情况下,当屏幕方向或键盘显示隐藏变化时都会销毁当前Activity,创建新的Activity,如果不希望重新创建Activity实例,可以按如下配置Activity:
android:configChanges="keyboardHidden|orientation"

Activity的四种启动模式(LaunchMode):
1. Standard:默认模式,标准模式。每次激活Activity都会创建Activity实例,并放入任务栈中。
2. SingleTop:如果在任务的栈顶正好存在该Activity的实例,就重用该实例(会调用onNewIntent()),否则就会创建新的实例并放入栈顶(注:即使栈中已经存在该Activity实例,只有不在栈顶,都会创建实例)。
3. SingleTask:如果在栈中已经有该Activity的实例,就重用该实例(会调用onNewIntent()),重用时,会让该实例回到栈顶,因此在它上面的实例将被移出栈。如果栈中不存在该实例,将会创建新的实例放入栈中。
4. SingleInstance:在一个新栈中创建该Activity的实例,并让多个应用共享该栈中的该Activity实例。一旦该模式的Activity的实例已经存在与某个栈中,任何应用再激活该Activity时都会重用该栈中的实例(会调用实例的onNewIntent())。其效果相同于多个应用共享一个应用,不管谁激活该Activity都会进入同一个应中。

三、Fragment详解
系统内置了三种Fragments ,这三种Fragments 分别有不同的应用场景分别为:
1.DialogFragment:对话框式的Fragments,可以将一个fragments 对话框并到activity 管理的fragments back stack 中,允许用户回到一个前曾摒弃fragments. 
2.ListFragments:类似于ListActivity 的效果,并且还提供了ListActivity 类似的onListItemCLick和setListAdapter等功能.
3.PreferenceFragments:类似于PreferenceActivity .

将Fragment添加到Activity中的两种方式
1.在布局文件中使用<fragment.../>元素添加,<fragment../>元素的android:name属性指定Fragment的实现类;
2.在java代码中通过FragmentTransaction对象的add()方法来添加Fragment.Activity的getFragmentManager()方法可返回FragmentManager,FragmentManager对象的beginTransaction()方法即可开启并返回FragmentTransaction对象.

Fragment获取它所在Activity:调用Fragment的getActivity()方法即可返回.
Activity获取它所包含的Fragment:调用Activity关联的FragmentManger的findFragmentById(int id)或findFragmentByTag(String tag)方法即可获取.

Fragment与Activity通信
Activity向Fragment传递数据:在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法即可将Bundle数据包传给Fragment.
Fragment向Activity传递数据或Activity需要在Fragment运行中实时通信:在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,这样Fragment即可调用该回调方法将数据传给Activity.

Fragment的管理与Fragment事务(Activity管理Fragment主要依靠FragmentManager)
FragmentManager可以完成如下几方面功能
1.使用findFragmentById(int id)或findFragmentByTag(String tag)方法获取指定Fragment;
2.调用popBackStack()方法将Fragment从后台栈中弹出;
3.调用addOnBackStackChangeListener()注册一个监听器,用于监听后台栈的变化.

public class BookListActivity extends Activity implements
		BookListFragment.Callbacks
{
	// 定义一个旗标,用于标识该应用是否支持大屏幕
	private boolean mTwoPane;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 指定加载R.layout.activity_book_list对应的界面布局文件
		// 但实际上该应用会根据屏幕分辨率家在不同的界面布局文件
/*屏幕适配-->创建values-sw600dp、values-large文件夹,创建refs.xml文件如下
<resources>
	<item type="layout" name="activity_book_list">
		@layout/activity_book_twopane
	</item>
</resources>
*/
		setContentView(R.layout.activity_book_list);
		// 如果加载的界面布局文件中包含ID为book_detail_container的组件
		if (findViewById(R.id.book_detail_container) != null)
		{
			mTwoPane = true;
			((BookListFragment) getFragmentManager()
				.findFragmentById(R.id.book_list))
				.setActivateOnItemClick(true);
		}
	}
	@Override
	public void onItemSelected(Integer id)
	{
		if (mTwoPane)
		{
			// 创建Bundle,准备向Fragment传入参数
			Bundle arguments = new Bundle();
			arguments.putInt(BookDetailFragment.ITEM_ID, id);
			// 创建BookDetailFragment对象
			BookDetailFragment fragment = new BookDetailFragment();
			// 向Fragment传入参数
			fragment.setArguments(arguments);
			// 使用fragment替换book_detail_container容器当前显示的Fragment
			getFragmentManager().beginTransaction()
					.replace(R.id.book_detail_container, fragment).commit();
		}
		else
		{
			// 创建启动BookDetailActivity的Intent
			Intent detailIntent = new Intent(this, BookDetailActivity.class);
			// 设置传给BookDetailActivity的参数
			detailIntent.putExtra(BookDetailFragment.ITEM_ID, id);
			// 启动Activity
			startActivity(detailIntent);
		}
	}
}

activity_book_list.xml
<!-- 直接使用BookListFragment作为界面组件 -->
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
	android:name="org.crazyit.app.BookListFragment"
	android:id="@+id/book_list"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:layout_marginLeft="16dp"
	android:layout_marginRight="16dp"/>

activity_book_twopane.xml
<!-- 定义一个水平排列的LinearLayout,并指定使用中等分隔条 -->
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="horizontal"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:layout_marginLeft="16dp"
	android:layout_marginRight="16dp"
	android:divider="?android:attr/dividerHorizontal"
	android:showDividers="middle">
	<!-- 添加一个Fragment -->
	<fragment
		android:name="org.crazyit.app.BookListFragment"
		android:id="@+id/book_list"
		android:layout_width="0dp"
		android:layout_height="match_parent"
		android:layout_weight="1" />
	<!-- 添加一个FrameLayout容器 -->
	<FrameLayout
		android:id="@+id/book_detail_container"
		android:layout_width="0dp"
		android:layout_height="match_parent"
		android:layout_weight="3" />
</LinearLayout>

public class BookListFragment extends ListFragment
{
	private Callbacks mCallbacks;
	public interface Callbacks
	{
		public void onItemSelected(Integer id);
	}
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 为该ListFragment设置Adapter
		setListAdapter(new ArrayAdapter<BookContent.Book>(getActivity(),
				android.R.layout.simple_list_item_activated_1,
				android.R.id.text1, BookContent.ITEMS));  //①
	}
	// 当该Fragment被添加、显示到Activity时,回调该方法
	@Override
	public void onAttach(Activity activity)
	{
		super.onAttach(activity);
		// 如果Activity没有实现Callbacks接口,抛出异常
		if (!(activity instanceof Callbacks))
		{
			throw new IllegalStateException(
				"BookListFragment所在的Activity必须实现Callbacks接口!");
		}
		// 把该Activity当成Callbacks对象
		mCallbacks = (Callbacks) activity;
	}
	// 当该Fragment从它所属的Activity中被删除时回调该方法
	@Override
	public void onDetach()
	{
		super.onDetach();
		// 将mCallbacks赋为null。
		mCallbacks = null;
	}
	// 当用户点击某列表项时回调该方法
	@Override
	public void onListItemClick(ListView listView
		, View view, int position, long id)
	{
		super.onListItemClick(listView, view, position, id);
		mCallbacks.onItemSelected(BookContent.ITEMS.get(position).id);
	}
	public void setActivateOnItemClick(boolean activateOnItemClick)
	{
		getListView().setChoiceMode(
				activateOnItemClick ? ListView.CHOICE_MODE_SINGLE
						: ListView.CHOICE_MODE_NONE);
	}
}

public class BookDetailActivity extends Activity
{
	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 指定加载/res/layout目录下的activity_book_detail.xml布局文件
		// 该界面布局文件内只定义了一个名为book_detail_container的FrameLayout
		setContentView(R.layout.activity_book_detail);
		// 将ActionBar上应用图标转换成可点击的按钮
		getActionBar().setDisplayHomeAsUpEnabled(true);
		if (savedInstanceState == null)
		{
			// 创建BookDetailFragment对象
			BookDetailFragment fragment = new BookDetailFragment();
			// 创建Bundle对象,
			Bundle arguments = new Bundle();
			arguments.putInt(BookDetailFragment.ITEM_ID, getIntent()
				.getIntExtra(BookDetailFragment.ITEM_ID, 0));
			// 向Fragment传入参数
			fragment.setArguments(arguments);
			// 将指定fragment添加到book_detail_container容器中
			getFragmentManager().beginTransaction()
					.add(R.id.book_detail_container, fragment).commit();
		}
	}
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		if (item.getItemId() == android.R.id.home)
		{
			// 创建启动BookListActivity的Intent
			Intent intent = new Intent(this, BookListActivity.class);
			// 添加额外的Flag,将Activity栈中处于FirstActivity之上的Activity弹出
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			// 启动intent对应的Activity
			startActivity(intent);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

public class BookDetailFragment extends Fragment
{
	public static final String ITEM_ID = "item_id";
	// 保存该Fragment显示的Book对象
	BookContent.Book book;
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 如果启动该Fragment时包含了ITEM_ID参数
		if (getArguments().containsKey(ITEM_ID))
		{
			book = BookContent.ITEM_MAP.get(getArguments()
				.getInt(ITEM_ID));
		}
	}
	// 重写该方法,该方法返回的View将作为Fragment显示的组件
	@Override
	public View onCreateView(LayoutInflater inflater
		, ViewGroup container, Bundle savedInstanceState)
	{
		// 加载/res/layout/目录下的fragment_book_detail.xml布局文件
		View rootView = inflater.inflate(R.layout.fragment_book_detail,
				container, false);
		if (book != null)
		{
			// 让book_title文本框显示book对象的title属性
			((TextView) rootView.findViewById(R.id.book_title))
					.setText(book.title);
			// 让book_desc文本框显示book对象的desc属性
			((TextView) rootView.findViewById(R.id.book_desc))
				.setText(book.desc);		
		}
		return rootView;
	}
}

model层
public class BookContent
{
	public static class Book
	{


		public Integer id;
		public String title;
		public String desc;
		
		public Book(Integer id, String title, String desc)
		{
			this.id = id;
			this.title = title;
			this.desc = desc;
		}


		@Override
		public String toString()
		{
			return title;
		}
	}


	public static List<Book> ITEMS = new ArrayList<Book>();
	public static Map<Integer, Book> ITEM_MAP 
		= new HashMap<Integer, Book>();


	static
	{
		addItem(new Book(1, "疯狂Java讲义"
			, "一本全面、深入的Java学习图书,已被多家高校选做教材。"));
		addItem(new Book(2, "疯狂Android讲义"
			, "Android学习者的首选图书,常年占据京东、当当、亚马逊3大网站Android销量排行榜的榜首"));
		addItem(new Book(3, "轻量级Java EE企业应用实战"
			, "全面介绍Java EE开发的Struts 2、Spring 3、Hibernate 4框架"));
	}
	
	private static void addItem(Book book)
	{
		ITEMS.add(book);
		ITEM_MAP.put(book.id, book);
	}
}

四、Fragment的生命周期
Fragment存在状态:
1.活动状态:位于前台,用户可见,可以获得焦点
2.暂停状态:位于前台,依然可见。不能获得焦点
3.停止状态:不可见,失去焦点

--------------添加Fragment----------------------
1.当fragment被创建的时候,它会经历以下状态.
onAttach():当该Fragment被添加到Activity时被回调,只会被调用一次;
onCreate():创建Fragment时被回调,只会被调用一次;当fragment和activity关联之后,调用这个方法.
onCreateView():每次创建、绘制该Fragment的View组件时回调该方法,Fragment将会显示该方法返回的View组件;
onActivityCreated():当Fragment所在Activity被启动完成后回调该方法;当activity的onCreate()方法被返回之后,调用这个方法.
2.当这个fragment对用户可见的时候,它会经历以下状态。
onStart():启动Fragment时被回调;
onResume():恢复Fragment时被回调,onStart()方法后一定回调onResume();
--------------运行状态---------------------
3.进入"后台模式"/fragment被销毁了/持有它的activity被销毁了会经历以下状态.
onPause():暂停Fragment时被回调;
--------------暂停状态----------------------
onStop():停止Fragment时被回调;
--------------停止状态----------------------
onDestroyView():销毁Fragment所包含的View组件时被回调;当fragment中的视图被移除的时候,调用这个方法.
onDestroy():销毁Fragment时被回调,只会调用一次;
onDetach():将Fragment从Activity中删除,被替换完成时回调该方法,onDestroy()方法后一定会回调该方法,只会被调用一次;当fragment和activity分离的时候调用.
--------------销毁状态----------------------
在以下的状态中,可以使用Bundle对象保存一个fragment的对象.
onCreate()    //保存的数据恢复
onCreateView() //初始化UI
onActivityCreated()   //具体操作      
安卓基础学习_Activity与Fragment