前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >安卓软件开发:实现高级布局顺序App的技术难点

安卓软件开发:实现高级布局顺序App的技术难点

原创
作者头像
Nimyears
修改2024-10-30 14:42:30
530
修改2024-10-30 14:42:30
举报
文章被收录于专栏:JetpackCompose M3玩转全栈

2024年已过半,作为一名聋人独立开发者,我经常反思自己这半年来的进步。我全身心投入到Jetpack Compose和Java的学习与实践中,开发了一个利用Jetpack Compose、Kotlin和Java实现高级布局顺序的App。本文记录了这个过程中解决布局顺序和重叠效果的经验,希望给有一定经验的开发者带来启发。

在安卓软件开发中,布局设计影响界面的美观性,还会直接影响用户体验。尤其在满足产品原型需求时,复杂布局的实现可能会遇到一些挑战。本文将通过实际场景,展示如何实现复杂布局顺序及布局重叠效果。

一、需求分析

如图所示,产品原型需求中存在多层次的布局顺序,比如中间红色区域(区域3)需要覆盖在其他灰色区域(区域1、2、4、5)之上。这种布局顺序对开发来说是一个非常大挑战,因为需要控制每个区域的重叠顺序和位置,确保不同设备上显示一致。

二、实现思路

在安卓开发中,可以通过FrameLayout LinearLayout 等容器控制布局顺序。FrameLayout的子视图会按添加顺序层叠,因此它非常适合用于实现层次分明的布局需求。具体实现过程中,我会使用布局偏移marginoffset)微调各区域的位置。

三、布局实现:XML代码示例

以下代码展示了如何利用XML布局文件实现目标效果。各个区域(区域1至区域5)根据需求依次叠放,调整了布局顺序和位置。

3.1 设计代码

代码语言:xml
复制

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <!--TODO 区域1-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/image2"/>
        
        <!--TODO 区域2-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-30px"
            android:background="@drawable/image1"/>
        
        <!--TODO 区域3-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-30px"
            android:background="@drawable/m_image"/>
        
        <!--TODO 区域4-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-30px"
            android:background="@drawable/image1"/>
        
        <!--TODO 区域5-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-30px"
            android:background="@drawable/image2"/>
        
    </LinearLayout>



</FrameLayout>

3.1.1 效果图

3.1.2 解释代码

  • 布局顺序:在LinearLayout中添加视图是从左到右,因此在代码中声明的顺序决定了它们在屏幕上的排列顺序。
  • 位置微调:使用layout_marginStart调整各个区域的位置,保证它们在视觉上轻微重叠,从而实现统一的视觉效果。
  • 背景颜色对比:不同区域使用了不同的颜色或背景图资源,符合产品设计图的视觉要求。

接下来继续优化

3.2 优化中间区域的布局

通过将中间红色区域放在FrameLayout的最外层,可以确保红色区域覆盖在其他区域之上,以下是优化后的代码:

代码语言:xml
复制
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue"
    android:gravity="center">

    <!-- 布局 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:gravity="center">

        <!-- 区域1 -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-630px"
            android:background="@drawable/image2" />

        <!-- 区域2 -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-50px"
            android:background="@drawable/image1" />
    </LinearLayout>

    <!-- 中间红色区域3覆盖在其他区域上 -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="-180px"
        android:background="@drawable/m_image" />

    <!-- 布局-2 -->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <!-- 区域4 -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-60px"
            android:background="@drawable/image1" />

        <!-- 区域5 -->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-40px"
            android:background="@drawable/image2" />
    </LinearLayout>
</FrameLayout>

还是不行,想到了唯一方法是红色区域可以放在最外层的布局。

代码语言:xml
复制
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="-180px"
        android:background="@drawable/m_image" />

经过后调整了红色区显示正确,可是右侧黑色区域顺序显示不对,应该要先解决它

尝试多写了外层加一个布局顺序

