Android基础知识点整理之四大组件、Fragment(精华)

一、Android四大组件:

        Activity(活动)用于用户交互和功能表现;Service(服务)后台服务运行功能处理,没有界面呈现;Broadcast Receive(广播)用于广播接收者,所用于service和activity之间的数据传输;Content Provider(内容提供者)支持多个应用之间数据的存储和读取,类似于数据库。

1、Activity(活动):

        Activity是Android的四大组件之一,也是一个工程里面应用最多的组件,工程里面所有可见的UI都全都依托于Activity。用户可视化操作界面,同时可以为用户提供交互入口,当我们创建一个Activity时需要调用setContentView()方法来完成界面的显示。

(1)一个Activity通常就是一个单独的屏幕(窗口)

(2)Activity之间使用Intent通信,多使用Bundle传值:

A页面:
    Intent intent = new Intent(AActivity.this, BActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString("KEY", "value");
    intent.putExtras(bundle);
    startActivity(intent);
B页面:
    Intent intent = getIntent();
    String value = intent.getStringExtra("KEY", "");

(3)Activity的生命周期:

        在Activity中会维持一个Activity Stack(Activity栈),当一个新的Activity被创建时会被放在栈顶,这个Activity就处于运行状态。当再有一个Activity被创建时就会被重新压入栈顶,而之前创建的Activity就会被压在新创建的Activity下面,之前的Activity就会在后台运行 。

a、Running运行中:Activity被创建并且处于Running可见状态,并且可以用户交互,此时的Activity处于栈顶 

b、Paused暂停状态:当Activity失去焦点,不能与用户交互,但是依然可见。当一个新的非全屏的Activity或透明的Activity(弹窗)就执行onPause()方法处于暂停状态,这个时候Activity中的各种数据还在保存着;当非全屏的Activity或透明的Activity被关闭时就执行onResume()方法恢复运行。

c、Stoped停止状态:当一个Activity被另一个Activity完全覆盖,或者点击HOME键退入了后台,这时候Activity执行onStop()方法处于停止状态。这里有些是跟暂停状态相似的:这个时候Activity的各种数据还被保持着;当系统的别的地方需要用到内容时,系统会自动的去销毁Activity。当Activity重新显示时则依次执行onReStart()、onStart()、onResume()方法恢复运行。

d、Destroy销毁状态:当我们点击返回按钮或者执行finish()方法或者在系统内存不够用时就会把把Activity从栈里面移除销毁被系统回收。

图片

Activity 类定义了下面的回调。可以不用实现所有的回调方法。但了解其中的每一个非常的重要,实现这些可以保证你的应用行为如用户所期望的那样。

回调描述
onCreate()这是第一个回调,在活动第一次创建时调用
onStart()这个回调在活动为用户可见时被调用
onResume()这个回调在应用程序与用户开始可交互的时候调用
onPause()被暂停的活动无法接受用户输入,不能执行任何代码。当前活动将要被暂停,上一个活动将要被恢复时调用
onStop()当活动不在可见时调用
onDestroy()当活动被系统销毁之前调用
onRestart()当活动被停止以后重新打开时调用

示例代码:

public class MainActivity extends Activity {
   String msg = "Android : ";

   /** 当活动第一次被创建时调用 */
   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);  //加载UI组件
      Log.d(msg, "The onCreate() event");
   }

   /** 当活动即将可见时调用 */
   @Override
   protected void onStart() {
      super.onStart();
      Log.d(msg, "The onStart() event");
   }

   /** 当活动可见时调用 */
   @Override
   protected void onResume() {
      super.onResume();
      Log.d(msg, "The onResume() event");
   }

   /** 当其他活动获得焦点时调用 */
   @Override
   protected void onPause() {
      super.onPause();
      Log.d(msg, "The onPause() event");
   }

   /** 当活动不再可见时调用 */
   @Override
   protected void onStop() {
      super.onStop();
      Log.d(msg, "The onStop() event");
   }

   /** 当活动将被销毁时调用 */
   @Override
   public void onDestroy() {
      super.onDestroy();
      Log.d(msg, "The onDestroy() event");
   }
}

 

2、Service(服务)

        通常用作后台处理耗时的操作,与Activity一样存在自己的生命周期,需要继承Service基类并且在AndroidManifest.xml(使用<service></service>标签)中配置相关信息。它非常适合执行那些不需要和用户交互但还要长期运行的任务,不过需要注意的是,服务并不是运行在一个独立的进程当中的,而是依赖于创建服务时所在的应用程序进程。与某个应用程序进程被杀掉时,所有依赖于该进程的服务也会停止运行。另外也不要被服务的后台概念所迷惑,实际上服务并不会自动开启线程,所有的代码都是默认运行在主线程当中的。也就是说,我们需要在服务的内部手动创建子线程,并在这里执行具体的任务,否则就有可能出现主线程被阻塞住的情况。

