Android 开发 之 Fragment 详解

作者 : 韩曙亮

转载请著名出处 : http://blog.csdn.net/shulianghan/article/details/38064191



1. Fragement 概述


Fragement 与 Activity 生命周期关系 : Fragement 嵌入到 Activity 组件中才可以使用, 其生命周期与 Activity 生命周期相关.

-- stop 与 destroy 状态 : Activity 暂停 或者 销毁的时候, 其内部嵌入的所有的 Fragement 也会执行 暂停 或者 销毁 操作;

-- 活动状态 : 只有当 Activity 处于活动状态的时候, 我们才能操作 Fragement;


Fragement 特征 : 

-- Fragement 与 Activity 交互 : Fragement 调用 getActivity() 获取其 所嵌入的 Activity, Activity 获取 FragementManager 的findFragementById() 或 findFragementByTag() 获取 Fragement;

-- Activity 增删 Fragement : Activity 调用 Fragement 的 add()remove()replace() 等方法 添加 删除 替换 Fragement;

-- Fragement 与 Activity 对应关系 : 一个 Activity 中可以嵌入多个 Fragement, 一个 Fragement 可以嵌入多个 Activity;

-- 生命周期受 Activity 影响 : Fragement 的生命周期 受 Activity 生命周期控制;


Fragement 作用 :  Fragement 是为了 Android 中 平台电脑 UI 设计, 开发者不用设计 非常负责的 界面, 只需要设计好模块, 对UI 组件进行分组 和 模块化的设计和开发, 简化了 UI 组件;


Fragement 可复用性 : 同一个 app 应用, 可以在不同的 Activity 中加载同一个 Fragement;



2. Fragement 类 和 方法介绍


(1) Fragement 相关类介绍


Fragement 子类 : 

-- DialogFragement : 对话框界面的 Fragement, 显示一个浮动的对话框, 这个对话框可以方便的与 Activity 进行交互, Activity 可以管理这个 Fragment;

-- ListFragement : 列表界面的 Fragement, 显示一个条目列表, 该列表可以设置一个适配器, 提供了许多管理 列表的函数;

-- PerformanceFragement : 选项设置界面的 Fragement, 该Fragment 创建 类似与 设置 应用程序时很管用;

-- WebViewFragement : WebView 界面的 Fragement;



(2) Fragement 生命周期相关方法介绍 


onCreate() :

[java]  view plain copy
  1. onCreate(Bundle savedInstanceState)  

-- 回调时机 : 在创建 Fragement 的时候回调;

-- 参数解析 : Bundle savedInstance, 用于保存 Fragment 参数, Fragement 也可以 重写 onSaveInstanceState(Bundle outState) 方法, 保存Fragement状态;

-- 执行的动作 : 获取 Frgement 显示的内容, 以及启动Fragment 传入的参数, 调用 getArguments() 获取键值对;


onCreateView() : 

[java]  view plain copy
  1. onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState);  

-- 回调时机 : Fragement 绘制界面组件 的时候回调, 该方法返回 View, 这个View就是 Fragement 本身;

-- 参数解析 : inflater 布局加载器, 是上下文传入, 不用自己创建; container 加载组件的父容器;

-- 执行的操作 : 使用 inflate 布局加载器 加载布局文件, 并未组件设置显示的值;


onPause() : 

-- 回调时机 : Fragement 暂停的时候, 即进入后台的时候 回调;



3. Fragment 创建


Fragment 创建 : 

-- 参数准备 : 创建一个 Bundle 对象, 并向其中设置参数 : 

[java]  view plain copy
  1. Bundle bundle = new Bundle();   
  2. bundle.putString("key""value");  
-- 创建 Fragment 对象 : 使用 new MyFragment() 创建对象, 并 调用 myFragment.setArguments(bundle)  方法传入参数;

[java]  view plain copy
  1. MyFragment myFragment = new MyFragment();  
  2. myFragment.setArguments(bundle);  


Fragment嵌入Activity方式 : Fragment 添加到 Activity 中才能显示, 以下是将 Fragment 嵌入 Activity 的方式;

-- 布局文件嵌入 : 在布局文件中 使用 元素, 通过定义 android:name = "com.example.MyFragment" 属性指定 Fragment 类;

