• Android Fragment 完全解析


    参考文章:http://blog.csdn.net/guolin_blog/article/details/8881711 http://blog.csdn.net/guolin_blog/article/details/13171191 Android Fragment应用实战,使用碎片向ActivityGroup说再见

    界面如下:

    实现步骤:

    程序结构:

    1. 编写主界面的xml文件
      1. <?xml version="1.0" encoding="utf-8"?>
      2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      3.     android:orientation="vertical"
      4.     android:layout_width="fill_parent"
      5.     android:layout_height="fill_parent">
      6.  
      7.     <FrameLayout
      8.         android:layout_width="match_parent"
      9.         android:layout_height="0dp"
      10.         android:layout_weight="1"
      11.         android:id="@+id/content">
      12.     </FrameLayout>
      13.         <LinearLayout
      14.             android:layout_width="match_parent"
      15.             android:layout_height="60dp"
      16.             android:background="@drawable/tab_bg">
      17.             <RelativeLayout
      18.                 android:layout_width="0dp"
      19.                 android:layout_height="match_parent"
      20.                 android:layout_weight="1"
      21.                 android:id="@+id/message_layout">
      22.                 <LinearLayout
      23.                     android:layout_width="match_parent"
      24.                     android:layout_height="wrap_content"
      25.                     android:layout_centerVertical="true"
      26.                     android:orientation="vertical">
      27.                     <ImageView
      28.                         android:layout_width="wrap_content"
      29.                         android:layout_height="wrap_content"
      30.                         android:layout_gravity="center_horizontal"
      31.                         android:src="@drawable/message_unselected"
      32.                         android:id="@+id/message_image"/>
      33.                     <TextView
      34.                         android:layout_width="wrap_content"
      35.                         android:layout_height="wrap_content"
      36.                         android:layout_gravity="center_horizontal"
      37.                         android:text="消息"
      38.                         android:id="@+id/message_text"
      39.                         android:textColor="#82858b"/>
      40.                 </LinearLayout>
      41.             </RelativeLayout>
      42.             <RelativeLayout
      43.                 android:layout_width="0dp"
      44.                 android:layout_height="match_parent"
      45.                 android:layout_weight="1"
      46.                 android:id="@+id/contacts_layout">
      47.                 <LinearLayout
      48.                     android:layout_width="match_parent"
      49.                     android:layout_height="wrap_content"
      50.                     android:layout_centerVertical="true"
      51.                     android:orientation="vertical">
      52.                     <ImageView
      53.                         android:layout_width="wrap_content"
      54.                         android:layout_height="wrap_content"
      55.                         android:layout_gravity="center_horizontal"
      56.                         android:src="@drawable/contacts_unselected"
      57.                         android:id="@+id/contacts_image"/>
      58.                     <TextView
      59.                         android:layout_width="wrap_content"
      60.                         android:layout_height="wrap_content"
      61.                         android:layout_gravity="center_horizontal"
      62.                         android:text="联系人"
      63.                         android:id="@+id/contacts_text"
      64.                         android:textColor="#82858b"/>
      65.                 </LinearLayout>
      66.             </RelativeLayout>
      67.             <RelativeLayout
      68.                 android:layout_width="0dp"
      69.                 android:layout_height="match_parent"
      70.                 android:layout_weight="1"
      71.                 android:id="@+id/news_layout">
      72.                 <LinearLayout
      73.                     android:layout_width="match_parent"
      74.                     android:layout_height="wrap_content"
      75.                     android:layout_centerVertical="true"
      76.                     android:orientation="vertical">
      77.                     <ImageView
      78.                         android:layout_width="wrap_content"
      79.                         android:layout_height="wrap_content"
      80.                         android:layout_gravity="center_horizontal"
      81.                         android:src="@drawable/news_unselected"
      82.                         android:id="@+id/news_image"/>
      83.                     <TextView
      84.                         android:layout_width="wrap_content"
      85.                         android:layout_height="wrap_content"
      86.                         android:layout_gravity="center_horizontal"
      87.                         android:text="动态"
      88.                         android:id="@+id/news_text"
      89.                         android:textColor="#82858b"/>
      90.                 </LinearLayout>
      91.             </RelativeLayout>
      92.             <RelativeLayout
      93.                 android:layout_width="0dp"
      94.                 android:layout_height="match_parent"
      95.                 android:layout_weight="1"
      96.                 android:id="@+id/setting_layout">
      97.                 <LinearLayout
      98.                     android:layout_width="match_parent"
      99.                     android:layout_height="wrap_content"
      100.                     android:layout_centerVertical="true"
      101.                     android:orientation="vertical">
      102.                     <ImageView
      103.                         android:layout_width="wrap_content"
      104.                         android:layout_height="wrap_content"
      105.                         android:layout_gravity="center_horizontal"
      106.                         android:src="@drawable/setting_unselected"
      107.                         android:id="@+id/setting_image"/>
      108.                     <TextView
      109.                         android:layout_width="wrap_content"
      110.                         android:layout_height="wrap_content"
      111.                         android:layout_gravity="center_horizontal"
      112.                         android:text="设置"
      113.                         android:id="@+id/setting_text"
      114.                         android:textColor="#82858b"/>
      115.                 </LinearLayout>
      116.             </RelativeLayout>
      117.         </LinearLayout>
      118.  
      119. </LinearLayout>

      效果图如下:

      这里面最上方是一个frameLayout,下面是一个大的LinearLayout套了四个RelativeLayout,每个RelativeLayout 里面有套了一个LinearLayout,然后此线性布局下面放了一个imageview和Textview。

      其中,四个相对布局都是用的weight权重来实现的。

       

    2. 分别编写每个fragment的xml。
      1. <?xml version="1.0" encoding="utf-8"?>
      2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
      3.     android:layout_height="match_parent">
      4.  
      5.     <LinearLayout
      6.         android:layout_width="wrap_content"
      7.         android:layout_height="wrap_content"
      8.         android:orientation="vertical"
      9.         android:layout_centerInParent="true">
      10.         <ImageView
      11.             android:layout_width="wrap_content"
      12.             android:layout_height="wrap_content"
      13.             android:layout_gravity="center_horizontal"
      14.             android:src="@drawable/message_selected"/>
      15.         <TextView
      16.             android:layout_width="wrap_content"
      17.             android:layout_height="wrap_content"
      18.             android:layout_gravity="center_horizontal"
      19.             android:padding="10dp"
      20.             android:text="这是消息界面"
      21.             android:textSize="20sp"/>
      22.     </LinearLayout>
      23. </RelativeLayout>

      只举一个实例,其他一样。

    3. 为每个xml 定义各自的Fragment
      1. package com.example.FragmentDemo;
      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.  
      9. /**
      10.  * Created by zhuxuekui on 2015/5/18.
      11.  */
      12. public class MessageFragment extends Fragment {
      13.     @Override
      14.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      15.         View messageLayout = inflater.inflate(R.layout.message_layout,container,false);
      16.         return messageLayout;
      17.     }
      18. }
    4. 编写业务逻辑层
      1. /**
      2.  * 项目的主Activity,所有的Fragment都嵌入在这里。
      3.  *
      4.  * @author guolin
      5.  */
      6. public class MainActivity extends Activity implements OnClickListener {
      7.  
      8.    /**
      9.     * 用于展示消息的Fragment
      10.     */
      11.    private MessageFragment messageFragment;
      12.  
      13.    /**
      14.     * 用于展示联系人的Fragment
      15.     */
      16.    private ContactsFragment contactsFragment;
      17.  
      18.    /**
      19.     * 用于展示动态的Fragment
      20.     */
      21.    private NewsFragment newsFragment;
      22.  
      23.    /**
      24.     * 用于展示设置的Fragment
      25.     */
      26.    private SettingFragment settingFragment;
      27.  
      28.    /**
      29.     * 消息界面布局
      30.     */
      31.    private View messageLayout;
      32.  
      33.    /**
      34.     * 联系人界面布局
      35.     */
      36.    private View contactsLayout;
      37.  
      38.    /**
      39.     * 动态界面布局
      40.     */
      41.    private View newsLayout;
      42.  
      43.    /**
      44.     * 设置界面布局
      45.     */
      46.    private View settingLayout;
      47.  
      48.    /**
      49.     * 在Tab布局上显示消息图标的控件
      50.     */
      51.    private ImageView messageImage;
      52.  
      53.    /**
      54.     * 在Tab布局上显示联系人图标的控件
      55.     */
      56.    private ImageView contactsImage;
      57.  
      58.    /**
      59.     * 在Tab布局上显示动态图标的控件
      60.     */
      61.    private ImageView newsImage;
      62.  
      63.    /**
      64.     * 在Tab布局上显示设置图标的控件
      65.     */
      66.    private ImageView settingImage;
      67.  
      68.    /**
      69.     * 在Tab布局上显示消息标题的控件
      70.     */
      71.    private TextView messageText;
      72.  
      73.    /**
      74.     * 在Tab布局上显示联系人标题的控件
      75.     */
      76.    private TextView contactsText;
      77.  
      78.    /**
      79.     * 在Tab布局上显示动态标题的控件
      80.     */
      81.    private TextView newsText;
      82.  
      83.    /**
      84.     * 在Tab布局上显示设置标题的控件
      85.     */
      86.    private TextView settingText;
      87.  
      88.    /**
      89.     * 用于对Fragment进行管理
      90.     */
      91.    private FragmentManager fragmentManager;
      92.  
      93.    @Override
      94.    protected void onCreate(Bundle savedInstanceState) {
      95.       super.onCreate(savedInstanceState);
      96.       requestWindowFeature(Window.FEATURE_NO_TITLE);
      97.       setContentView(R.layout.activity_main);
      98.       // 初始化布局元素
      99.       initViews();
      100.       fragmentManager = getFragmentManager();
      101.       // 第一次启动时选中第0个tab
      102.       setTabSelection(0);
      103.    }
      104.  
      105.    /**
      106.     * 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。
      107.     */
      108.    private void initViews() {
      109.       messageLayout = findViewById(R.id.message_layout);
      110.       contactsLayout = findViewById(R.id.contacts_layout);
      111.       newsLayout = findViewById(R.id.news_layout);
      112.       settingLayout = findViewById(R.id.setting_layout);
      113.       messageImage = (ImageView) findViewById(R.id.message_image);
      114.       contactsImage = (ImageView) findViewById(R.id.contacts_image);
      115.       newsImage = (ImageView) findViewById(R.id.news_image);
      116.       settingImage = (ImageView) findViewById(R.id.setting_image);
      117.       messageText = (TextView) findViewById(R.id.message_text);
      118.       contactsText = (TextView) findViewById(R.id.contacts_text);
      119.       newsText = (TextView) findViewById(R.id.news_text);
      120.       settingText = (TextView) findViewById(R.id.setting_text);
      121.       messageLayout.setOnClickListener(this);
      122.       contactsLayout.setOnClickListener(this);
      123.       newsLayout.setOnClickListener(this);
      124.       settingLayout.setOnClickListener(this);
      125.    }
      126.  
      127.    @Override
      128.    public void onClick(View v) {
      129.       switch (v.getId()) {
      130.       case R.id.message_layout:
      131.          // 当点击了消息tab时,选中第1个tab
      132.          setTabSelection(0);
      133.          break;
      134.       case R.id.contacts_layout:
      135.          // 当点击了联系人tab时,选中第2个tab
      136.          setTabSelection(1);
      137.          break;
      138.       case R.id.news_layout:
      139.          // 当点击了动态tab时,选中第3个tab
      140.          setTabSelection(2);
      141.          break;
      142.       case R.id.setting_layout:
      143.          // 当点击了设置tab时,选中第4个tab
      144.          setTabSelection(3);
      145.          break;
      146.       default:
      147.          break;
      148.       }
      149.    }
      150.  
      151.    /**
      152.     * 根据传入的index参数来设置选中的tab页。
      153.     *
      154.     * @param index
      155.     * 每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。
      156.     */
      157.    private void setTabSelection(int index) {
      158.       // 每次选中之前先清楚掉上次的选中状态
      159.       clearSelection();
      160.       // 开启一个Fragment事务
      161.       FragmentTransaction transaction = fragmentManager.beginTransaction();
      162.       // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
      163.       hideFragments(transaction);
      164.       switch (index) {
      165.       case 0:
      166.          // 当点击了消息tab时,改变控件的图片和文字颜色
      167.          messageImage.setImageResource(R.drawable.message_selected);
      168.          messageText.setTextColor(Color.WHITE);
      169.          if (messageFragment == null) {
      170.             // 如果MessageFragment为空,则创建一个并添加到界面上
      171.             messageFragment = new MessageFragment();
      172.             transaction.add(R.id.content, messageFragment);
      173.          } else {
      174.             // 如果MessageFragment不为空,则直接将它显示出来
      175.             transaction.show(messageFragment);
      176.          }
      177.          break;
      178.       case 1:
      179.          // 当点击了联系人tab时,改变控件的图片和文字颜色
      180.          contactsImage.setImageResource(R.drawable.contacts_selected);
      181.          contactsText.setTextColor(Color.WHITE);
      182.          if (contactsFragment == null) {
      183.             // 如果ContactsFragment为空,则创建一个并添加到界面上
      184.             contactsFragment = new ContactsFragment();
      185.             transaction.add(R.id.content, contactsFragment);
      186.          } else {
      187.             // 如果ContactsFragment不为空,则直接将它显示出来
      188.             transaction.show(contactsFragment);
      189.          }
      190.          break;
      191.       case 2:
      192.          // 当点击了动态tab时,改变控件的图片和文字颜色
      193.          newsImage.setImageResource(R.drawable.news_selected);
      194.          newsText.setTextColor(Color.WHITE);
      195.          if (newsFragment == null) {
      196.             // 如果NewsFragment为空,则创建一个并添加到界面上
      197.             newsFragment = new NewsFragment();
      198.             transaction.add(R.id.content, newsFragment);
      199.          } else {
      200.             // 如果NewsFragment不为空,则直接将它显示出来
      201.             transaction.show(newsFragment);
      202.          }
      203.          break;
      204.       case 3:
      205.       default:
      206.          // 当点击了设置tab时,改变控件的图片和文字颜色
      207.          settingImage.setImageResource(R.drawable.setting_selected);
      208.          settingText.setTextColor(Color.WHITE);
      209.          if (settingFragment == null) {
      210.             // 如果SettingFragment为空,则创建一个并添加到界面上
      211.             settingFragment = new SettingFragment();
      212.             transaction.add(R.id.content, settingFragment);
      213.          } else {
      214.             // 如果SettingFragment不为空,则直接将它显示出来
      215.             transaction.show(settingFragment);
      216.          }
      217.          break;
      218.       }
      219.       transaction.commit();
      220.    }
      221.  
      222.    /**
      223.     * 清除掉所有的选中状态。
      224.     */
      225.    private void clearSelection() {
      226.       messageImage.setImageResource(R.drawable.message_unselected);
      227.       messageText.setTextColor(Color.parseColor("#82858b"));
      228.       contactsImage.setImageResource(R.drawable.contacts_unselected);
      229.       contactsText.setTextColor(Color.parseColor("#82858b"));
      230.       newsImage.setImageResource(R.drawable.news_unselected);
      231.       newsText.setTextColor(Color.parseColor("#82858b"));
      232.       settingImage.setImageResource(R.drawable.setting_unselected);
      233.       settingText.setTextColor(Color.parseColor("#82858b"));
      234.    }
      235.  
      236.    /**
      237.     * 将所有的Fragment都置为隐藏状态。
      238.     *
      239.     * @param transaction
      240.     * 用于对Fragment执行操作的事务
      241.     */
      242.    private void hideFragments(FragmentTransaction transaction) {
      243.       if (messageFragment != null) {
      244.          transaction.hide(messageFragment);
      245.       }
      246.       if (contactsFragment != null) {
      247.          transaction.hide(contactsFragment);
      248.       }
      249.       if (newsFragment != null) {
      250.          transaction.hide(newsFragment);
      251.       }
      252.       if (settingFragment != null) {
      253.          transaction.hide(settingFragment);
      254.       }
      255.    }
      256. }

    首先在oncreate方法里面initview() 初始化各个控件,然后为每个layout 设置监听事件(相对布局的layout),当我们点击到某个layout时候,执行SetTabSelection(index)方法。

    在刚刚的方法里面,我们首先执行clearSelection,将所有的imageview都设置为不选中状态,然后并隐藏hideFragment,这里我们用FragmentManager里面的FragmentTransaction来实现的。

    这两个方法执行完之后,我们进入到switch条件语句,改变某个选中的图标的图片以及文字,这里面我们显示的是Fragment,没有用replace而是用的add,show,hide方法来实现。这样程序执行的效率会高一点,不然,用replace的话,被替换掉的fragment会彻底的被干掉,即声明周期结束,当我们又一次选中的时候,还要重新加载,这样变得麻烦。

  • 相关阅读:
    devenv.exe与devenv.com
    [LeetCode 132] 回文分割II(Palindrome Partitioning II)
    [翻译]More C++ Idioms 取址器(Address of)
    [LeetCode 131] 回文分割(Palindrome Partitioning)
    [翻译]More C++ Idioms 类成员检测器
    C++类的隐式默认构造函数
    [翻译]More C++ Idioms 通过初始化挂接(Attach by Initialization)
    【转】来自微软的纯CSS下拉菜单
    引用asp.net母版页后,母版页和内容页的页面事件执行顺序
    如何解决无法显示隐藏文件/文件夹
  • 原文地址:https://www.cnblogs.com/zhuxuekui/p/4513371.html
Copyright © 2020-2023  润新知