❤ Uniapp使用一(文档和 API 篇)

❤ Uniapp使用一(文档和 API 篇)

一、介绍

uni-app官网:https://uniapp.dcloud.io/api/media/image?id=previewimage
微信小程序官网:https://developers.weixin.qq.com/miniprogram/dev/api/media/image/wx.previewImage.html

二、使用

API篇

❤ API-页面和路由

uni.navigateBack 返回

进去页面触发
onShow(async () => {
	getList(1); //利用学员编号进行展示
})
uni.navigateBack({  
//uni.navigateTo跳转的返回,默认1为返回上一级
	delta: 1
});

uniapp监听页面顶部导航栏返回事件

<u-navbar title="测试" :custom-back="customBack"></u-navbar>

 methods: {
    customBack() {
      let routes = getCurrentPages()
      let lastPage = routes[routes.length - 2].route // 页面栈中的最后一个项为当前页面,route属性为页面路径
      console.log(lastPage, 'routes')
      if (lastPage === 'pagesMine/pages/equityCard/myCard') {
        uni.navigateBack()
      } else {
        uni.navigateBack({
          delta: 2,
        })
      }
    }
  },

uniapp监听从哪个页面来

var pages = getCurrentPages();//获取页面
    var beforePage = pages[pages.length - 2];//上个页面
	  if(beforePage.route=='pages/component/myreport/index'){
	  uni.getStorage({
	  	key: 'myinfo',
	  	success: function(res) {
	  	_this.form = res.data;
	  	}
	  });
  }

uniapp监听是否是返回来的

getCurrentPages().length
在onShow生命周期函数中判断是否是通过左上角返回按钮返回的

getCurrentPages().length

// 大于1,则表示当前页面不是第一个页面,即用户是通过返回按钮返回的;否则表示当前页面是第一个页面,即用户是通过路由跳转进入的。

❤ API-媒体图片

uniapp 实现图片预览 单图预览和多图预览

①单图预览

current对应就是0
urls:必须是单个某一条传入

预览一张图片,你的current传死就是0.所以urls也必须是字符串形式

@click="viewImg(item,index)"

// 缩放图片
	function viewImg(item,index){
		console.log(item.certificateImageUrl,index)
		let imgsArray = [];
		imgsArray[0] = item?.certificateImageUrl;
	      uni.previewImage({
	        current:0,
	        urls:imgsArray,
	      })
	}
②多图预览
@click="previewImage(index)"

previewImage(index) {
			let photoList = this.photos.map(item => {
				return item.src;
			});
			uni.previewImage({
				current: index,
				urls: photoList
			});
}

❤ API-媒体视频

uni.chooseVideo 选择视频

<view><button class="btnsaoma" @tap="test"  style="margin-top: 20rpx;">去视频识别分析</button></view>


<!-- 拍摄的视频部分start -->
		<uni-popup ref="popupvideo">
					<view class="guanbiclass">
						<view class="guanbiclasstop">
							请确认您拍摄的视频
						</view>
						<video :src="videosrc" style="width: 400rpx;height: 400rpx;margin: 0 115rpx;float: left;border-radius: 14rpx;margin-bottom: 60rpx;"></video>
						<view style="text-align: center;margin-top: 30rpx;">
							<button class="mini-btn" type="default" style="background-color: #0E77FF;color: #fff;" size="mini" @click="closevideo()">重拍</button>
							<button style="margin-left: 20rpx;background-color: #0E77FF;"  class="mini-btn" type="primary" size="mini"
								@click="submitvideo()">确认下一步</button>
						</view>
		
					</view>
		</uni-popup>
		
<!-- 拍摄的视频部分end -->

//方法
test: function () {
				let _this = this;
				uni.chooseVideo({
					mediaType:['video'],//类型
					sourceType: ['camera', 'album'],
					success: function (res) {
						console.log(res);
						const tempFilePathsvideo = res.tempFilePath;
						_this.videosrc = tempFilePathsvideo;
						_this.$refs.popupvideo.open('center');
						console.log(tempFilePathsvideo);
					}
				});
},