-- 代码方式嵌入 : 调用 FragmentTransaction 对象的 add() 方法向 Activity 中添加 Fragment;



4. Fragment 与 Activity 通信


Fragment 获取 Activity : 调用 Fragment 对象的 getActivity()方法, 即可获取 Fragment 嵌入的 Activity 对象;


Activity 获取 Fragment : 

-- Fragment 属性 : 在布局文件中, 可以为 元素指定 android:id 和 android:tag 属性;

-- 获取方法 : 调用 Activity 的 findFragmentById(int id) 或者 findFragmentByTag(String tag)方法;


Fragment 向 Activity 传递数据 : 将 Activity 当作接口子类对象, Fragment 中调用 Activity 中的接口方法;

-- Fragment 定义接口 : 在 Fragment 内部定义一个 Callback 接口;

-- Activity 实现该接口 : MyActivity extends Activity implement MyFragment.Callback;

-- Fragment 中获取该接口对象 : 在Fragment 中定义一个 Callback 全局变量, 然后在 onAttach(Activity activity) 方法中, 将activity 强转为 Callback 对象

-- 调用接口方法 : 上面获取了 Callback 对象, 即Activity对象, 调用 Activity 中的 接口方法, 就能在 Fragment 中调用 Activity 对应的方法了;


Activity 向 Fragment 传递数据 : 

-- 创建 Bundle 数据包 : 创建一个 Bundle 对象, 把要存放的键值对 放到这个对象中;

-- 设置 Bundle 对象给 Fragment : 调用 Fragment 对象的 setArguments(Bundle bundle) 方法, 将 Bundle 对象设置给 Fragment;



5. Fragment 事务管理


FragmentManager 功能 : FragmentManager 对象 可以通过 activity.getFragmentManager()获取;

-- 获取指定 Fragment : 通过 findFragmentById() 或者 findFragmentByTag() 方法获取指定 Fragment;

-- 弹出栈 : 通过调用 popBackStack(), 将 Fragment 从后台的 栈 中弹出;

-- 监听栈 : 通过调用 addOnBackStackChangeListener 注册监听器, 监听 后台栈变化; 


FragmentTransaction 对象获取途径 : 

-- 获取 FragmentManager 对象 : 调用 Activity 的 getFragmentManager() 获取 FragmentManager 对象;

-- 获取 FragmentTansaction 对象 : 调用 FragmentManager 对象的 beginTransaction() 方法获取 FragmentTransaction 对象;


FragmentTransaction(Fragment 事务)作用 : 对 Fragement 进行 增, 删 , 改 操作需要 FragmentTransaction 对象进行操作, 开启 这个事务, 获取 事务对象, 然后执行对 Fragment 的操作, 最后提交事务;

-- 开启事务 :  调用 Fragement 对象的 beginTransaction() 方法可以获取 FragementTransaction 对象;

-- 操作碎片 :  FragmentTransaction 对象 中 包含了 add(), remove(), replace() 等方法;

-- 提交操作 :  当执行完 Fragement 的操作之后, 可以调用 FragementTransaction 对象的 commit() 方法提交修改;


addToBackStack()方法作用 : 该方法是 FragementTransaction 的方法, 在提交事务前调用该方法, 可以将 事务中执行的操作 添加到 back 栈中, 用户按下 回退键, 修改过的 Fragement 会 回退到 事务执行之前的状态;



6. Fragment 生命周期




(1) Fragment 状态


活动状态 : Fragment 处于前台, 可见可以获取焦点;


暂停状态 : Fragment 嵌入的Activity 也处于暂停状态, 即 Fragment 处于后台, 可见失去焦点


停止状态 : Fragement 嵌入的 Activity 处于停止状态, 不可见失去焦点;


销毁状态 : Fragement 所在的 Activity 被销毁, 执行了 onDestroy() 方法, 此时 Fragement 被完全删除;



(2) Fragement 生命周期相关方法


Android 开发 之 Fragment 详解_第1张图片


红色方法 与 Activity 相对应, 蓝色方法 是 自身对应的方法, 棕色方法 单独对应;


onAttach() : 嵌入, Fragement 被嵌入到 Activity 时回调该方法, 只会调用一次;