代码语言:xml
复制
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    android:background="@color/blue"
    android:gravity="center"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:gravity="center"
            android:orientation="horizontal">

            <!--TODO 区域1-->
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="-630px"
                android:background="@drawable/image2" />
            <!--TODO 区域2-->
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="-50px"
                android:background="@drawable/image1" />
        </LinearLayout>
    </LinearLayout>


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="horizontal">

        <!--TODO 区域4-->
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="-60px"
            android:background="@drawable/image1" />

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">

            <!--TODO 区域5-->
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center|end"
                android:layout_marginStart="-40px"
                android:background="@drawable/image2" />
        </LinearLayout>
    </LinearLayout>
    <!--TODO 区域3-->
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginStart="-180px"
        android:background="@drawable/m_image" />
</FrameLayout>

终于搞定了 )

3.2.2 最终效果图

3.2.3 TODO层次结构

四、XML的关键技术点

  1. FrameLayout层叠效果:FrameLayout的子视图是按声明顺序层叠的,因此在XML布局文件中,红色区域3在其他区域之后声明,从而覆盖在它们之上。
  2. LinearLayout的布局偏移:通过layout_marginStart实现各个区域的偏移,很好控制它们在屏幕上的精确位置。
  3. 中心对齐:使用layout_gravity="center"确保中间的红色区域3位于布局中心。

五、使用Jetpack Compose的实现

以下是Jetpack Compose的代码实现方式且支持动态布局调整。Compose提供了offset函数轻松实现元素的偏移定位。

代码语言:kotlin
复制
@Composable
fun MainScreen() {
    Surface(
        color = Color.Blue,
        modifier = Modifier.fillMaxSize()
    ) {
        Box(
            contentAlignment = Alignment.Center,
            modifier = Modifier.fillMaxSize()
        ) {
            // 区域1
            Image(
                painter = painterResource(id = R.drawable.image2),
                contentDescription = null,
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset(x = (-630).dp)
            )

            // 区域2
            Image(
                painter = painterResource(id = R.drawable.image1),
                contentDescription = null,
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset(x = (-50).dp)
            )

            // 中间区域3
            Image(
                painter = painterResource(id = R.drawable.m_image),
                contentDescription = null,
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset(x = (-180).dp)
            )

            // 区域4
            Image(
                painter = painterResource(id = R.drawable.image1),
                contentDescription = null,
                modifier = Modifier
                    .align(Alignment.Center)
                    .offset(x = (-60).dp)
            )

            // 区域5
            Image(
                painter = painterResource(id = R.drawable.image2),
                contentDescription = null,
                modifier = Modifier
                    .align(Alignment.CenterEnd)
                    .offset(x = (-40).dp)
            )
        }
    }
}

六、技术难点解析

  • 布局顺序的控制:在FrameLayout和Box中,子视图按添加顺序层叠显示。为了控制叠放顺序,要仔细规划各视图的声明顺序,确保中心区域在最后声明以覆盖其他区域。
  • 动态调整:Compose在运行时通过Modifieroffset动态调整布局位置,相比传统的XML布局更加灵活,有利于响应需求变化。

七、总结

实现复杂布局顺序时,理解布局容器的特性是关键。FrameLayout和LinearLayout可以很好控制布局顺序和重叠关系,而Jetpack Compose则提供了更简便的动态布局控制方式。通过上述技术点,开发者可以灵活满足产品原型的复杂需求,实现更具层次感的高级布局效果。

八、实战

谢谢大家阅读)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、需求分析
  • 二、实现思路
  • 三、布局实现:XML代码示例
    • 3.1 设计代码
      • 3.1.1 效果图
        • 3.1.2 解释代码
          • 3.2 优化中间区域的布局
            • 3.2.2 最终效果图
              • 3.2.3 TODO层次结构
              • 四、XML的关键技术点
              • 五、使用Jetpack Compose的实现
              • 六、技术难点解析
              • 七、总结
              • 八、实战
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档