// 上传视频
uni.uploadFile({
							url: _this.$store.state.requestUrl +'', //接口地址
							filePath: _this.videosrc,
							name: 'file',
							formData: {
								'imei':'',//设备码
								'userId':_this.$store.state.userId,//用户ID(游客传0)
								'version': 2,
								'reportType':'',
								'isQueue':1,//否队列(0:等待响应报告ID;1:立即返回二维码)
								// 'file': _this.videosrc,
							},
							success: (uploadFileRes) => {
								console.log(uploadFileRes,'返回');
								console.log(uploadFileRes.data);
								// if(data.code==200){
								// 	// _this.$store.state.userId = data.data.userInfo.id;
								// 	// _this.msg = data.data;
								// }else{
								// 	uni.showToast({
								// 		title: data.msg,
								// 		icon: "none"
								// 	});
									
								// }
							}
});

保存视频 uni.saveVideoToPhotosAlbum

// 保存视频
	uni.saveVideoToPhotosAlbum({
				filePath: res.tempFilePath,
				success: function () {
				console.log('保存成功');
	}
});

uni.uploadFile(OBJECT) 上传图片、视频

媒体 /画面录制器 wx.createMediaRecorder

❤ API-界面

弹窗

uni.showActionSheet(OBJECT)(从底部向上弹出操作菜单)

需要注意的是,uni.showToast 只支持基础样式的设置,如颜色、大小、边框等。如果需要更复杂的样式,可以考虑使用自定义组件或模态框等组件来实现。

uni.showModal(OBJECT)模态框

显示模态弹窗,可以只有一个确定按钮,也可以同时有确定和取消按钮。类似于一个API整合了 html 中:alert、confirm

uni.showModal({
	title: '提示',
	content: '这是一个模态弹窗',
	success: function (res) {
		if (res.confirm) {
			console.log('用户点击确定');
		} else if (res.cancel) {
			console.log('用户点击取消');
		}
	}
});

uniapp提示弹框

// uniapp提示弹框

uni.showToast({
	title: '成功提示',
	//将值设置为 success 或者直接不用写icon这个参数
	icon: 'success',
	//显示持续时间为 2秒
	duration: 2000
})  

// 加载提示弹框
//前端数据请求时,显示加载提示弹框
uni.showLoading({
	title: '加载中...'
});
// 数据从后端接口返回后,提示弹框关闭
uni.hideLoading();


// 加载提示
uni.showModal({
		title: '提示',
		content: '确认删除该条信息吗?',
		success: function(res) {
		if (res.confirm) {
		    // 执行确认后的操作
		} 
		else {
			// 执行取消后的操作
		}
	}
})


uni.showActionSheet({
	itemList: ['选项一', '选项二', '选项三'],
	success (res) {
	   // 选择其中任意一项后,获取其索引(res.tapIndex),从0开始
	   console.log(res.tapIndex) 
	},
	fail (res) {
	   // 取消后的操作
	}
})

界面滚动

uni.pageScrollTo(OBJECT) 滚动

将页面滚动到目标位置。可以指定滚动到具体的scrollTop数值,也可以指定滚动到某个元素的位置

uni.pageScrollTo(将页面滚动到目标位置)

ID选择器:#the-id
元素: id="hexinzhibiao"

uni.pageScrollTo({
		// scrollTop: 0,
		selector:'#hexinzhibiao',
		duration: 300
});

uni.showLoading页面加载效果


//开始加载
uni.showLoading({
	title: "加载中" //为了网络慢,给用户的友好等待提示
});

//加载完成
uni.hideLoading(); //loading 弹窗end

界面动画

API-动画属性 uni.createAnimation(OBJECT)

uni.createAnimation(OBJECT) 

界面设置导航条

uni.setNavigationBarTitle() 设置当前页面的页头(导航栏标题)

如果需要在页面进入时设置标题,可以在onReady内执行,以避免被框架内的修改所覆盖。如果必须在onShow内执行需要延迟一小段时间

onReady() {
	uni.setNavigationBarTitle({
	      title: '个人基本信息表',
	});
},
		
onLoad() {
	let _this = this;
	uni.setNavigationBarTitle({
	      title: '个人基本信息表',
	});
},
custome 字断自定义底部导航栏(tabBar)的样式和行为