onCreate() : 创建, Fragement 创建的时候回调该方法, 只会回调一次;


onCreateView() : 绘制, 在 Fragement 绘制的时候回调该方法, 该方法会返回 绘制的 View 组件;


onActivityCreated() : 界面创建, Fragement 所嵌入的 Activity 创建完成回调该方法;


onStart() : 启动, Fragement 启动时回调, 此时Fragement可见;


onResume() : 激活, Fragement 进入前台, 可获取焦点时激活;


onPause() : 暂停, Fragement 进入后台, 不可获取焦点时激活;


onStop() : 停止, Fragement 不可见时回调;


onDestroyView() : 销毁组件, 销毁 Fragement 绘制的 View 组件时回调;


onDestroy() : 销毁, 销毁 Fragement 回调;


onDetach() : 移除, Fragement 从 Activity 中移除的时候回调;



7. 代码示例 



(1) 需求分析


纵向手机屏幕 : 两个界面, 每个界面都有一个 Fragement,  一个Fragement显示新闻列表, 一个Fragement 显示新闻内容;

横向手机屏幕 : 一个界面, 两个Fragement, Fragement 显示内容与上面相同;



(2) 新闻标题 Fragment


存放新闻标题的 Fragment : NewsTittleFragment.java

[java]  view plain copy
  1. package cn.org.octopus;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.ListFragment;  
  5. import android.os.Bundle;  
  6. import android.view.LayoutInflater;  
  7. import android.view.View;  
  8. import android.view.ViewGroup;  
  9. import android.widget.ArrayAdapter;  
  10. import android.widget.ListAdapter;  
  11. import android.widget.ListView;  
  12.   
  13. /** 
  14.  * 内部类 :  
  15.  *      Callbacks接口 
  16.  *      Fragement中维护该接口子类对象  
  17.  *      需要Activity实现该接口, 实现接口方法  
  18.  *      Activity 在onAttach()方法中传入;  
  19.  *  
  20.  * 方法简介 :  
  21.  *      重写生命周期的 11 个方法; 
  22.  *      onAttach() 方法中, 传入所嵌入的Activity, 并判断是否嵌入正确 
  23.  *      onCreate() 方法中, 创建  Fragement 中 ListView 的适配器, 并将适配器设置给 ListView 
  24.  *      onDetach() 方法中, 将  Callbacks 接口子类对象置空 
  25.  * 
  26.  *      setChoiceMode() 设置ListView 的选择模式 
  27.  *      onListItemClick() ListView 的点击回调方法 
  28.  *  注意 Android  
  29.  *       
  30.  */  
  31. public class NewsTittleFragment extends ListFragment {  
  32.   
  33.     private Callbacks activityCallback;         /* 从 onAttach()方法中传入的 Callbacks 接口子类, 由 Activity 强制转换而来 */  
  34.       
  35.     /** 定义回调接口   
  36.      *  接口用法 :  
  37.      *  1. 该 Fragement 所 Activity 实现该接口 
  38.      *  2. 该 Fragement 中 维护一个 该接口子类, 即 Activity 
  39.      *  3. 调用 Activity 接口子类的方法, 将数据传递给 Activity **/  
  40.     public interface Callbacks{  
  41.         public void onNewsSelect(int id);  
  42.     }  
  43.       
  44.       
  45.     /** Fragment 嵌入Activity */  
  46.     @Override  
  47.     public void onAttach(Activity activity) {  
  48.         super.onAttach(activity);  
  49.         System.out.println("onAttach");  
  50.           
  51.         if ( ! ( activity instanceof Callbacks))  
  52.             System.out.println("Fragement in wrong Activity !");  
  53.           
  54.         /* 为Activity中定义的Callbacks接口子类对象赋值 */  
  55.         activityCallback = (Callbacks) activity;  
  56.     }  
  57.       
  58.     /** Fragement 创建 
  59.      *  进行设置适配器操作 */  
  60.     @Override  
  61.     public void onCreate(Bundle savedInstanceState) {  
  62.         super.onCreate(savedInstanceState);  
  63.         System.out.println("onCreate");  
  64.           
  65.         /* 为 ListFragment 创建适配器 
  66.          * 注意使用的是 Android 自带的布局, 在 sdk\platforms\android-10\data\res\layout 目录下 
  67.          *  */  
  68.         ListAdapter adapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_activated_1, android.R.id.text1, NewsContent.getInstance().news);  
  69.         /* 设置适配器 给 ListFragement */  
  70.         setListAdapter(adapter);  
  71.     }  
  72.       
  73.     /** Fragment 绘制 */  
  74.     @Override  
  75.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  76.             Bundle savedInstanceState) {  
  77.         System.out.println("onCreateView");  
  78.         return super.onCreateView(inflater, container, savedInstanceState);  
  79.           
  80.     }  
  81.       
  82.     /** Activity 创建完毕 */  
  83.     @Override  
  84.     public void onActivityCreated(Bundle savedInstanceState) {  
  85.         super.onActivityCreated(savedInstanceState);  
  86.         System.out.println("onActivityCreated");  
  87.     }  
  88.       
  89.     /** Fragement 进入可视状态 */  
  90.     @Override  
  91.     public void onStart() {  
  92.         super.onStart();  
  93.         System.out.println("onStart");  
  94.     }  
  95.       
  96.     /** Fragement 进入激活状态 */  
  97.     @Override  
  98.     public void onResume() {  
  99.         super.onResume();  
  100.         System.out.println("onResume");  
  101.     }  
  102.       
  103.     /** Fragement 进入暂停状态 */  
  104.     @Override  
  105.     public void onPause() {  
  106.         super.onPause();  
  107.         System.out.println("onPause");  
  108.     }  
  109.       
  110.     /** Fragement 进入停止状态 */  
  111.     @Override  
  112.     public void onStop() {  
  113.         super.onStop();  
  114.         System.out.println("onStop");  
  115.     }  
  116.       
  117.     /** 销毁 Fragement 显示组件 */  
  118.     @Override  
  119.     public void onDestroyView() {  
  120.         super.onDestroyView();  
  121.         System.out.println("onDestroyView");  
  122.     }  
  123.       
  124.     /** 销毁 Fragement */  
  125.     @Override  
  126.     public void onDestroy() {  
  127.         super.onDestroy();  
  128.         System.out.println("onDestroy");  
  129.     }  
  130.       
  131.     /** 将 Fragement 从 Activity 中删除 */  
  132.     @Override  
  133.     public void onDetach() {  
  134.         super.onDetach();  
  135.         System.out.println("onDetach");  
  136.         activityCallback = null;  
  137.     }  
  138.       
  139.     /** 
  140.      * 列表对象被点击之后回调的方法 
  141.      */  
  142.     @Override  
  143.     public void onListItemClick(ListView l, View v, int position, long id) {  
  144.         super.onListItemClick(l, v, position, id);  
  145.         activityCallback.onNewsSelect((int) id);  
  146.     }  
  147.       
  148.     /** 设定选择模式, 该列表默认不能选择, 可以设置为不能选择, 单选 和 多选 
  149.      *  ListView.CHOICE_MODE_NONE       不能选择 
  150.      *  ListView.CHOICE_MODE_SINGLE     单选 
  151.      *  ListView.CHOICE_MODE_MULTIPLE   多选 
  152.      *  */  
  153.     public void setChoiceMode(int choiceMode) {  
  154.         getListView().setChoiceMode(choiceMode);  
  155.     }  
  156.       
  157. }  



