从XML到Compose的UI变革:现代(2026)Android开发指南

博主2017年之前也开发android应用,如今业余兴趣玩鸿蒙了。现在再看如今的android开发,前后对比,像是完全变了个样。博主之前还吐槽android界面的xml页面写起来像是开老爷车,现在看起来android开发也变得简单了,是变得更好了。这样的UI写起来才更现代和符合主流。接下来介绍分享下从XML到Compose:现代Android开发指南,分享给有需要的小伙伴。

对于2017年之前涉足Android开发的开发者而言,如今的开发生态堪称"脱胎换骨"。当年主流的XML布局+Data Binding、Java主导开发的模式,早已被以Kotlin为核心、Jetpack Compose声明式UI为载体的现代开发体系所重塑。

本文将深度解析2017年后Android开发的核心变革,拆解现代技术栈,并通过实战demo与项目搭建教程,帮你快速衔接新时代的开发节奏。

一、核心变革:Android开发的"改朝换代"

2017年至今,Google通过推出MAD(Modern Android Development)理念,完成了从开发语言、UI构建到架构设计的全链路革新。其中最直观的变化,莫过于"告别XML"与"Kotlin优先"两大核心转变。

1.1 从XML到声明式UI:Jetpack Compose的颠覆

2017年前后,XML是Android布局的唯一主流选择,开发者需在XML中定义界面结构,再通过findViewById或Data Binding关联业务逻辑,不仅存在"布局与逻辑分离不彻底""控件更新繁琐"等问题,还需应对布局层级嵌套导致的性能损耗。

1.1.1 Jetpack Compose是什么

Jetpack Compose 是用于构建原生 Android 界面的新工具包。它使用更少的代码、强大的工具和直观的 Kotlin API,可以帮助开发者简化并加快 Android 界面开发。

在此之前,我们如何实现一个功能呢?我们是在Activity中编写Java/Kotlin的代码,在XML中编写布局代码,这种方式是我们已经使用了很久的方式,而Jetpack Compose完全抛弃了之前的方式,新创造了一种"使用代码"编写页面的方式,而这种方式,有一个好听的名字,叫做声明式UI。

Jetpack Compose作为Google推出的声明式UI工具包,彻底打破了这一模式------它允许开发者直接使用Kotlin代码描述UI,通过"状态驱动视图"的核心逻辑,实现UI的自动刷新与高效维护。无需再编写繁琐的XML文件,也无需手动绑定控件,开发效率与代码可读性大幅提升。

Google 推出的现代化 Android 声明式 UI 工具包,其首次公开时间为 ‌2019 年‌,在当年的 Google I/O 大会上正式公布。2021 年 7 月‌:正式发布 1.0.0 稳定版本,可用于生产环境开发。

kotlin 复制代码
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Compose01Theme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Row() {
        Text(text = "Hello $name!")
        Text(text = "First Compose Demo",
            modifier = Modifier
                .padding(10.dp)
                .background(Color.Red)
                .clickable {
                    //click 
                })
    }
}

@Composable
fun More(title:String) {
    Row(modifier = Modifier
        .background(Color.Red)
        .padding(10.dp)
    ) {
        Text(text = title,
            fontSize = 16.sp, color = Color.White, modifier = Modifier.weight(1f)
        )
        Button(onClick = { }) {
            Text(text = "查看详情", color = Color.White)
        }
    }
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    Compose01Theme {
        Greeting("Android")
    }
}

1.1.2 Jetpack Compose的革命性意义

Jetpack Compose的诞生标志着Android UI开发进入"声明式时代"。

相较于传统XML布局+View体系的命令式编程,Compose通过纯Kotlin代码实现UI描述,具有三大核心优势:

  1. 声明式UI模型:开发者只需描述"UI应该是什么样子",系统自动处理状态变化到UI更新的映射。例如实现一个计数器,传统方式需要findViewById后修改TextView内容,而Compose中只需声明
    Text(count.toString()) ,状态变化会自动触发UI刷新。
  2. 组件化架构:每个Composable函数都是独立可复用的UI单元,支持嵌套组合。如 Button(onClick = { ... })
    { Text("Click me") } 将逻辑与UI无缝融合,避免了Fragment的复杂生命周期管理。
  3. 响应式数据流:通过 State 和 remember 实现数据驱动UI,配合 collectAsState
    可轻松集成Flow/RxJava等响应式库。测试显示,Compose的列表渲染性能比RecyclerView提升30%以上(Google
    I/O 2021数据)。