a、Service用于后台完成用户指定的操作,分为两种:

        (1)startService()(启动服务):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于started状态。是由其他组件调用startService()方法启动的,这导致服务的onStartCommand()方法被调用。当服务是started状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()方法停止,或者由其他组件调用stopService()方法停止。

        (2)bindService()(绑定服务):当应用程序组件调用bindService()方法绑定到服务时,服务处于bound状态。调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,大有“不求同时生,必须同时死”的特点。

图片

 

b、要创建服务,你需要创建一个继承自Service基类,Service基类定义了不同的回调方法和多数重要方法。你不需要实现所有的回调方法。虽然如此,理解所有的方法还是非常重要的:

回调描述
onStartCommand()其他组件(如Activity)通过调用startService()来请求启动服务时,系统调用onStartCommand()方法。如果你实现该方法,你必须在工作完成时调用stopSelf()或者stopService()方法来停止服务。
onBind当其他组件想要通过bindService()来绑定服务时,系统调用该方法。如果你实现该方法,你需要返回IBinder对象来提供一个接口,以便客户来与服务通信。你必须实现该方法,如果你不允许绑定,则直接返回null。
onUnbind()当中断所有服务发布的特殊接口时,系统调用该方法。
onRebind()当新的客户端与服务连接,且此前它已经通过onUnbind(Intent)通知断开连接时,系统调用该方法。
onCreate()当服务通过onStartCommand()和onBind()被第一次创建的时候,系统调用该方法。该调用要求执行一次性安装。
onDestroy()当服务不再有用或者被销毁时,系统调用该方法。你的服务需要实现该方法来清理任何资源,如线程,已注册的监听器,接收器等。

代码示例说明生命周期:

//继承Service基类
public class HelloService extends Service {  

    /** 标识服务如果被杀死之后的行为 */
    int mStartMode;

    /** 绑定的客户端接口 */
    IBinder mBinder;

    /** 标识是否可以使用onRebind */
    boolean mAllowRebind;

    /** 当服务被创建时调用. */
    @Override
    public void onCreate() {

    }


    /** 调用startService()启动服务时回调 */
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return mStartMode;
    }


    /** 通过bindService()绑定到服务的客户端 */
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }


    /** 通过unbindService()解除所有客户端绑定时调用 */
    @Override
    public boolean onUnbind(Intent intent) {
        return mAllowRebind;
    }

    /** 通过bindService()将客户端绑定到服务时调用*/
    @Override
    public void onRebind(Intent intent) {

    }

    /** 服务不再有用且将要被销毁时调用 */
    @Override
    public void onDestroy() {

    }
}

实际应用在程序中的简单示例:

第一步创建MyService来继承Service基类,我们只实现onStartCommand()和onDestroy() 

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;

public class MyService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Let it continue running until it is stopped.
        Toast.makeText(this, "服务已经启动", Toast.LENGTH_LONG).show();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Toast.makeText(this, "服务已经停止", Toast.LENGTH_LONG).show();
    }
}

第二步配置AndroidManifest.xm

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.runoob.androidservices"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk
        android:minSdkVersion="13"
        android:targetSdkVersion="22" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>

        </activity>

        //注册Service
        <service android:name=".MyService" />

    </application>

</manifest>

第三步在Activity中使用startService()和stopService()方法来启动和停止服务

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    // 启动Service
    public void startService(View view) {
        startService(new Intent(getBaseContext(), MyService.class));
    }

    // 停止Service
    public void stopService(View view) {
        stopService(new Intent(getBaseContext(), MyService.class));
    }
}

Service常见问题:

Q:Service的onCreate回调函数可以做耗时的操作吗?

A:不可以, Service的onCreate是在主线程(ActivityThread)中调用的,耗时操作会阻塞UI

Q:如果需要做耗时的操作,你会怎么做?

A:线程和Handler方式

Q:是否知道IntentService,在什么场景下使用IntentService?

A:IntentService相比父类Service而言,最大特点是其回调函数onHandleIntent中可以直接进行耗时操作,不必再开线程。其原理是IntentService的成员变量 Handler在初始化时已属于工作线程,之后handleMessage,包括onHandleIntent等函数都运行在工作线程中。

如果对IntentService的了解仅限于此,会有种IntentService很鸡肋的观点,因为在Service中开线程进行耗时操作也不麻烦。我当初也是这个观点,所以很少用IntentService。