(3) 新闻内容的 Fragment


存放新闻内容的 Fragment : NewsContentFragement.java;

[java]  view plain copy
  1. package cn.org.octopus;  
  2.   
  3. import android.app.Fragment;  
  4. import android.os.Bundle;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.TextView;  
  9.   
  10. public class NewsContentFragement extends Fragment {  
  11.   
  12.     /* Bundle的key */  
  13.     public static final String TAG_NEWS_ID = "cn.org.octopus.news.tittle";  
  14.       
  15.     private News news;  
  16.       
  17.     @Override  
  18.     public void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.           
  21.         /* 校验 参数中是否包含 TAG_NEWS_ID 键值*/  
  22.         boolean isIllegal = getArguments().containsKey(TAG_NEWS_ID);  
  23.           
  24.         if(isIllegal){  
  25.             /* 如果包含 TAG_NEWS_ID 键值, 就会去键对应的 id */  
  26.             int id = getArguments().getInt(TAG_NEWS_ID);  
  27.             /* 从 NewsContent 单例对象中的 map 集合中获取 news 对象 */  
  28.             news = NewsContent.getInstance().news_map.get(id);  
  29.         }  
  30.     }  
  31.       
  32.     @Override  
  33.     public void onSaveInstanceState(Bundle outState) {  
  34.         super.onSaveInstanceState(outState);  
  35.     }  
  36.       
  37.     @Override  
  38.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  39.             Bundle savedInstanceState) {  
  40.           
  41.         /* 加载布局文件 */  
  42.         View rootView = inflater.inflate(R.layout.fragment_news_content, container, false);  
  43.         /* 获取新闻标题组件 */  
  44.         TextView news_content_tittle = (TextView) rootView.findViewById(R.id.news_content_tittle);  
  45.         /* 获取新闻内容组件 */  
  46.         TextView news_content_content = (TextView) rootView.findViewById(R.id.news_content_content);  
  47.         if(null != news){  
  48.             /* 设置新闻标题 */  
  49.             news_content_tittle.setText(news.getTittle());  
  50.             /* 设置新闻内容 */  
  51.             news_content_content.setText(news.getContent());  
  52.         }  
  53.           
  54.         return rootView;  
  55.     }  
  56.       
  57. }  