在 UniApp 中,custom 字段用于自定义底部导航栏(tabBar)的样式和行为。通过设置 custom: true,你可以完全自定义底部导航栏的外观和交互方式。

使用自定义 tabBar 可以实现以下功能:
改变图标和文字的颜色、大小等样式。
自定义点击切换页面的交互效果。
添加额外的按钮或组件到导航栏中。
以下是一个示例:

// JavaScript
export default {
  config: {
    tabBar: {
      custom: true,
      list: [
        {
          pagePath: 'pages/home/index',
          iconPath: 'static/images/tabbar/home.png',
          selectedIconPath: 'static/images/tabbar/home-selected.png',
          text: '首页'
        },
        {
          pagePath: 'pages/category/index',
          iconPath: 'static/images/tabbar/category.png',
          selectedIconPath: 'static/images/tabbar/category-selected.png',
          text: '分类'
        },
        {
          pagePath: 'pages/cart/index',
          iconPath: 'static/images/tabbar/cart.png',
          selectedIconPath: 'static/images/tabbar/cart-selected.png',
          text: '购物车'
        },
        {
          pagePath: 'pages/mine/index',
          iconPath: 'static/images/tabbar/mine.png',
          selectedIconPath: 'static/images/tabbar/mine-selected.png',
          text: '我的'
        }
      ]
    }
  }
}

在上述示例中,我们将 config 对象中的 tabBar.custom 设置为 true,表示启用自定义 tabBar。然后,我们可以使用 list 数组配置底部导航栏的每个按钮的样式和行为。每个按钮都包含以下属性:

pagePath:按钮对应的页面路径。
iconPath:默认状态下的图标路径。
selectedIconPath:选中状态下的图标路径。
text:按钮的文字。
通过自定义 tabBar,你可以根据项目需求设计独特的底部导航栏样式,并控制点击按钮时的页面切换行为。同时,你还可以使用自定义组件在 tabBar 中添加额外的按钮或其他元素。

注意:自定义 tabBar 仅适用于非全局导航模式(非 app-plus 平台下的 nvue 页面)。在 app-plus 平台下,底部导航栏样式将由原生操作系统提供的底部导航栏来显示。

❤ API - 数据缓存

本地数据存储

uniapp提供了一套uni存储API,可以在不同的平台上实现本地数据存储。

uni存储API包括以下几个方法:

uni.setStorage(key, value)
uni.getStorage(key)
uni.removeStorage(key)
uni.clearStorage()

使用uni存储API实现本地数据存储也很简单,只需要调用对应的存储方法即可。以下代码是将数据存储到uni存储中的实例:

// 存储数据
uni.setStorage({
  key: 'key',
  data: 'value',
  success: function () {
    console.log('数据保存成功');
  }
});

// 获取数据
uni.getStorage({
  key: 'key',
  success: function (res) {
    const data = res.data;
    console.log('获取数据成功:', data);
  },
  fail: function (err) {
    console.log(err);
  }
});

❤ API - 网络

(1)发起请求

发送接口请求数据

uni.request({
	url: '/api/familyManagement/homePage/messageProcessing',
	method: 'get',
	dataType:'json',
	data:dataps,
	success(res) {
		if (res.data.code == 200) {
			uni.showToast({
				title: res.data.msg,
				icon: 'none',
				duration:2000,
			});
			console.log(res.data,'返回1');
			_this.getList();
			_this.tiao();
		} else {
			uni.showToast({
				title: res.data.msg,
				icon: 'none',
				duration:3000,
			})
		}
	},
	complete() {
		uni.hideLoading(); //loading 弹窗end
	},
	fail(err) {
		console.log('失败:', err);
	}
})

(2)uniapp接口获取和处理文件流

主要就是将响响应的数据类型修改成 arraybuffer
默认的request请求是JSON格式
responseType: ‘arraybuffer’,我们可以设置 arraybuffer
这样就可以拿到文件流了,案例的文件流是bas64格式

uni.request({
      url: "https://xxx.xxx.cn/bank/file/xxx/aeb9beb4fb2444ff80d47ed11c18b991.jpg",
      method: 'GET',
      responseType: 'arraybuffer',
      
      success: res => {
        let datas = res.data;
        this.codeUrl =  'data:image/png;base64,'+uni.arrayBufferToBase64(datas);
        console.log(this.codeUrl);
      },
    });