但是IntentService还有一个特点,就是多次调用onHandleIntent函数(也就是有多个耗时任务要执行),多个耗时任务会按顺序依次执行。原理是其内置的Handler关联了任务队列,Handler通过looper取任务执行是顺序执行的。这个特点就能解决多个耗时任务需要顺序依次执行的问题。而如果仅用service,开多个线程去执行耗时操作,就很难管理。

关于IntentService的详解可以去看看这篇文章:Android 多线程之IntentService 完全详解_zejian的博客-CSDN博客_intentservice

3、Broadcast Receive(广播)

广播接收器用于响应来自其他应用程序或者系统的广播消息。这些消息有时被称为事件或者意图。例如,应用程序可以初始化广播来让其他的应用程序知道一些数据已经被下载到设备,并可以为他们所用。这样广播接收器可以定义适当的动作来拦截这些通信。

有以下两个重要的步骤来使系统的广播意图配合广播接收器工作。

  • 创建广播接收器
  • 注册广播接收器

代码示例:

第一步创建广播接收器需要实现为BroadcastReceiver类的子类,并重写onReceive()方法来接收以Intent对象为参数的消息:

public class MyReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
        String action = intent.getAction(); //获取action标志
        if(action.equals("cn.programmer.CUSTOM_INTENT")){
            String value = intent.getStringExtra("key");
            Toast.makeText(context, "接收到Intent传递的消息"+value, Toast.LENGTH_LONG).show();
        }
      
   }
}

第二步在MainActivity.java 中通过sendBrodcast(intent)发送广播

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //发送自定义广播
        Intent intent = new Intent();
        intent.setAction("cn.programmer.CUSTOM_INTENT");
        intent.putExtra("key","value");
        sendBroadcast(intent);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

   
}

第三步注册广播接收器:分为静态注册和动态注册

        a、静态注册:通过在AndroidManifest.xml中注册广播接收器来监听制定的广播意图。假设我们将要注册MyReceiver来监听自定义产生的cn.programmer.CUSTOM_INTENT事件。该事件由Android系统的启动进程完成时发出。

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">

      <intent-filter>
         <action android:name="cn.programmer.CUSTOM_INTENT">
         </action>
      </intent-filter>

   </receiver>
</application>

        现在,无论什么时候Android设备被启动,都将被广播接收器MyReceiver所拦截,并且在onReceive()中实现的逻辑将被执行。

        有许多系统产生的事件被定义为类Intent中的静态常量值。下面的表格列举了重要的系统事件。

事件常量描述
android.intent.action.BATTERY_CHANGED持久的广播,包含电池的充电状态,级别和其他信息。
android.intent.action.BATTERY_LOW标识设备的低电量条件。
android.intent.action.BATTERY_OKAY标识电池在电量低之后,现在已经好了。
android.intent.action.BOOT_COMPLETED在系统完成启动后广播一次。
android.intent.action.BUG_REPORT显示报告bug的活动。
android.intent.action.CALL执行呼叫数据指定的某人。
android.intent.action.CALL_BUTTON用户点击"呼叫"按钮打开拨号器或者其他拨号的合适界面。
android.intent.action.DATE_CHANGED日期发生改变。
android.intent.action.REBOOT设备重启。

        b、动态注册:使用registerReceiver(myReciver,intentFilter);来动态注册

public class MainActivity extends Activity {  
    MyReceiver myReceiver;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main); 
 
        //1、实例化IntentFilter对象  
        IntentFilter intentFilter = new IntentFilter();  
        intentFilter.addAction("cn.programmer.CUSTOM_INTENT");  
        myReceiver = new MyReceiver();  
        //2、注册广播接收  
        registerReceiver(myReceiver,intentFilter);  
    } 
 
    //3、按钮点击事件,通过sendBroadcast发送广播
    public void send2(View v){  
        Intent intent = new Intent();  
        intent.setAction("cn.programmer.CUSTOM_INTENT");  
        intent.putExtra("key","value");  
        sendBroadcast(intent);  
    }  
    /*4、动态注册需在Acticity生命周期onPause通过 
     *unregisterReceiver()方法移除广播接收器, 
     * 优化内存空间,避免内存溢出 
     */  
    @Override  
    protected void onPause() {  
        super.onPause();  
        unregisterReceiver(new MyReceiver());  
    }  
    
}  