1.2 从Java到Kotlin:官方钦定的"第一语言"

2019年,Google正式宣布"Kotlin优先",标志着Java在Android开发中的主导地位被取代。尽管Java目前仍被支持,但所有新的Jetpack库、官方示例及新特性(如协程、Flow)均优先适配Kotlin。Kotlin的空安全特性的能大幅减少空指针崩溃,简洁的语法(如扩展函数、Lambda表达式)能显著减少模板代码,让开发者更专注于业务逻辑而非语法细节。

1.3 其他核心变革:异步、注入与架构的升级

除了语言与UI,异步处理、依赖注入与架构设计也发生了根本性变化:

  • 异步处理:取代了复杂的AsyncTask与RxJava,协程(Coroutines)+ Flow成为主流,实现更简洁、可预测的异步编程;

  • 依赖注入:Hilt作为基于Dagger 2的官方简化版本,成为标准化方案,无需手动编写繁琐的Dagger组件,实现依赖的自动注入;

  • 架构设计:MVVM(Model-View-ViewModel)或MVI(Model-View-Intent)成为主流,配合ViewModel库实现数据持久化,与Compose完美适配。

二、现代Android开发技术栈(2026标准)

一个标准的现代Android项目,需围绕"Kotlin+Compose"构建全链路技术栈,以下是2026年行业主流的"黄金技术栈":

技术维度 推荐工具/库 核心作用
编程语言 Kotlin 空安全、简洁语法,官方优先支持
UI框架 Jetpack Compose(Material 3) 声明式UI,支持动态配色与多设备适配
异步处理 Coroutines + Flow 异步编程与响应式流处理
依赖注入 Hilt 官方标准化DI方案,简化依赖管理
架构模式 MVVM/MVI + Clean Architecture 解耦逻辑与UI,提升可测试性
网络请求 Retrofit + OkHttp 行业标准的网络交互方案
本地存储 Room + DataStore SQLite抽象层,支持Flow衔接
工程化 多模块化 + Gradle Kotlin DSL 提升编译速度与团队协作效率

三、实战Demo:新旧开发模式对比

下面通过"Hello World"与"登录页面"两个核心场景,直观对比2017年传统模式与现代模式的开发差异。

3.1 基础场景:Hello World

传统模式(XML + Java/Kotlin)

第一步:编写XML布局文件(activity_main.xml)

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:gravity="center">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="20sp"/>

</LinearLayout>
      

第二步:在Activity中绑定并更新控件(MainActivity.kt)

kotlin 复制代码
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 手动绑定控件
        val textView = findViewById<TextView>(R.id.textView)
        // 手动更新文本
        textView.text = "Hello Modern Android!"
    }
}
      

现代模式(Jetpack Compose + Kotlin)

无需XML文件,直接用Kotlin代码编写UI,通过Composable函数定义界面:

kotlin 复制代码
// MainActivity.kt
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 直接在setContent中编写UI
        setContent {
            // 应用主题(Material 3)
            MaterialTheme {
                // 调用Composable函数
                Greeting(name = "Modern Android")
            }
        }
    }
}

// 声明式UI组件,可复用
@Composable
fun Greeting(name: String) {
    // 类似函数调用的方式组合UI
    Text(
        text = "Hello $name!",
        modifier = Modifier
            .fillMaxSize()
            .wrapContentSize(Alignment.Center),
        fontSize = 20.sp
    )
}
      

核心优势:无需维护XML与控件绑定,UI与逻辑在同一文件中,状态变化时Compose自动刷新文本。

3.2 核心场景:登录页面(现代模式完整实现)

基于MVVM架构+Compose+协程实现,包含状态管理、点击事件处理等核心功能。

第一步:定义UI状态类(LoginUiState.kt)

kotlin 复制代码
// 存储登录页面的所有UI状态
data class LoginUiState(
    val username: String = "",
    val password: String = "",
    val isLoading: Boolean = false,
    val loginSuccess: Boolean = false,
    val errorMsg: String? = null
)
      

第二步:实现ViewModel(LoginViewModel.kt)

kotlin 复制代码
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch

