Android Fragment简记

温习Android的知识。

本文更像是对CodePath Android Cliffnotes => Creating and Using Fragments的翻译及简化。

由于没有在CodePath Android Cliffnotes上找到lisence之类的信息,暂不知这样是否妥当。

Fragment一般可以理解成Activity的一部分(视图,UI)。

定义Fragment

一个Fragment包含两部分,View和Java类。

View可以是XML布局,也可以是纯Java代码的View。

Java类需要继承自Fragment类。在support library v4中的Fragment类可最低支持Api-4。

在Activity中加入Fragment

首先Activity要支持Fragment:如果使用的是support library中的Fragment,那么Activity也需要继承自support library中的FragmentActivity。

添加的方式有两种——静态的和动态的。

静态

直接在Activity的XML布局文件中加入Fragment。

class属性指定Java类。

<?xml version="1.0" encoding="utf-8"?>       

动态

使用FragmentManager。

但首先也需要在Activity的布局中有一个place holder给Fragment提供位置。

// Begin the transactionFragmentTransaction ft = getSupportFragmentManager().beginTransaction();// Replace the container with the new fragmentft.replace(R.id.your_placeholder, new FooFragment());// or ft.add(R.id.your_placeholder, new FooFragment());// Execute the changes specifiedft.commit();

生命周期

  • onAttach() Fragment attach到Activity时调用
  • onCreate() 对Fragment做初始化
  • onCreateView() 当Fragment需要创建View时调用
  • onActivityCreated() 当宿主Activity完成了onCreate()方法时被调用
  • onDestroyView() 当Fragment开始被销毁时调用
  • onStart() 当Fragment可见时调用
  • onResume() 获取一些昂贵的资源,如位置、传感器等
  • onPause() 释放昂贵资源,提交更改

与Fragment的交互

Fragment不应该相互间直接通信,而应通过Activity来进行。有三个方法可以在Fragment和Activity之间进行通信。

带参数的Fragment

在某些情况下,Fragment可能需要特定的参数。(用来初始化Fragment。)

一个常用模式是使用newInstance()来创建带参数的Fragment。(这样做的原因是Fragment只能有一个无参的构造方法。)

public class DemoFragment extends Fragment {    // Creates a new fragment given an int and title    // DemoFragment.newInstance(5, "Hello");    public static DemoFragment newInstance(int someInt, String someTitle) {        DemoFragment fragmentDemo = new DemoFragment();        Bundle args = new Bundle();        args.putInt("someInt", someInt);        args.putString("someTitle", someTitle);        fragmentDemo.setArguments(args);        return fragmentDemo;    }}public class DemoFragment extends Fragment {   @Override   public void onCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);       // Get back arguments       int SomeInt = getArguments().getInt("someInt", 0);          String someTitle = getArguments().getString("someTitle", "");       }}

Activity调用Fragment方法

public class MainActivity extends FragmentActivity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        DemoFragment fragmentDemo = (DemoFragment)             getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);        fragmentDemo.doSomething("some param");    }}

在Fragment中的Listener

如果Fragment需要共享事件给Activity,则需要利用这种方法。

Fragment中定义一个接口,并且由Activity来实现这个接口。在onAttach()方法中将实现了这个接口的Activity获取到。

public class MyListFragment extends Fragment {  // ...  // Define the listener of the interface type  // listener is the activity itself  private OnItemSelectedListener listener;  // Define the events that the fragment will use to communicate  public interface OnItemSelectedListener {    public void onRssItemSelected(String link);  }  // Store the listener (activity) that will have events fired once the fragment is attached  @Override  public void onAttach(Activity activity) {    super.onAttach(activity);      if (activity instanceof OnItemSelectedListener) {        listener = (OnItemSelectedListener) activity;      } else {        throw new ClassCastException(activity.toString()            + " must implement MyListFragment.OnItemSelectedListener");      }  }  // Now we can fire the event when the user selects something in the fragment  public void onSomeClick(View v) {     listener.onRssItemSelected("some link");  }}public class RssfeedActivity extends FragmentActivity implements  MyListFragment.OnItemSelectedListener {    DetailFragment fragment;  @Override  protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_rssfeed);      fragment = (DetailFragment) getSupportFragmentManager()            .findFragmentById(R.id.detailFragment);  }  // Now we can define the action to take in the activity when the fragment event fires  @Override  public void onRssItemSelected(String link) {      if (fragment != null && fragment.isInLayout()) {          fragment.setText(link);      }  }}

Fragment与ActionBar菜单项

如果Fragment中有相关联的ActionBar菜单项,可以在Fragment中通过onCreateOptionsMenu()方法来进行设置,就与Activity中一致。

需要注意的是,只有事件没有在Activity中被处理掉时,Fragment中的事件回调才会被调用。

但你需要设置该Fragment中有菜单项。

@Overridepublic void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setHasOptionsMenu(true);}