4、内容提供者(Content Provider)

        ContentProvider是Android提供给上层的一个组件,主要用于实现数据访问的统一管理和数据共享。这里的数据管理是通过定义统一的访问接口来完成,如增删改查。同时,它采用了类似Internet的URL机制,将数据以URI的形式来标识,这样其他App就可以采用一套标准的URI规范来访问同一处数据,而不用关心具体的实现细节。我们知道在Android系统中可能会涉及到一个App的数据被其他App使用的情况,比如通讯录,日历,短信等,这时就需要一套能实现数据共享的机制,这里的ContentProvider就可以提供该功能,其底层使用了binder来完成App进程之间的通信,同时使用匿名共享内存来作为共享数据的载体。当然为了保证数据访问的安全性,ContentProvider还对每处的数据URI增加了权限管理机制,以控制该数据的访问者及访问方式。

图片

有时候需要在应用程序之间共享数据。这时内容提供者变得非常有用。

内容提供者可以让内容集中,必要时可以有多个不同的应用程序来访问。内容提供者的行为和数据库很像。你可以查询,编辑它的内容,使用 insert(), update(), delete() 和 query() 来添加或者删除内容。多数情况下数据被存储在 SQLite 数据库。

内容提供者被实现为类 ContentProvider 类的子类。需要实现一系列标准的 API,以便其他的应用程序来执行事务。

 如何使用ContentProvider:

public class MyContentProvider extends ContentProvider {
    public MyContentProvider() {
    }

