详解Android开发中Fragment的使用

 更新时间:2015年07月31日 12:59:18   作者:低调小一  
这篇文章主要介绍了详解Android开发中Fragment的使用,包括Java代码中调用Fragment的方法,需要的朋友可以参考下

前言
学习Java和Android将近一年的时间了,期间的成果应该就是独立完成了一个Android客户端,并且保证了其在主线版本的稳定性。期间遇到了很多坑,也跟着师兄学到了很多Android知识。但是人总是要拥抱变化,不能让自己太安逸,虽然有不舍,但是我已经证明了自己的学习能力,下一步就是开始做Rom Porting了。这里总结一下之前项目中用到最多的Fragment。

Fragment简介
Fragment可以理解成Activity中用户界面的一个行为或者一部分,它必须被嵌套在Activity中。但是一个Fragment有它自己独立的xml布局文件,并且具有良好的封装性,因此特殊情况下Fragment可以很容易用Activity来进行替换。

创建Fragment
创建一个Fragment和创建Activity类似,需要实现XML布局文件和Java Class。
XML布局文件和其他布局文件都一样,例如如下所示的布局文件(fragment_layout.xml):

 <?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:orientation="vertical" > 
  
  <TextView 
   android:id="@+id/textView" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="@string/testview" /> 
  
  <Button 
   android:id="@+id/button" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="@string/button" /> 
  
 </LinearLayout> 

Java代码中,一般情况下可以根据需要实现Fragment以下几个生命周期方法:
1. onAttach():当Fragment依附于activity时被调用,可以在该方法中获取activity句柄,从而实现Fragment和activity之间的通信。
2. onCreate():对Fragment做初始化。
3. onCreateView():在第一次为Fragment绘制用户界面时系统会调用此方法。
4. onActivityCreated():在宿主Activity onCreate函数执行完成之后被调用,可以在这个方法里进行Fragment自己的widget实例化和业务逻辑处理。
5. onDestoryView():当Fragment开始被销毁时调用。
6. onStart():当Fragment可见时被调用。
还有许多其他用以操纵Fragment生命周期中各个阶段的回调函数,大家可自行Google学习。

Fragment生命周期
每一个Fragment都有自己的一套生命周期回调方法和处理自己的用户输入事件。对应的生命周期如下图所示:

2015731125232561.png (376×1066)

在Activity中加入Fragment
首先,需要确保Acitivity支持Fragment,因此Activity通常需要继承自FragmentActivity。在Activity中添加Fragment通常有两种方法:静态的和动态的。
静态方法
直接在Activity的XML布局文件中加入Fragment,如下所示:

 

 <?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="match_parent" 
  android:layout_height="match_parent" 
  android:baselineAligned="false" 
  android:orientation="horizontal" > 
  
  <fragment 
   android:id="@+id/first" 
   android:name="com.example.FristFragment" 
   android:layout_width="0dp" 
   android:layout_height="match_parent" 
   android:layout_weight="1" /> 
  
  <fragment 
   android:id="@+id/second" 
   android:name="com.example.SecondFragment" 
   android:layout_width="0dp" 
   android:layout_height="match_parent" 
   android:layout_weight="1" /> 
  
 </LinearLayout> 

<fragment>中的android:name 属性指定了布局中实例化的fragment类
当系统创建Activity布局时,它实例化了布局文件中指定的每一个Fragment,并且为它们调用onCreateView()函数,以获取每一个fragment的布局。系统直接在<fragment>元素位置插入fragment返回的view
注意:每个fragment都需要一个唯一的标识,如果重启activity,系统可用来恢复fragment(并且用来捕捉fragment的事务处理,例如移除)。为了Fragment提供ID有三种方法:

  •     用android:id属性提供一个唯一的标识
  •     用android:tag属性提供一个唯一的字符串
  •     如果上述两个属性都没有,系统会使用其容器视图的ID

动态方法
使用FragmentTranscation。可以使用FragmentTranscation的API来对Activity的Fragment进行操作(例如添加,移除,或者替换Fragment)。参考代码如下:

 FragmentManager fragmentManager = getFragmentManager() 
 FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
 ExampleFragment fragment = new ExampleFragment(); 
 fragmentTransaction.add(R.id.fragment_container, fragment); 
 fragmentTransaction.commit(); 

传入add()函数的第一个参数是Fragment被放置的ViewGroup,它由资源ID(resource ID)指定,第二个参数就是要添加的fragment。一旦通过FragmentTranscation做了更改,都应当使用commit()视变化生效。