class LoginViewModel : ViewModel() {
    // 私有可变状态流(仅ViewModel内部可修改)
    private val _uiState = MutableStateFlow(LoginUiState())
    // 公开不可变状态流(UI层仅可观察)
    val uiState = _uiState.asStateFlow()

    // 用户名输入变化回调
    fun onUsernameChange(username: String) {
        _uiState.value = _uiState.value.copy(username = username)
    }

    // 密码输入变化回调
    fun onPasswordChange(password: String) {
        _uiState.value = _uiState.value.copy(password = password)
    }

    // 登录按钮点击事件(协程处理异步逻辑)
    fun onLoginClick() {
        viewModelScope.launch {
            // 1. 开始加载,清空错误信息
            _uiState.value = _uiState.value.copy(
                isLoading = true,
                errorMsg = null,
                loginSuccess = false
            )

            // 2. 模拟网络请求(异步操作)
            delay(1500)

            // 3. 验证与结果处理
            val currentState = _uiState.value
            if (currentState.username.isEmpty() || currentState.password.isEmpty()) {
                _uiState.value = currentState.copy(
                    isLoading = false,
                    errorMsg = "用户名或密码不能为空"
                )
            } else {
                _uiState.value = currentState.copy(
                    isLoading = false,
                    loginSuccess = true
                )
            }
        }
    }
}
      

第三步:实现Compose UI(LoginScreen.kt)

kotlin 复制代码
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel

@Composable
fun LoginScreen(
    viewModel: LoginViewModel = viewModel(), // 自动注入ViewModel
    onLoginSuccess: () -> Unit = {} // 登录成功回调
) {
    // 观察ViewModel中的状态流,自动响应状态变化
    val uiState by viewModel.uiState.collectAsState()

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        // 用户名输入框
        OutlinedTextField(
            value = uiState.username,
            onValueChange = { viewModel.onUsernameChange(it) },
            label = { Text("用户名") },
            modifier = Modifier.fillMaxWidth()
        )

        Spacer(modifier = Modifier.height(16.dp))

        // 密码输入框
        OutlinedTextField(
            value = uiState.password,
            onValueChange = { viewModel.onPasswordChange(it) },
            label = { Text("密码") },
            modifier = Modifier.fillMaxWidth()
        )

        Spacer(modifier = Modifier.height(24.dp))

        // 登录按钮(加载状态时禁用并显示进度条)
        Button(
            onClick = { viewModel.onLoginClick() },
            enabled = !uiState.isLoading,
            modifier = Modifier.fillMaxWidth()
        ) {
            if (uiState.isLoading) {
                CircularProgressIndicator(
                    modifier = Modifier.height(24.dp).width(24.dp),
                    strokeWidth = 2.dp,
                    color = MaterialTheme.colorScheme.onPrimary
                )
            } else {
                Text("登录")
            }
        }

        // 错误信息提示
        uiState.errorMsg?.let { errorMsg ->
            Spacer(modifier = Modifier.height(16.dp))
            Text(
                text = errorMsg,
                color = MaterialTheme.colorScheme.error
            )
        }

        // 登录成功回调
        if (uiState.loginSuccess) {
            onLoginSuccess()
        }
    }
}
      

第四步:在Activity中使用LoginScreen

kotlin 复制代码
@AndroidEntryPoint // Hilt依赖注入注解
class LoginActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                LoginScreen(
                    onLoginSuccess = {
                        // 登录成功,跳转首页
                        startActivity(Intent(this, HomeActivity::class.java))
                        finish()
                    }
                )
            }
        }
    }
}
      

四、新旧项目衔接:XML项目迁移到Compose

对于2017年前后的旧项目,无需推倒重来,Google提供了完善的互操作性方案,支持XML与Compose混合使用,实现平滑迁移。迁移可分为四个阶段逐步推进:

4.1 第一阶段:环境准备

在项目级与模块级build.gradle.kts中开启Compose支持并引入依赖(以Kotlin DSL为例):

kotlin 复制代码
// 模块级build.gradle.kts
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
}

android {
    compileSdk = 35

    buildFeatures {
        compose = true // 开启Compose支持
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.x" // 需与Kotlin版本匹配
    }
}

dependencies {
    // Compose核心依赖
    implementation(libs.compose.ui)
    implementation(libs.compose.material3)
    implementation(libs.compose.ui.tooling.preview)
    debugImplementation(libs.compose.ui.tooling)
}
      

4.2 第二阶段:在XML中嵌入Compose(自下而上)