(4) 新闻内容存储相关代码


新闻实体类 : 

[java]  view plain copy
  1. package cn.org.octopus;  
  2.   
  3. public class News {  
  4.   
  5.     private int id;         //新闻序号  
  6.     private String tittle;  //新闻标题  
  7.     private String content; //新闻内容  
  8.   
  9.     /** 构造方法  */  
  10.     public News(int id, String tittle, String content) {  
  11.         super();  
  12.         this.id = id;  
  13.         this.tittle = tittle;  
  14.         this.content = content;  
  15.     }  
  16.   
  17.     public int getId() {  
  18.         return id;  
  19.     }  
  20.   
  21.     public void setId(int id) {  
  22.         this.id = id;  
  23.     }  
  24.   
  25.     public String getTittle() {  
  26.         return tittle;  
  27.     }  
  28.   
  29.     public void setTittle(String tittle) {  
  30.         this.tittle = tittle;  
  31.     }  
  32.   
  33.     public String getContent() {  
  34.         return content;  
  35.     }  
  36.   
  37.     public void setContent(String content) {  
  38.         this.content = content;  
  39.     }  
  40.   
  41.     /* 这里只返回标题, 是为了适配 ListFragement 时使用 */  
  42.     @Override  
  43.     public String toString() {  
  44. //      return "News [id=" + id + ", tittle=" + tittle + ", content=" + content  
  45. //              + "]";  
  46.         return tittle;  
  47.     }  
  48.       
  49. }  


新闻数据 : 