创建菜单:

@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {   inflater.inflate(R.menu.fragment_menu, menu);}

响应:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   // handle item selection   switch (item.getItemId()) {      case R.id.edit_item:         // do s.th.         return true;      default:         return super.onOptionsItemSelected(item);   }}

Fragment间的导航

可用:

  • ActionBar Tabs
  • Fragment Navigation Drawer
  • ViewPager

管理Fragment的回退栈

如果需要用后退键来回退Fragment,则在FragmentTransaction中调用addToBackstack()即可。

// Create the transactionFragmentTransaction fts = getSupportFragmentManager().beginTransaction();// Replace the content of the containerfts.replace(R.id.flContainer, new FirstFragment()); // Append this transaction to the backstackfts.addToBackStack("optional tag");// Commit the changesfts.commit(); 

也可进行弹出:

FragmentManager fragmentManager = getSupportFragmentManager();if (fragmentManager.getBackStackEntryCount() > 0) {    fragmentManager.popBackStack();} Android Fragment简记

Fragment一般可以理解成Activity的一部分(视图,UI)。

定义Fragment

一个Fragment包含两部分,View和Java类。

View可以是XML布局,也可以是纯Java代码的View。

Java类需要继承自Fragment类。在support library v4中的Fragment类可最低支持Android 2.1(API-7)。

在Activity中加入Fragment

首先Activity要支持Fragment:如果使用的是support library中的Fragment,那么Activity也需要继承自support library中的FragmentActivity。

添加的方式有两种——静态的和动态的。

静态

直接在Activity的XML布局文件中加入Fragment。

class属性指定Java类。

<?xml version="1.0" encoding="utf-8"?>       

动态

使用FragmentManager。

但首先也需要在Activity的布局中有一个place holder给Fragment提供位置。

// Begin the transactionFragmentTransaction ft = getSupportFragmentManager().beginTransaction();// Replace the container with the new fragmentft.replace(R.id.your_placeholder, new FooFragment());// or ft.add(R.id.your_placeholder, new FooFragment());// Execute the changes specifiedft.commit();

生命周期

  • onAttach() Fragment attach到Activity时调用
  • onCreate() 对Fragment做初始化
  • onCreateView() 当Fragment需要创建View时调用
  • onActivityCreated() 当宿主Activity完成了onCreate()方法时被调用
  • onDestroyView() 当Fragment开始被销毁时调用
  • onStart() 当Fragment可见时调用
  • onResume() - 获取一些昂贵的资源,如位置、传感器等
  • onPause() - 释放昂贵资源,提交更改

与Fragment的交互

Fragment不应该相互间直接通信,而应通过Activity来进行。有三个方法可以在Fragment和Activity之间进行通信。

带参数的Fragment

在某些情况下,Fragment可能需要特定的参数。(用来初始化Fragment。)

一个常用模式是使用newInstance()来创建带参数的Fragment。(这样做的原因是Fragment只能有一个无参的构造方法。)

public class DemoFragment extends Fragment {    // Creates a new fragment given an int and title    // DemoFragment.newInstance(5, "Hello");    public static DemoFragment newInstance(int someInt, String someTitle) {        DemoFragment fragmentDemo = new DemoFragment();        Bundle args = new Bundle();        args.putInt("someInt", someInt);        args.putString("someTitle", someTitle);        fragmentDemo.setArguments(args);        return fragmentDemo;    }}public class DemoFragment extends Fragment {   @Override   public void onCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);       // Get back arguments       int SomeInt = getArguments().getInt("someInt", 0);          String someTitle = getArguments().getString("someTitle", "");       }}

Activity调用Fragment方法

public class MainActivity extends FragmentActivity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        DemoFragment fragmentDemo = (DemoFragment)             getSupportFragmentManager().findFragmentById(R.id.fragmentDemo);        fragmentDemo.doSomething("some param");    }}