Fragments通信
Fragments之间不应该直接进行通信,它们之间的交互应该通过宿主Activity进行。有三种Fragment和Acitivity交互的方法:
1. Activity创建带参数的Fragment。
2. Activity中保持了Fragment的对象句柄,可通过句柄直接调用该Fragment的public方法。
3. Fragment可在onAttach函数中获取定义的listener句柄。
创建带参数的Fragment
在某些特定的情况下,Fragment可能需要特定的参数来进行初始化。由于Fragment必须只有一个无参构造函数,因此可以考虑使用静态的newInstance方法来创建带参数的Fragment。示例代码如下:

  

 import android.os.Bundle; 
 import android.support.v4.app.Fragment; 
  
 public class TestFragment extends Fragment { 
  public static TestFragment newInstance(int num, String title) { 
   TestFragment fragment = new TestFragment(); 
   Bundle args = new Bundle(); 
   args.putInt("num", num); 
   args.putString("title", title); 
   fragment.setArguments(args); 
   return fragment; 
  } 
  
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
   super.onCreate(savedInstanceState); 
  
   int num = getArguments().getInt("num", 0); 
   String title = getArguments().getString("title", ""); 
  } 
  
 } 

你可以在Activity里,简单的加载一个带参数的Fragment:

 FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); 
 TestFragment fragment = TestFragment.newInstance(5, "fragment title"); 
 ft.replace(R.id.placeholder, fragment); 
 ft.commit(); 

调用Fragment的方法
因为Activity可以获取嵌入的Fragment的句柄,因此可以直接通过Fragment句柄调用该方法。

 public class TestFragment extends Fragment { 
  public void doSomething(String param) { 
   // do something in fragment 
  } 
 } 

在Activity中,可以直接通过Fragment的对象句柄调用该方法:

 public class MainActivity extends FragmentActivity { 
  @Override 
  public void onCreate(Bundle savedInstanceState) { 
   super.onCreate(savedInstanceState); 
   TestFragment testFragment = new TestFragment(); 
   testFragment.doSomething("some param"); 
  } 
 } 

Fragment Listener
如果Fragment需要共享事件给Activity,则需要利用这个方法。Fragment中定义一个接口,并且由Activity来实现这个接口。在onAttach()方法中将实现了这个接口的Activity获得到。
在Fragment中定义接口代码如下:

   

import android.support.v4.app.Fragment; 
  
 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"); 
  } 
 } 

在Activity中实现这个接口:

   

import android.support.v4.app.FragmentActivity; 
  
 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); 
   } 
  } 
 } 

相关文章

  • maven打包上传到私有仓库的实现步骤

    maven打包上传到私有仓库的实现步骤

    这篇文章主要介绍了maven打包上传到私有仓库的实现步骤,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-01-01
  • Java数据结构之环形链表和约瑟夫问题详解

    Java数据结构之环形链表和约瑟夫问题详解

    约瑟夫(Josephus)问题是单向环形链表的一种体现,也就是丢手帕问题,下面这篇文章主要给大家介绍了关于Java数据结构之环形链表和约瑟夫问题的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 教你使用java将excel数据导入MySQL

    教你使用java将excel数据导入MySQL

    今天教大家如何使用Java将excel数据导入MySQL,文中有非常详细的代码示例,对正在学习java的小伙伴呢很有帮助,需要的朋友可以参考下
    2021-05-05
  • 关于ArrayList的动态扩容机制解读

    关于ArrayList的动态扩容机制解读

    这篇文章主要介绍了关于ArrayList的动态扩容机制解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • 一文搞懂Java正则表达式的使用

    一文搞懂Java正则表达式的使用

    正则表达式,又称规则表达式,是一种文本模式。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。本文将通过示例为大家详细说说Java正则表达式的使用,感兴趣的可以了解一下
    2022-08-08
  • 关于Feign的覆写默认配置和Feign的日志

    关于Feign的覆写默认配置和Feign的日志

    这篇文章主要介绍了关于Feign的覆写默认配置和Feign的日志方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java实现添加页码到PDF文档

    Java实现添加页码到PDF文档

    页码可以清楚了解总页数、定位页数快速寻找自己所要的文段、打印时不会分不清头中尾。今天这篇文章就将介绍如何通过Java代码,以编程的方式将添加页码到PDF文档,需要的可以参考一下
    2023-04-04
  • mybatis多数据源动态切换的完整步骤

    mybatis多数据源动态切换的完整步骤

    这篇文章主要给大家介绍了关于mybatis多数据源动态切换的完整步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Kotlin-Coroutines中的async与await异步协程管理

    Kotlin-Coroutines中的async与await异步协程管理

    这篇文章主要为大家介绍了Kotlin-Coroutines中的async与await异步协程管理,提升程序性能解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Spring Boot集成Druid查看配置是否生效的方法

    Spring Boot集成Druid查看配置是否生效的方法

    本文主要介绍了Spring Boot集成Druid查看配置是否生效的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06

最新评论