Android官方开发文档Training系列课程中文版:使用Fragment构建动态UI之构建灵活的UI

简介: 原文地址:http://android.xsoftlab.net/training/basics/fragments/fragment-ui.html当设计应用程序时需要支持尺寸较大的宽屏设备时,可以基于可用的屏幕空间在不同的布局中配置并重新使用fragment来提升用户体验。

原文地址:http://android.xsoftlab.net/training/basics/fragments/fragment-ui.html

当设计应用程序时需要支持尺寸较大的宽屏设备时,可以基于可用的屏幕空间在不同的布局中配置并重新使用fragment来提升用户体验。

举个例子,手持设备在同一时间可能只适合展示一个界面,相反的,你可能希望在平板设备上一边一个Fragment,因为平板有更宽的界面用来展示更多的信息。


上图中:两个Fragment,利用同一个Activity在不同的屏幕尺寸中展示出不同的界面效果。在大屏幕中,两个fragment一边一个,但是在手持设备上,只能在同一时间内放置一个fragment,所以只能在用户使用的时候使用替换的方式来展示另一个fragment。

类FragmentManager支持在运行时添加、删除、替换fragment,以便提供更灵活的体验。

在运行时添加Fragment到Activity中

正如上节课展示的那样,我们可以通过在布局文件中添加< fragment>标签的方式定义fragment,不过,我们还可以在activity运行的时候添加fragment到activity中。如果你计划在activity的生命周期内改变fragment的话,那么这项功能就很有必要了。

如果要执行类似添加、删除fragment的这种事务,必须通过使用FragmentManager创建一个事务对象FragmentTransaction,它提供了添加、删除、替换和其它fragment相关事务的功能。

如果activity允许fragment可以移除或者替换,那么必须在onCreate方法内初始化fragment并添加到activity中。

在处理fragment的时候有很重要的一条规则,尤其是在添加fragment的时候,就是activity必须包含一个容器View对象,以便fragment对象可以添加到这个容器中。

下面这个布局就是上一节课同时只显示一个fragment更改过后的布局,为了可以替换fragment,activity的布局需要包含一个空的FrameLayout,当做fragment的容器。

注意,文件的名称还是和上节课中布局的名字相同,但是布局的文件夹目录名称则不再包含”large”标识符,所以这个布局是在比”large”小的设备屏幕上使用的,因为这种屏幕不适合同时显示多个fragment。

res/layout/news_articles.xml:

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

在activity中调用getSupportFragmentManager()方法获得支持库中的FragmentManager对象,然后调用这个对象的beginTransaction()方法创建FragmentTransaction事务对象,通过这个事务对象的add()方法添加fragment。

你还可以使用FragmentTransaction事务对象执行多个fragment的事务。当准备确认要应用这些改变是,你应该调用commit()方法。

举个例子,下面这段代码展示了如何在上面的布局中添加fragment:

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_articles);
        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (findViewById(R.id.fragment_container) != null) {
            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }
            // Create a new Fragment to be placed in the activity layout
            HeadlinesFragment firstFragment = new HeadlinesFragment();

            // In case this activity was started with special instructions from an
            // Intent, pass the Intent's extras to the fragment as arguments
            firstFragment.setArguments(getIntent().getExtras());

            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment).commit();
        }
    }
}

因为fragment在运行时被添加到了FrameLayout中,所以activity可以使用另一个不同的fragment来替换它,或者可以移除它。

替换Fragment

替换fragment的过程和添加的过程很相似,只是需要使用replace()方法而不是add()方法。

记住,在执行fragment事务的时候,比如替换或者移除,经常需要适当的允许用户可以通过返回撤销改变。为了通过fragment事务允许用户做到这一点,必须在FragmentTransaction事务提交之前调用addToBackStack()方法。

Note:当你通过移除或者替换将fragment作为事务添加到回退栈的时候,那个被移除的fragment会进入停止状态(没有被销毁)。如果用户通过返回还原了fragment,那么它就会重新启动。如果没有添加事务到回退栈,那么fragment在移除或者替换的时候会被销毁。

这是个替换fragment的例子:

// Create fragment and give it an argument specifying the article it should show
ArticleFragment newFragment = new ArticleFragment();
Bundle args = new Bundle();
args.putInt(ArticleFragment.ARG_POSITION, position);
newFragment.setArguments(args);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();

addToBackStack()方法有一个可选的字符串参数,这个参数可以用来指定事务的唯一标示名称。这个名称不是必须的,除非你计划通过FragmentManager.BackStackEntry API执行更佳的fragment操作。

目录
相关文章
|
2月前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
104 3
|
2月前
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
153 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
安全 Android开发 iOS开发
Android vs. iOS:构建生态差异与技术较量的深度剖析###
本文深入探讨了Android与iOS两大移动操作系统在构建生态系统上的差异,揭示了它们各自的技术优势及面临的挑战。通过对比分析两者的开放性、用户体验、安全性及市场策略,本文旨在揭示这些差异如何塑造了当今智能手机市场的竞争格局,为开发者和用户提供决策参考。 ###
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
549 5
|
开发工具 Android开发 iOS开发
Android vs iOS:构建移动应用时的关键考量####
本文深入探讨了Android与iOS两大移动平台在开发环境、性能优化、用户体验设计及市场策略方面的差异性,旨在为开发者提供决策依据。通过对比分析,揭示两个平台各自的优势与挑战,帮助开发者根据项目需求做出更明智的选择。 ####
|
前端开发 JavaScript 测试技术
Android适合构建中大型项目的架构模式全面对比
Android适合构建中大型项目的架构模式全面对比
194 2
|
调度 Android开发 开发者
构建高效Android应用:探究Kotlin多线程优化策略
【10月更文挑战第11天】本文探讨了如何在Kotlin中实现高效的多线程方案,特别是在Android应用开发中。通过介绍Kotlin协程的基础知识、异步数据加载的实际案例,以及合理使用不同调度器的方法,帮助开发者提升应用性能和用户体验。
203 4
|
编解码 Android开发 UED
构建高效Android应用:从内存优化到用户体验
【10月更文挑战第11天】本文探讨了如何通过内存优化和用户体验改进来构建高效的Android应用。介绍了使用弱引用来减少内存占用、懒加载资源以降低启动时内存消耗、利用Kotlin协程进行异步处理以保持UI流畅,以及采用响应式设计适配不同屏幕尺寸等具体技术手段。
191 2
|
11月前
|
Java Android开发 开发者
探索安卓开发:构建你的第一个“Hello World”应用
在安卓开发的浩瀚海洋中,每个新手都渴望扬帆起航。本文将作为你的指南针,引领你通过创建一个简单的“Hello World”应用,迈出安卓开发的第一步。我们将一起搭建开发环境、了解基本概念,并编写第一行代码。就像印度圣雄甘地所说:“你必须成为你希望在世界上看到的改变。”让我们一起开始这段旅程,成为我们想要见到的开发者吧!
212 0

热门文章

最新文章