保留外层XML布局,将其中的单个子View(如按钮、卡片)替换为Compose组件,适合初次迁移尝试:

  1. 在XML中添加ComposeView占位符:
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">

    <!-- 原有XML控件 -->
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="旧XML布局"/>

    <!-- Compose占位符 -->
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/my_compose_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>
      
  1. 在Activity/Fragment中渲染Compose内容:
kotlin 复制代码
class MyActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_my)
        
        val composeView = findViewById<ComposeView>(R.id.my_compose_view)
        composeView.setContent {
            // 渲染Compose组件
            MyComposeButton(onClick = { /* 点击事件处理 */ })
        }
    }
}

// Compose组件
@Composable
fun MyComposeButton(onClick: () -> Unit) {
    Button(onClick = onClick) {
        Text("Compose按钮")
    }
}
      

4.3 第三阶段:将整个页面迁移到Compose

当单个组件迁移稳定后,可直接移除XML文件,将整个页面替换为Compose实现:

kotlin 复制代码
// Fragment示例(Activity类似)
class HomeFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        // 直接返回ComposeView,无需加载XML
        return ComposeView(requireContext()).apply {
            setContent {
                MaterialTheme {
                    HomeScreen() // 完整Compose页面
                }
            }
        }
    }
}

@Composable
fun HomeScreen() {
    Column(modifier = Modifier.fillMaxSize()) {
        Text("完整Compose页面")
        // 其他Compose组件...
    }
}
      

4.4 第四阶段:在Compose中复用旧XML View

若存在第三方库(如地图、旧版图表)暂无Compose版本,可通过AndroidView包裹旧View复用:

kotlin 复制代码
@Composable
fun LegacyViewIntegration() {
    AndroidView(
        // 初始化旧View
        factory = { context ->
            TextView(context).apply {
                text = "我是旧XML View"
                textSize = 18f
            }
        },
        // 状态变化时更新旧View
        update = { view ->
            view.text = "Compose状态驱动更新"
        }
    )
}
      

五、从零搭建现代Android项目(2026版)

搭建全新项目时,需遵循"多模块化+MAD架构"原则,以下是完整搭建流程:

5.1 项目创建(Android Studio)

  1. 打开Android Studio → File → New → New Project;

  2. 选择"Empty Compose Activity"模板(默认集成Compose,无XML布局);

  3. 配置参数:

    • Language:Kotlin(Compose仅支持Kotlin);

    • Minimum SDK:API 24+(推荐,兼容绝大多数设备,Compose最低支持API 21);

    • Build Configuration Language:Kotlin DSL(build.gradle.kts);

    • 项目名称:ModernAndroidDemo。

5.2 项目结构设计(多模块化)

现代项目推荐多模块化结构,按功能与职责拆分模块,提升编译速度与可维护性,标准结构如下:

5.3 核心模块配置(关键代码)

1. 版本统一管理(gradle/libs.versions.toml)

bash 复制代码
[versions]
kotlin = "2.2.20"
compose = "1.9.3"
compose-material = "1.4.0"
hilt = "2.57.2"
retrofit = "3.0.0"
room = "2.6.1"

[libraries]
# Compose
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
compose-material3 = { module = "androidx.compose.material3:material3", version.ref = "compose-material" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }

# Hilt
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }

# 网络
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version = "4.12.0" }

# 本地存储
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
      

2. 主模块配置(app/build.gradle.kts)

kotlin 复制代码
plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.dagger.hilt.android")
    kotlin("kapt")
}

android {
    namespace = "com.example.modernandroiddemo"
    compileSdk = 35

    defaultConfig {
        applicationId = "com.example.modernandroiddemo"
        minSdk = 24
        targetSdk = 35
        versionCode = 1
        versionName = "1.0"
    }

    buildFeatures {
        compose = true
        viewBinding = false // 无需ViewBinding,Compose已替代
    }

    composeOptions {
        kotlinCompilerExtensionVersion = libs.versions.compose.get()
    }

    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8
    }

    kotlinOptions {
        jvmTarget = "1.8"
    }
}

dependencies {
    // 核心依赖
    implementation(libs.compose.ui)
    implementation(libs.compose.material3)
    debugImplementation(libs.compose.ui.tooling)
    
    // Hilt
    implementation(libs.hilt.android)
    kapt(libs.hilt.compiler)
    
    // 业务模块依赖
    implementation(project(":feature:feature-login"))
    implementation(project(":feature:feature-home"))
    
    // 核心基础模块依赖
    implementation(project(":core:core-common"))
    implementation(project(":core:core-network"))
}