最后使用uni.arrayBufferToBase64()方法将 ArrayBuffer 对象转成 Base64 字符串
<image :src="${codeUrl}" ></image>

❤ API - 设备

uni.makePhoneCall(OBJECT) 拨打电话

uni.makePhoneCall({
	phoneNumber: '114' //仅为示例
});

❤ 教程-页面 - 生命周期

onUnload 监听页面卸载

onReachBottom 页面触底加载

页面触底加载(用于下拉加载分页和加载更多)

可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,
比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。

如使用scroll-view导致页面没有滚动,则触底事件不会被触发。scroll-view滚动到底部的事件请参考scroll-view的文档。

在这里插入图片描述

与onShow 同级别
onReachBottom() {
			if (this.total > this.getUserHistoryReportList.length) {
				this.queryParams.pageNum++
				this.onlistin(); //执行的方法
			} else {}
},


getList 方法使用
getList() {
				let _this = this;
				uni.request({
					url:'/接口',
					method: 'GET',
					data: _this.queryParams,
					success(res) {
						console.log(res.data);
						if(_this.queryParams.pageNum==1){
							_this.getUserHistoryReportList  =res.data.rows;
						}else{
							_this.getUserHistoryReportList = [..._this.getUserHistoryReportList, ...res.data.rows];
						}
						_this.total = res.data.total;
					},
					fail(err) {
						 uni.showModal({
						      content: '请求失败'+ err.errMsg,
						      showCancel: false
						  });
						console.log('失败:', err);
					}
				})
	},

onPullDownRefresh 页面下拉刷新

和onLoad等生命周期函数同级,监听该页面用户下拉刷新事件

需要在 pages.json 里,找到的当前页面的pages节点,并在 style 选项中开启 enablePullDownRefresh。

当处理完数据刷新后,uni.stopPullDownRefresh 可以停止当前页面的下拉刷新。

在这里插入图片描述

// 下拉刷新
		onPullDownRefresh() {
			this.handleQuery();
			uni.stopPullDownRefresh(); //停止刷新
},

页面下拉刷新 uni.startPullDownRefresh(OBJECT)

开始下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。

页面针对不同类型设备禁止刷新
uni-app 中实现动态禁用/开启下拉刷新

https://ask.dcloud.net.cn/article/35134
在这里插入图片描述

❤ 教程-页面 - 文本、富文本标签

uniapp富文本和H5内容标签 v-html,uniapp rich-text、uparse、v-html(3种)
由于小程序端的限制,uni-app的富文本的处理与普通网页不同

有rich-text组件、v-html、和uParse三类方案

1. rich-text

rich-text是uni-app的内置组件,提供了高性能的富文本渲染模式。

API参考https://uniapp.dcloud.io/component/rich-text

优点
rich-text的优势是全端支持、高性能

缺点
只能整体设点击事情,无法对富文本中的图片、超链接单独设点击事件。

如果是图片,可以把内容拆成多个rich-text解决。rich-text不支持内嵌视频也可以通过拆分多个rich-text,中间插入video来实现。

注:h5和app-nvue无此限制,支持链接等单独点击。

  1. v-html

v-html指令,是web开发中很常用的。可惜由于小程序不支持html,使用场景受限。

在uni-app中,h5端,和app-vue的v3编译器下可以使用v-html。其他环境无法支持。

  1. uParse

由于小程序的rich-text组件在一些场景不满足需求,于是业内出现了wxparse等三方方案,把HTML或markdown格式的服务器数据源转为view来渲染。

但wxparse许久不更新,且不跨端,在uni-app插件市场出现了更多改进版的parse插件。

它们功能更强,支持直接渲染markdown或html的数据源为富文本,也支持其中的图片和超链接的点击处理,有的还支持表格和视频的处理。

但这些parser解决方案的性能不如rich-text。

注:app-nvue只能使用rich-text。

几种方案的特点讲清楚了,大家在开发中根据自己的需求选择合适的富文本渲染方案吧。

至于富文本编辑,即在输入框里图文混排内容,解决方案如下:

在h5、app-vue、微信小程序,支持editor组件

在h5中,传统的富文本编辑仍可使用

在非微信的其他小程序中,其官方没有提供解决方案,目前只能使用web-view组件套一个远程网页来满足这方面的需求。web-view组件是全端可用的解决方案。

还有一种方案,不再编辑区直接预览效果,而是采用markdown编辑器方案,输入区输入markdown语法,预览区提供预览。这种方案是跨端的。插件市场搜富文本编辑,有不少插件。http://ext.dcloud.net.cn/search?q=富文本编辑

富文本编辑editor组件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/325656.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI嵌入式K210项目(4)-FPIOA

文章目录 前言一、FPIOA是什么&#xff1f;二、FPIOA代码分析总结 前言 磨刀不误砍柴工&#xff0c;在正式开始学习之前&#xff0c;我们先来了解下K210自带的FPIOA&#xff0c;这个概念可能与我们之前学习STM32有很多不同&#xff0c;STM32每个引脚都有特定的功能&#xff0c…

Spring基于AOP(面向切面编程)开发

概述 AOP为Aspect Oriented Programming的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续&#xff0c;是软件开发中的一个热点&#xff0c;也是Spring框架中的一个重要内容&…

通过旋转机械臂,将机械臂上相机拍摄图像的任意点移动至图像中心的方法

计算原理 角度计算 相机CCD大小固定&#xff0c;即相机成像平面大小固定&#xff0c;相机视场角(FOV)仅由相机焦距F决定&#xff1b; 因此&#xff0c;定焦相机的FOV大小固定&#xff0c;通过上图可以看出相机视场角的计算公式为&#xff1a; FOV 2*atan&#xff08;w/2f&…

Windows 下 使用 VSCode 和 arm-none-eabi 编译Linux代码时 mkdir 命令出错

编译环境&#xff1a; IDE: VSCode 交叉编译器&#xff1a;arm-none-eabi make 命令&#xff1a;Mingw-w64 GCC for Windows 64 源代码管理&#xff1a;git 交叉编译器版本和安装目录: E:\work_soft\gcc-arm-none-eabi-10.3-2021.10 Mingw 版本和目录&#xff1a;E:\work_…

C++ 设计模式之外观模式

【声明】本题目来源于卡码网&#xff08;题目页面 (kamacoder.com)&#xff09; 【提示&#xff1a;如果不想看文字介绍&#xff0c;可以直接跳转到C编码部分】 【简介】什么是外观模式 外观模式Facade Pattern , 也被称为“⻔⾯模式”&#xff0c;是⼀种结构型设计模式&#…

2011 年考研数二真题解析

一、选择题 【01】【02】【03】【04】【05】【06】【07】【08】 二、填空题 【09】【10】【11】【12】【13】【14】 三、解答题 【15】【16】【17】【18】【19】【20】【21】【22】【23】

Vue高级(二)

3.搭建vuex环境 创建文件&#xff1a;src/store/index.js //引入Vue核心库import Vue from vue//引入Vueximport Vuex from vuex//应用Vuex插件Vue.use(Vuex)//准备actions对象——响应组件中用户的动作const actions {}//准备mutations对象——修改state中的数据const mutat…

mac idea 配置docker 插件

mac默认配置 会报错 mac Can’t connect: com.intellij.docker.agent.Api TaskException: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? (Details: [2] No such file or directory) 终端执行 sudo ln -s "$HO…

中学生英语杂志中学生英语杂志社中学生英语编辑部2023年第46期目录

“《中学生英语》教育教改与考试研究中心”课题组课题成果交流 高中英语学习动机因素与其对学习成效的影响研究 仇丽; 3-4 主位推进程序在高中英语读后续写中的应用 陈媛媛; 5-6《中学生英语》投稿&#xff1a;cn7kantougao163.com 小学英语教学:互动式英语词汇记忆…

Spring AOP 源码分析

【阅读前提】&#xff1a; 需了解AOP注解开发流程&#xff1a;链接 一、注解 EnableAspectJAutoProxy 在配置类中添加注解EnableAspectJAutoProxy&#xff0c;便开启了AOP&#xff08;面向切面编程&#xff09; 功能。此注解也是了解AOP源码的入口。 EnableAspectJAutoProxy…