在Fragment中的Listener

如果Fragment需要共享事件给Activity,则需要利用这种方法。

Fragment中定义一个接口,并且由Activity来实现这个接口。在onAttach()方法中将实现了这个接口的Activity获取到。

public class MyListFragment extends Fragment {  // ...  // Define the listener of the interface type  // listener is the activity itself  private OnItemSelectedListener listener;  // Define the events that the fragment will use to communicate  public interface OnItemSelectedListener {    public void onRssItemSelected(String link);  }  // Store the listener (activity) that will have events fired once the fragment is attached  @Override  public void onAttach(Activity activity) {    super.onAttach(activity);      if (activity instanceof OnItemSelectedListener) {        listener = (OnItemSelectedListener) activity;      } else {        throw new ClassCastException(activity.toString()            + " must implement MyListFragment.OnItemSelectedListener");      }  }  // Now we can fire the event when the user selects something in the fragment  public void onSomeClick(View v) {     listener.onRssItemSelected("some link");  }}public class RssfeedActivity extends FragmentActivity implements  MyListFragment.OnItemSelectedListener {    DetailFragment fragment;  @Override  protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_rssfeed);      fragment = (DetailFragment) getSupportFragmentManager()            .findFragmentById(R.id.detailFragment);  }  // Now we can define the action to take in the activity when the fragment event fires  @Override  public void onRssItemSelected(String link) {      if (fragment != null && fragment.isInLayout()) {          fragment.setText(link);      }  }}

Fragment与ActionBar菜单项

如果Fragment中有相关联的ActionBar菜单项,可以在Fragment中通过onCreateOptionsMenu()方法来进行设置,就与Activity中一致。

需要注意的是,只有事件没有在Activity中被处理掉时,Fragment中的事件回调才会被调用。

但你需要设置该Fragment中有菜单项。

@Overridepublic void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setHasOptionsMenu(true);}

创建菜单:

@Overridepublic void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {   inflater.inflate(R.menu.fragment_menu, menu);}

响应:

@Overridepublic boolean onOptionsItemSelected(MenuItem item) {   // handle item selection   switch (item.getItemId()) {      case R.id.edit_item:         // do s.th.         return true;      default:         return super.onOptionsItemSelected(item);   }}

Fragment间的导航

可用:

  • ActionBar Tabs
  • Fragment Navigation Drawer
  • ViewPager

管理Fragment的回退栈

如果需要用后退键来回退Fragment,则在FragmentTransaction中调用addToBackstack()即可。

// Create the transactionFragmentTransaction fts = getSupportFragmentManager().beginTransaction();// Replace the content of the containerfts.replace(R.id.flContainer, new FirstFragment()); // Append this transaction to the backstackfts.addToBackStack("optional tag");// Commit the changesfts.commit(); 

也可进行弹出:

FragmentManager fragmentManager = getSupportFragmentManager();if (fragmentManager.getBackStackEntryCount() > 0) {    fragmentManager.popBackStack();}

更多相关文章

  1. Android中调用Rest web服务
  2. [置顶] android framework Service分析
  3. Android使用ksoap2调用C#webservice体会
  4. Android之ActivityManagerService浅谈
  5. android编写访问http的代码
  6. 关于android instrumentation的理解、使用
  7. Android(安卓)对话框(Dialog)大全
  8. Android(安卓)Activity的启动过程(API27 源码分析)
  9. Android将Service服务打包jar供三方调用

随机推荐

  1. cocos2dx2.1.4FATAL EXCEPTION: GLThread
  2. Android之模拟网易新闻客户端
  3. android音乐播放器开发 SweetMusicPlayer
  4. Android关于BuildToolVersion与ComplieSd
  5. react-native打包android
  6. Android中AsyncTask线程的使用
  7. 如何通过简历和面试找到好工作?
  8. Android刮奖控件,需要的直接拿去用
  9. Android通知栏颜色改变方法
  10. Android笔记1——开发前奏1开发环境搭建