// Hilt注解处理器配置
kapt {
    correctErrorTypes = true
}
      

3. 应用类配置(App.kt)

kotlin 复制代码
import android.app.Application
import dagger.hilt.android.HiltAndroidApp

// Hilt全局注入注解,必须在Application类上添加
@HiltAndroidApp
class App : Application() {
    override fun onCreate() {
        super.onCreate()
        // 全局初始化操作(如日志、网络配置等)
    }
}
      

4. 清单文件配置(AndroidManifest.xml)

xml 复制代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.modernandroiddemo">

    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.ModernAndroidDemo">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

六、总结与进阶趋势

6.1 核心总结

2017年至今,Android开发的核心变革可概括为"三个转变":

  • 开发语言:从Java主导到Kotlin优先,空安全与简洁性成为核心优势;

  • UI构建:从XML imperative布局到Compose声明式UI,状态驱动替代手动更新;

  • 架构理念:从单一模块到多模块化+Clean Architecture,解耦与可维护性成为核心目标。

现代Android开发的终极标准栈可浓缩为:Kotlin + Jetpack Compose + Hilt + MVVM/MVI + 多模块化 + Gradle Kotlin DSL

6.2 进阶趋势(2026+)

未来Android开发将向"跨平台"与"工程化深化"两大方向演进:

  • Kotlin Multiplatform(KMP):实现Android与iOS共享业务逻辑,甚至通过Compose Multiplatform共享UI,大幅降低跨平台开发成本;

  • AI辅助开发:Android Studio的AI功能(如Codey)将深度集成,自动生成Compose代码、优化布局与逻辑;

  • 工程化升级:Buildless构建、动态功能模块(App Bundle)、CI/CD自动化将成为标准配置。

过去几年 Android 架构经历了从 MVC → MVP → MVVM → Clean Architecture 的演进。到了 2026 年,官方推荐的现代架构已经非常明确:

Kotlin + Jetpack Compose + Hilt + Clean Architecture + Gradle Kotlin DSL + 多模块化

这种结构不仅提升构建速度与维护性,还能让团队多人并行开发更加高效。

对于老开发者而言,无需恐惧变革------Compose与旧技术栈的互操作性、Google完善的迁移文档,都能让你平滑过渡。拥抱Kotlin与Compose,你将发现Android开发变得更简洁、更高效、更具乐趣。

参考链接

https://developer.android.com/codelabs/basic-android-kotlin-compose-first-app

https://blog.csdn.net/qq_42698421/article/details/153392719

https://blog.csdn.net/FDoubleman/article/details/156735424

https://blog.csdn.net/chenyiran123456/article/details/147026101

https://cloud.tencent.com/developer/article/2378444

https://developer.aliyun.com/article/1409238

https://github.com/compose-museum/WithCompose

https://developer.android.com/courses/android-basics-compose/course?hl=zh-cn

相关推荐
微祎_2 小时前
Flutter for OpenHarmony:构建一个 Flutter 单词拼图游戏,深入解析状态驱动 UI、交互式字母操作与教育类应用设计
javascript·flutter·ui
xiangxiongfly9152 小时前
Android 共享元素转场效果
android·动画·共享元素转场效果
我是阿亮啊2 小时前
Android 中线程和进程详解
android·线程·进程·进程间通信
FuckPatience2 小时前
WPF xaml中的 xmlns:d=“http://schemas.microsoft.com/expression/blend/2008“ 的使用
ui·wpf
我命由我123453 小时前
Android 开发问题:Duplicate class android.support.v4.app.INotificationSideChannel...
android·java·开发语言·java-ee·android studio·android-studio·android runtime
似霰3 小时前
Android 平台智能指针使用与分析
android·c++
有位神秘人3 小时前
Android中BottomSheetDialog的折叠、半展开、底部固定按钮等方案实现
android
LeeeX!3 小时前
YOLOv13全面解析与安卓平台NCNN部署实战:超图视觉重塑实时目标检测的精度与效率边界
android·深度学习·yolo·目标检测·边缘计算
dongdeaiziji3 小时前
Android 图片预加载和懒加载策略
android