外贸建站服务器如何选?海洋建站主机推荐?

外贸建站用哪个服务器比较好&#xff1f;独立网站怎么选择主机&#xff1f; 随着全球化的趋势&#xff0c;外贸网站的建设越来越受到企业的重视。然而&#xff0c;要想让外贸网站稳定、安全、可靠地运行&#xff0c;选择合适的外贸建站服务器是关键。海洋建站将详细介绍如何选…

Git 实操

文章目录 安装本地操作工作流程 Git 初始化以及仓库的创建、操作基本信息初始化一个Git 仓库 Git 管理远程仓库Git 克隆给远程仓库设置别名pull 拉取并合并分支Push推送到远程实战 git 是免费的管理github 的一个软件 安装 Git 官网下载&#xff1a;https://git-scm.com/downlo…

前端(二)VUE功能集锦

一、引言 作者开发工具平台的时候&#xff0c;用到了vue和element-ui&#xff0c;这里写一下各种功能使用&#xff0c;有的是绕点弯路&#xff0c;有的是需要结合实现需要自己改写一下。 二、功能 先看看环境&#xff0c;作者后端是SpringBoot&#xff0c;前端是VUEElementUI&a…

揭秘高生产力设计工具!15款原型设计软件推荐大公开!

1、Proto.io Proto.io是一个特殊的手机原型开发平台——可以构建和部署全交互式移动程序的原型&#xff0c;并可以模拟类似的成品。它可以在大多数浏览器中运行&#xff0c;并提供三个重要的界面&#xff1a;dashboard、编辑器和播放器。 dashboard可以用来管理项目。编辑器是…

spring常见漏洞(3)

CVE-2017-8046 Spring-Data-REST-RCE(CVE-2017-8046)&#xff0c;Spring Data REST对PATCH方法处理不当&#xff0c;导致攻击者能够利用JSON数据造成RCE。本质还是因为spring的SPEL解析导致的RCE 影响版本 Spring Data REST versions < 2.5.12, 2.6.7, 3.0 RC3 Spring Bo…

亚信安慧AntDB数据库自主研发技术再获国际认可

亚信安慧AntDB数据库最新宣布喜讯&#xff1a;成功通过了GB 18030-2022《信息技术 中文编码字符集》的最高级别认证&#xff0c;从而荣幸地成为首批获得此认证的数据库产品之一。这一认证的取得不仅是AntDB在技术上的重要里程碑&#xff0c;更是对其一贯积极践行国家政策和标准…

护眼台灯哪个品牌更好?汇总好用的护眼台灯前五名

随着对健康生活的追求不断增长&#xff0c;越来越多的人开始关注眼睛健康问题。在日常生活和工作中&#xff0c;台灯作为常用的照明设备之一备受关注&#xff0c;尤其是护眼台灯的问世引起了广泛关注。尤其是对于那些经常长时间用眼的人群&#xff0c;比如面临较重课业负担的学…

转载 | 深耕数据安全 创新“智”高点-天空卫士获评金智奖“年度最具影响力企业奖”

近日&#xff0c;以“并肩聚力&#xff0c;协同创新&#xff0c;共谋网络安全产业新发展”为主题的2022-2023年度中国网络安全与信息产业“金智奖”颁奖盛典在上海隆重举行。北京天空卫士网络安全技术有限公司&#xff08;以下简称“天空卫士”&#xff09;凭借其高速成长能力、…

【书生·浦语】大模型实战营——第五次课程作业

基础作业——使用LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署InternLM-Chat-7B模型&#xff0c;生成300字的小故事 环境准备 除了安装所需依赖之后&#xff0c;重要的是进行模型转化&#xff08;转换成TurboMind格式&#xff09;&#xff0c;这里需要注意转化命…

Android项目架构怎么做

项目架构指南 本指南包含一些最佳做法和推荐架构&#xff0c;有助于构建强大而优质的应用。 注意&#xff1a; 本页假定您对 Android 框架有基本的了解。 移动应用用户体验 典型的 Android 应用包含多个应用组件&#xff0c;包括 Activity、Fragment、Service、内容提供程序…