zoukankan      html  css  js  c++  java
  • Android 4学习(8):用户界面

    参考《Professional Android 4 Development》

    Fragment简介

    Fragment是我们可以将Activity分成不同的组成部分,这些组成部分拥有自己的生命周期和UI。它的最大用途在于适配不同的屏幕。

    创建Fragment

    FragmentActivity有很多相似之处,例如可以不带UI,但这样做对两者似乎都没什么意义。他们的创建方式也很相似,例如下面的代码:

    package test.fragments;
    import android.app.Fragment;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    public class MySkeletonFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater,
      ViewGroup container,
      Bundle savedInstanceState) {
      // Create, or inflate the Fragment’s UI, and return it.
      // If this Fragment has no UI then return null.
      return inflater.inflate(R.layout.my_fragment, container, false);
      }
    }

    Fragment生命周期

    Fragment的生命周期和它的宿主Activity密切相关,几乎和宿主Activity的生命周期一致,他们之间最大的不同在于Activity可以增加或删除Fragment。下图总结了Fragment的生命周期:


    Fragment特有的生命周期事件

    1. Attach and detach Fragment from the parent Activity
    2. Creating and destroying Fragment
    3. Creating and Destroying UI

    获取Fragment Manager

    每个Activity对象都内置了一个FragmentManager对象,使用getFragmentManager()即可获得:

    FragmentManager fragmentManager = getFragmentManager();

    添加FragmentActivity

    在Activity中添加Fragment的最简单方法是使用layout配置文件,例如:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <fragment android:name="com.paad.weatherstation.MyListFragment"
      android:id="@+id/my_list_fragment"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="1"
      />
      <fragment android:name="com.paad.weatherstation.DetailsFragment"
      android:id="@+id/details_fragment"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="3"
      />
    </LinearLayout>

    调用inflate方法生成Fragment的界面后,Fragment实际上是一个类似ViewGroup的角色,在Activity中管理自己的UI。

    上面那种将Fragment添加到Activity的方法缺乏灵活性,不能实现动态地添加和删除,更好的方式是使用FragmentTranaction和类似下面这样的配置文件:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <FrameLayout
      android:id="@+id/ui_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="1"
      />
      <FrameLayout
      android:id="@+id/details_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="3"
      />
    </LinearLayout>

    使用FragmentTransaction

    FragmentTransaction可以在运行时添加,删除或替换Fragment,从而实现UI的动态变化。Fragment TransactionFragment ManagerbeginTransaction()方法创建,然后可以进行Fragment的添加,删除和替换,最后通过commit()方法提交修改。

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    // Add, remove, and/or replace Fragments.
    // Specify animations.
    // Add to back stack if required.
    fragmentTransaction.commit();

    添加,删除和替换Fragment

    使用FragmentTransactionadd方法可以添加一个新的Fragmentadd()方法的主要参数是Fragment的容器View(或其ID)及Fragment实例,例如:

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.ui_container, new MyListFragment());
    fragmentTransaction.commit();

    删除Fragment需要FragmentTransaction的remove()方法,参数为Fragment对象,Fragment对象可以通过FragmentManager的findFragmentById()方法获得。

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    Fragment fragment = fragmentManager.findFragmentById(R.id.details_fragment);
    fragmentTransaction.remove(fragment);
    fragmentTransaction.commit();

    替换Fragment使用的是FragmentTransaction的replace()方法,参数分别为所要替代Fragment所在容器的ID和新的Fragment:

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.details_fragment, new DetailFragment(selected_index));
    fragmentTransaction.commit();

    获取指定的Fragment

    有两种方法可以获取某个特定的Fragment,如果这个Fragment已经被添加到某个layout文件中,则可以使用xml文件中的id作为参数:

    MyFragment myFragment = (MyFragment)fragmentManager.findFragmentById(R.id.MyFragment);

    也可以通过创建Fragment时添加的tag获取特定的Fragment:

    MyFragment myFragment = (MyFragment)fragmentManager.findFragmentByTag(MY_FRAGMENT_TAG);

    删除Fragment容器

    在配置文件中将visibility的属性设为"gone",即可删除某个Fragment,例如:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="match_parent"
      android:layout_height="match_parent">
      <FrameLayout
      android:id="@+id/ui_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="1"
      />
      <FrameLayout
      android:id="@+id/details_container"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:layout_weight="3"
      android:visibility="gone"
      />
    </LinearLayout>

    FragmentBack Stack

    Activity拥有Activity Stack,从而在用户按”返回”按钮时,回到前一个ActivityFragment也可以响应”返回”事件,方法是FragmentTransactioncommit之前调用addToBackStack()方法。这样,在用户按返回键后,Android会首先重现之前的UI布局。

    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.add(R.id.ui_container, new MyListFragment());
    Fragment fragment = fragmentManager.findFragmentById(R.id.details_fragment);
    fragmentTransaction.remove(fragment);
    String tag = null;
    fragmentTransaction.addToBackStack(tag);
    fragmentTransaction.commit();

    原理和Activity类似,调用addToBackStack()后,Fragment会被push到back stack中,而不是销毁。

    Fragment Transaction的动画效果

    Fragment Transaction有两种方法实现动画效果,分别是:

    • 设置渐进
    transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);

    • 设置动画效果
    fragmentTransaction.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_out_right);

    Fragment和宿主Activity之间的接口

    Fragment可以通过getActivity()方法获得宿主Activity对象:

    TextView textView = (TextView)getActivity().findViewById(R.id.textview);

    另一种常见的FragmentActivity之间的交互方式是使用回调函数:

    public interface OnSeasonSelectedListener {
      public void onSeasonSelected(Season season);
    }
    private OnSeasonSelectedListener onSeasonSelectedListener;
      private Season currentSeason;
      @Override
      public void onAttach(Activity activity) {
      super.onAttach(activity);
      try {
      onSeasonSelectedListener = (OnSeasonSelectedListener)activity;
      } catch (ClassCastException e) {
      throw new ClassCastException(activity.toString() +"must implement OnSeasonSelectedListener");
      }
      }
      private void setSeason(Season season) {
      currentSeason = season;
      onSeasonSelectedListener.onSeasonSelected(season);
    }

    没有UI的Fragment

    尽管不常见,但Fragment的确是可以没有UI的,好处也许是拥有了更灵活的生命周期控制。没有UI的Fragment生命周期事件有这些:
    public class NewItemFragment extends Fragment {
      @Override
      public void onAttach(Activity activity) {
      	super.onAttach(activity);
     	// Get a type-safe reference to the parent Activity.
      }
      @Override
        public void onCreate(Bundle savedInstanceState) {
    	  super.onCreate(savedInstanceState);
    	  // Create background worker threads and tasks.
      }
      @Override
      public void onActivityCreated(Bundle savedInstanceState) {
    	  super.onActivityCreated(savedInstanceState);
    	  // Initiate worker threads and tasks.
      }
    }

    常用的Fragment类

    • DiagFragment
    • ListFragment
    • webViewFragment

















  • 相关阅读:
    【校招面试 之 C/C++】第23题 C++ STL(五)之Set
    Cannot create an instance of OLE DB provider “OraOLEDB.Oracle” for linked server "xxxxxxx".
    Redhat Linux安装JDK 1.7
    ORA-10635: Invalid segment or tablespace type
    Symantec Backup Exec 2012 Agent for Linux 卸载
    Symantec Backup Exec 2012 Agent For Linux安装
    You must use the Role Management Tool to install or configure Microsoft .NET Framework 3.5 SP1
    YourSQLDba介绍
    PL/SQL重新编译包无反应
    MS SQL 监控数据/日志文件增长
  • 原文地址:https://www.cnblogs.com/jubincn/p/3381079.html
Copyright © 2011-2022 走看看