    @Override
    public boolean onCreate() {
        // TODO:启动时初始化你的内容
        return false;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {
        // TODO: 处理客户端的查询请求
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public String getType(Uri uri) {
        // TODO:处理对给定URI上数据的MIME类型的请求。  
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        // TODO: 处理插入新行的请求  
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        // 处理删除一行或多行的请求。  
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        // TODO: 处理更新一行或多行的请求。  
        throw new UnsupportedOperationException("Not yet implemented");
    }
}

咋一看,这些接口貌似跟数据库的访问接口类似。没错,ContentProvider就是专门来管理数据库中的数据的。那么既然作为通用的数据访问接口,ContentProvider为什么没有提供对普通文件的访问接口呢?我猜测是因为普通文件的数据是非结构化的,无法抽象出一套统一的访问接口,而数据库中的数据都是结构化数据,就相对比较容易了。

此外一般我们不会直接使用ContentProvider来访问,而是会通过ContentResolver来访问ContentProvider,为什么?因为ContentProvider作为一个数据源处理中心,不止给App内部使用,还会被其他App访问。所以这里的ContentProvider就好比一个server,其他的App在访问这个ContentProvider的时候都必须先获得一个Server的Client才行,这里的ContentResolver就是Android提供给开发者使用来得到一个ContentProvider Client的管理工具类。示例代码如下:

//根据号码获取联系人的姓名
public void getContactNameByNumber() throws Exception {
    ContentResolver resolver = getContentResolver();
    Cursor cursor = resolver.query(ContactsContract.Contacts.CONTENT_URI, new String[]{ContactsContract.Data.DISPLAY_NAME}, null, null, null);
    if(cursor.moveToFirst()){
        String name = cursor.getString(0);
        Log.i(TAG, name);
    }
    cursor.close();
}

此外我们在创建一个ContentProvider组件的时候,必须要声明一个authorities,并且必须保证系统内该字段不重名,它就好比URL中的主机地址。示例如下:

<provider
    android:name=".MyContentProvider"
    android:authorities="com.xiaofei"
    android:enabled="true"
    android:exported="true">

二、Fragment

1、定义:学名“碎片”,Activity界面中的一部分,可以理解为模块化的Activity

        (a)Fragment不能独立存在,必须嵌入到Activity中

        (b)Fragment就有自己的生命周期,处理它自己的事情,并可以在Activity运行时被创建和销毁

        (c) Fragment的生命周期受所在Activity的影响,比如当Activity暂停时,依托在该Activity中的所有Fragment全部暂停

        (d)支持动态、灵活的界面设计;fragment从Android3.0后引入,在低版本Android3.0之前,需要采用android-support-v4.jar兼容包

2、生命周期:

Fragment拥有自己的生命周期,与Activity很相似

图片

  • onAttach(): fragment实例被关联到活动实例。fragment和activity还没有完全初始化。通常,你在该方法中获取到活动的引用,在fragment将来的初始化工作中被使用。
  • onCreate(): 当创建fragment时,系统调用该方法。你需要初始化一些fragment的必要组件。这些组件是当fragment被暂停、停止时需要保留的,以便被恢复。
  • onCreateView(): 当fragment将要第一次绘制它的用户界面时系统调用该方法。为了绘制fragment的UI,你需要从该方法中返回一个代表fragment根布局的View组件。如果该fragment不提供用户界面,直接返回null。
  • onActivityCreated: 当宿主活动被创建,在onCreateView()方法之后调用该方法。activity和fragment实例与activity的视图层级被创建。这时,视图可以通过findViewById()方法来访问。在这个方法中,你可以实例化需要Context对象的对象。
  • onStart(): fragment可见时调用该方法。
  • onResume(): fragment可交互时调用该方法。
  • onPause(): 当首次表明用户将要离开fragment时系统调用该方法。通常,这里你需要提交任何的会超出用户会话的持久化的变化。
  • onStop(): fragment将要被停止时调用。
  • onDestroyView(): 调用该方法后,fragment将要被销毁。
  • onDestroy(): 该方法被用来清理fragment的状态。

当fragment被创建时则会依次执行:onAttach() ——> onCreate() ——> onCreateView() ——> onActivityCreate()

当fragment对用户可见时会依次执行:onStart() ——> onResume()

当fragment进入后台运行时会依次执行:onPause() ——>  onStop()

当fragment被销毁时(或者持有该fragment的activity被销毁时)会依次执行:

onPause() ——> onStop() ——> onDestroyView() ——> onDestroy() ——> onDetach()

当屏幕灭掉时会依次执行:onPause() ——> onSaveInstanceState() ——> onStop()

 当屏幕解锁时会依次执行:onStart() ——> onResume()

切换到其他fragment时会依次执行:onPause() ——> onStop() ——> onDestroyView()

切换到本身fragment时会依次执行:onCreateView() ——> onActivityCreate() ——> onStart() ——> onResume()

回到桌面会依次执行:onPause() ——> onSaveInstanceState() ——> onStop()

回到应用会依次执行:onStart() ——> onResume()

退出应用会依次执行:onPause() ——> onStop() ——> onDestroyView() ——> onDestroy() ——> onDetach()

3、具体使用

由于fragment是Activity的一部分,所以fragment都是在Activity中添加,将fragment添加到Activity中有两种办法:

(a)在Activity的layout.xml文件中静态添加

(b)在Activity的.java文件中动态添加

方法1:静态添加:

第一步:Activity的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

// 该fragment类定义在包名为"com.skywang.app"中的FragmentLayoutTest类的内部类ExampleFragment中
   <fragment android:name="com.skywang.app.FragmentLayoutTest$ExampleFragment"
        android:id="@+id/list"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
  
</LinearLayout>

第二步:Fragment的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:text="@string/example_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
   
</LinearLayout>

第三步:Activity的.Java文件

// 在Activity使用Fragment时,需要考虑版本兼容问题
// 1. Android 3.0后,Activity可直接继承自Activity,并且在其中嵌入使用Fragment
// 2. Android 3.0前,Activity需FragmentActivity(其也继承自Activity),同时需要导入android-support-v4.jar兼容包,这样在Activity中才能嵌入Fragment

public class FragmentLayoutTest extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_layout_test);
        // 设置上述布局文件
    }

    // 继承自Fragment
    // 布局文件中的Fragment通过该FragmentLayoutTest的内部类ExampleFragment实现
    public static class ExampleFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            
            return inflater.inflate(R.layout.example_fragment, container, false);
             // 将example_fragment.xml作为该Fragment的布局文件
            // 即相当于FragmentLayoutTest直接调用example_fragment.xml来显示到Fragment中
        }
    }
}

方法2:动态添加

第一步:在Activity的layout.xml文件中添加占位控件(FragmeLayout),这样做的好处是可以在Activity中添加不同的Fragment,更加灵活

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    
    <FrameLayout
        android:id="@+id/about_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    
</LinearLayout>

第二步:设置Fragment的布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:text="@string/example_fragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
   
</LinearLayout>

 第三步:在Activity的.java文件中动态添加fragment

public class FragmentTransactionTest extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_transaction_test);
        
        // 步骤1:获取FragmentManager
        FragmentManager fragmentManager = getFragmentManager();

        // 步骤2:获取FragmentTransaction        
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        
        // 步骤3:创建需要添加的Fragment :ExampleFragment
        ExampleFragment fragment = new ExampleFragment();

        // 步骤4:动态添加fragment
        // 即将创建的fragment添加到Activity布局文件中定义的占位符中(FrameLayout)
        fragmentTransaction.add(R.id.about_fragment_container, fragment);
        fragmentTransaction.commit();
    }
    
    // 继承与Fragment
    public static class ExampleFragment extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            
            return inflater.inflate(R.layout.example_fragment, container, false);
            // 将example_fragment.xml作为该Fragment的布局文件
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值