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

















  • 相关阅读:
    兼容各浏览器,背景透明,内容不透明
    101 个 MySQL 的调节和优化的提示
    二手房买卖砍价最新攻略 帮你花少钱买好房
    “中国互联网100强”(2013)发布
    写入文件,创建xunlei批量任务
    武汉选房
    Java并发编程(十一)线程池的使用
    Retrofit 代理模式
    Java并发编程(十)阻塞队列
    不要在Android的Application对象中缓存数据!
  • 原文地址:https://www.cnblogs.com/jubincn/p/3381079.html
Copyright © 2011-2022 走看看