[java]  view plain copy
  1. package cn.org.octopus;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7.   
  8. public class NewsContent {  
  9.   
  10.     /* 单例模式 
  11.      * 1. 私有 静态 本类成员变量 
  12.      * 2. 私有 构造 函数 
  13.      * 3. 公共 静态 函数, 检查本类成员变量是否为null, 返回本类成员变量 */  
  14.       
  15.     private static NewsContent newsContent;  
  16.       
  17.     public List news;  
  18.     public Map news_map;  
  19.       
  20.     private NewsContent(){  
  21.         news = new ArrayList();  
  22.         news_map = new HashMap();  
  23.           
  24.         News news1 = new News(0"郭振玺敛财术""7月30日,央视纪录频道CCTV-9总监刘文被带走。据相关报道,刘文被带走的原因是 “发现在纪录片对外采购上有财务问题”,另外,在一些高收视率的纪录片创作上,“涉嫌与隐性的植入广告有关的利益交换”。");  
  25.         News news2 = new News(1"朝鲜新版5000朝元新钞无金日成头像""韩国网刊《每日朝鲜》8月1日报道,已经开始流通的5000朝元新钞并未印金日成肖像,意味金日成肖像已从朝鲜货币上暂时消失。 旧版朝鲜5000元纸币上印有金日成头像。");  
  26.         News news3 = new News(2"美国医生感染埃博拉""菲律宾卫生部部长恩里克·奥尼亚说,目前菲律宾尚无埃博拉疫情。卫生部已通报地方卫生部门,一旦发现返菲海外劳工出现感染埃博拉病毒早期症状,立即对患者实行隔离治疗。卫生部还要求近期即将从海外回国的劳工如出现发烧、头痛、关节和肌肉疼痛、喉咙痛等症状,在回国前应获得所雇佣国家卫生部门的无感染证明,以避免埃博拉病毒传入菲律宾。");  
  27.                   
  28.         news.add(news1);  
  29.         news.add(news2);  
  30.         news.add(news3);  
  31.           
  32.         news_map.put(news1.getId(), news1);  
  33.         news_map.put(news2.getId(), news2);  
  34.         news_map.put(news3.getId(), news3);  
  35.     }  
  36.       
  37.     /** 
  38.      * 判断成员变量 是否为null  
  39.      *  如果不为null, 直接返回; 
  40.      *  如果为null, 先创建在返回; 
  41.      */  
  42.     public static NewsContent getInstance() {  
  43.           
  44.         if(newsContent != null)  
  45.             return newsContent;  
  46.         else  
  47.             return new NewsContent();  
  48.     }  
  49.       
  50. }  



(5) 主界面 Actiity 代码


主界面代码 : MainActivity.java

[java]  view plain copy
  1. package cn.org.octopus;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.FragmentManager;  
  5. import android.app.FragmentTransaction;  
  6. import android.os.Bundle;  
  7. import cn.org.octopus.NewsTittleFragment.Callbacks;  
  8.   
  9. public class MainActivity extends Activity implements Callbacks {  
  10.   
  11.     @Override  
  12.     protected void onCreate(Bundle savedInstanceState) {  
  13.         super.onCreate(savedInstanceState);  
  14.           
  15.         /* 加载布局文件, 这个布局文件中有一个 Fragment, 会自动加载该 Fragmet */  
  16.         setContentView(R.layout.activity_main);  
  17.     }  
  18.   
  19.     /**  
  20.      * 实现的 Callbasks 接口的方法,  
  21.      * 当 NewsTittleFragement 中的 ListView 被点击的时候 回调  
  22.      * */  
  23.     @Override  
  24.     public void onNewsSelect(int id) {  
  25.         /* 创建 Bundle 对象, Activity 传递给 Fragment 的参数需要靠该对象进行传递 */  
  26.         Bundle arguments = new Bundle();  
  27.         /* 封装数据到 Bundle 对象中, 注意提前定义好键值 */  
  28.         arguments.putInt(NewsContentFragement.TAG_NEWS_ID, id);  
  29.         /* 创建 Fragment 对象 */  
  30.         NewsContentFragement fragement = new NewsContentFragement();  
  31.         /* 将 Activity 要传递的数据 传递给 Fragment 对象 */  
  32.         fragement.setArguments(arguments);  
  33.         /* 获取FragmentManager 对象 */  
  34.         FragmentManager manager = getFragmentManager();  
  35.         /* 开启事务, 获取事务 */  
  36.         FragmentTransaction transaction =  manager.beginTransaction();  
  37.         /* 在事务中进行替换操作 */  
  38.         transaction.replace(R.id.news_content, fragement);  
  39.         /* 提交操作 */  
  40.         transaction.commit();  
  41.     }  
  42.   
  43. }  


(6) AndroidManifest.xml 配置文件


[html]  view plain copy
  1. xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="cn.org.octopus"  
  4.     android:versionCode="1"  
  5.     android:versionName="1.0" >  
  6.   
  7.     <uses-sdk  
  8.         android:minSdkVersion="15"  
  9.         android:targetSdkVersion="19" />  
  10.   
  11.     <application  
  12.         android:allowBackup="true"  
  13.         android:icon="@drawable/ic_launcher"  
  14.         android:label="@string/app_name"  
  15.         android:theme="@style/AppTheme" >  
  16.           
  17.         

你可能感兴趣的:(android知识)