qingmei2

Results 60 issues of qingmei2

> **本文已授权「玉刚说」微信公众号独家发布** ## 概述 `Paging`是`Google`在2018年I/O大会上推出的适用于`Android`原生开发的分页库,随着越来越多的开发者着手使用`Paging`,越来越多的问题暴露出来,最直接的一个问题是: > 如何管理列表额外的状态? 这样的需求随处可见,比如 `侧滑删除`、`为评论点赞` 等等: 本文将阐述:如何管理`Paging`分页列表的 **状态**,为何这样设计,以及设计的过程。 ## 列表的状态问题 和市面上其它热门的分页库相比,`Paging`最大的亮点在于其 **将列表分页加载的逻辑作为回调函数封装入 `DataSource` 中**,开发者在配置完成后,无需通过代码手动控制分页的加载,列表会 **自动加载** 下一页数据并展示。 这种便利意味着开发者不需要自己持有 **数据源** ,大多数时候这使得开发流程更加便利,但总有偶然,比如这样一个界面: ![](https://raw.githubusercontent.com/qingmei2/qingmei2-blogs-art/master/android/jetpack/paging/ex2-state/1.lvuyq8lwlyp.gif) 这种需求屡见不鲜,其本质是,列表本身展示服务端返回的列表数据之外,还需要 **本地控制额外的状态**。 什么叫 **额外的状态** ? 我们先用简单的一张图展示没有额外状态的情形,这时,列表的所有UI元素都从服务端获取:...

Android Jetpack

本文将针对将 `Unity` 的项目导出到 `Android` 平台的步骤进行一个总结。 首先点击`File`-`Building Settings`,打开配置面板: ![1.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e1d20af4ceab40c89a97a63821fc2216~tplv-k3u1fbpfcp-watermark.image?) 打开面板后,切换`Android`栏,准备导出项目,如果是第一次导出,那么`Unity`没有找到对应的开发环境配置,提示需要下载,以`iOS`为例: ![3.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a1ddb865d13b48a2b69b8216ce024299~tplv-k3u1fbpfcp-watermark.image?) 在 `Unity Hub` 上,需要手动指定下载的依赖,包括`Android SDK` 和 `NDK`, 下载安装完成后,需重启`Unity`,再回到配置面板,此时已经可用了: ![2.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a6884371897844658c2ad91bd13ebfde~tplv-k3u1fbpfcp-watermark.image?) 主面板提供了一些基础的配置,其中最重要的是`Export Project`选项,对于开发者而言,当然需要导出项目自行修改,因此需选中该选项。 > 若不勾选该选项,默认会导出一个可以直接安装运行的 `apk` 包。 根据 `Unity` 项目的复杂度不同,点击 `Switch Platform`...

Unity3D

## 概述 之前看到 [自如团队]() 发布的 [自如客APP裸眼3D效果的实现](https://juejin.cn/post/6989227733410644005) ,非常有趣,不久后,社区内 `Android` 的开发者们陆续提供了 [Flutter](https://juejin.cn/post/6991409083765129229)、 [Android 原生](https://juejin.cn/post/6991840263362576421) 、[Android Jetpack Compose](https://juejin.cn/post/6992169168938205191) 等不同的实现版本。 很快我看到了一个好玩的评论: ![comments.png](https://img-blog.csdnimg.cn/img_convert/9fc593cb5b48d206b41cdbf47045af0f.png) 既然客户端都卷成这样了,干脆破罐破摔,把 `Android OpenGL` 的实现版本也补齐,毕竟 **图形学或许会迟到,但绝不会缺席** 。 实现效果如下([图片来源](https://juejin.cn/post/6991409083765129229)),这一波属实参与到社区内裸眼`3D`的 **客户端大满贯** 了 : ![](https://img-blog.csdnimg.cn/b1ba76035cb545a2b865f7b8ce4dc90f.gif) ##...

图形学

## 概述 **音视频倍速** 是内容类`APP`非常重要的功能,其内部包含了 **视频流** 和 **音频流** 的倍速,其中视频倍速原理相对简单,即在解码视频帧时提升帧率即可。 **音频倍速** 相对复杂,众所周知,声音的本质其实是 **物体振动时产生的声波**,因此音频的倍速是 **将语音信号在时域上拉长或缩短**,考虑到用户的体验,在保证声音变速的同时,语音的采样率、基频以及共振峰都不能发生变化,以此达到 **变速不变调** 的目的。 对于 `Android` 平台的应用而言,音频倍速通常有3种实现方式: |实现方案|应用|简介| |:----- |:-----|----- | |Android AudioTrack | Android 原生音视频架构 | 原生支持,但存在兼容性问题,倍速效果不佳 | |Sonic...

音视频开发

# Android ExoPlayer 分场景集成不同音频倍速算法的实现 ## 概述 上文 [《Android 音频倍速的原理与算法分析》](https://github.com/qingmei2/blogs/issues/58) 中, 我们针对音频倍速的基本原理进行了梳理,并逐步引申出了 `Android` 平台上常用的2种算法实现:`Sonic` 和 `SoundTouch`。 初步结论是,在用户启用音频倍速时,我们需要 **根据具体场景切换不同实现** ,以此保证最佳的用户体验。 举例来说,对于常规音乐——尤其是背景乐、打击感比较强的音乐,我们优先选择 `SoundTouch`, 而对于人声更纯粹的音频(相声评书、歌手清唱等)而言,`Sonic` 才是更好的选择。 本文以 `Google` 开源的 `ExoPlayer` 为例,从源码分析播放器自身的 `Sonic` 具体是如何实现的倍速;之后,再尝试将 `SoundTouch`...

音视频开发

> **反思** 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 [这里](https://github.com/qingmei2/blogs/blob/master/src/%E5%8F%8D%E6%80%9D%E7%B3%BB%E5%88%97/thinking_in_android_index.md) 。 ## 背景 在自媒体的时代,**音视频播放** 俨然已成为内容类型 `APP` 最基础的能力,对于 `Android` 开发者而言,无论是 `Google` 开源的 [ExoPlayer](https://github.com/google/ExoPlayer) ,还是 `Bilibili` 开源的 [ijkplayer](https://github.com/bilibili/ijkplayer) , 都是构建应用音视频播放能力时优秀的选择。 虽然上述的三方播放器都自带完善的缓存功能,但对于内容和形式都日新月异的一众互联网产品来说,想要打造完美契合自家产品的用户体验,播放器自身的缓存机制已逐渐无法满足需求。 最具代表性的产品是 **抖音**。 在播放短视频内容时,保证浏览、上下切换时 **无缝链接** 般丝滑的用户体验,可以说是重中之重的性能要求,而这对于传统的播放器缓存机制而言是远远满足不了要求的。 因此,**构建自定义音视频缓存机制势在必行**。 本文将针对...

Thinking in Android
音视频开发

# 运用递归解决二叉树相关问题 ![](https://raw.githubusercontent.com/qingmei2/qingmei2-blogs-art/master/blogs/algorithm/1/image.vrvs0ycz82b.png) 在之前的章节中,我们已经介绍了如何解决树的遍历问题。我们也已经尝试过使用递归解决树的为 **前序遍历** 、 **中序遍历** 和 **后序遍历** 问题。 事实上,**递归** 是解决树相关问题的最有效和最常用的方法之一。本节中,我们将会介绍两种典型的递归方法。 ## 解决方案 > 本小节内容节选自 [LeetCode:运用递归解决树的问题](https://leetcode-cn.com/explore/learn/card/data-structure-binary-tree/3/solve-problems-recursively/11/) . 递归是解决树的相关问题最有效和最常用的方法之一。 我们知道,树可以以递归的方式定义为一个节点(根节点),它包括一个值和一个指向其他节点指针的列表。 递归是树的特性之一。 因此,许多树问题可以通过递归的方式来解决。 对于每个递归层级,我们只能关注单个节点内的问题,并通过递归调用函数来解决其子节点问题。 通常,我们可以通过 **自顶向下** 或 **自底向上** 的递归来解决树问题。 ### “自顶向下”...

Algorithm

> 原文:[An alternative Android Visualizer](https://www.egeniq.com/blog/alternative-android-visualizer) > 作者:[Dániel Zolnai](https://www.egeniq.com/blog/alternative-android-visualizer) > 译者:[却把清梅嗅](https://github.com/qingmei2) 听音乐时,有时你会看到那些视觉上令人愉悦的跃动条,它们音量越大跳得越高。通常,左边的条形对应的频率较低(低音),而右边的条形对应较高的频率(高音): ![请添加图片描述](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9d4f176a188b4314a760211b9dbbab80~tplv-k3u1fbpfcp-zoom-1.image) 这些跃动条通常被称为 **视觉均衡器** 或 **可视化器**,若想在 `Android` 应用中展示类似的可视化效果,你可以使用 `Android` 原生的 `Visualizer` 类,它是`Android`框架中的一部分,且能够附加到你的 `AudioTrack`。 它是切实有效的,但有一个重要的缺陷:它需要申请 **麦克风权限** ,而从官方文档上来看,这是有确切考虑的: > To protect privacy...

音视频开发

# 反思 | 开启B站少女心模式,探究APP换肤机制的设计与实现 > **反思** 系列博客是我的一种新学习方式的尝试,该系列起源和目录请参考 [这里](https://github.com/qingmei2/blogs/blob/master/src/%E5%8F%8D%E6%80%9D%E7%B3%BB%E5%88%97/thinking_in_android_index.md) 。 ## 概述 **换肤功能** 并非奇技淫巧,而是已非常普及,尤其当`Android Q`推出了 **深色模式** 之后,国内绝大多数主流应用都至少提供了 **日间** 和 **夜间** 两种模式。 对于无感的用户而言,这个功能实属鸡肋,但从另外一个角度上来说,这也是产品在雕琢 **用户极致体验** 过程中的一次尝试,为不同情景下,不同偏好的用户提供更多的选择性。 以 **哔哩哔哩** 为例,除了提供以上两种主题之外,还免费提供了充满 **少女心** 的粉色主题: ![](https://raw.githubusercontent.com/qingmei2/blogs/main/src/%E5%8F%8D%E6%80%9D%E7%B3%BB%E5%88%97/Skin/bilibili.png) 从产品的前瞻性上来看,国内在换肤功能的探索较国外是领先的,抽象的来看待`Android...

Thinking in Android

# [译] 编写AndroidStudio插件(五):本地化和通知 > 原文:[Write an Android Studio Plugin Part 5: Localization and Notifications](https://proandroiddev.com/write-an-android-studio-plugin-part-5-localization-and-notifications-cb036d867587) > 作者:[Marcos Holgado](https://medium.com/@marcosholgado) > 译者:[却把清梅嗅](https://github.com/qingmei2) >《编写AndroidStudio插件》系列是 IntelliJ IDEA 官方推荐的学习IDE插件开发的博客专栏,希望对有需要的读者有所帮助。 在本系列的[第四部分](https://proandroiddev.com/write-an-android-studio-plugin-part-4-jira-integration-cd54df01cff6)中,我们学习了如何在插件中集成诸如`Jira Cloud Platform`之类的第三方`API`,以及如何使用`MVP`或`MVC`之类的模式开发。本文我将部分重构插件,以便我们可以对插件进行本地化,并以更简单的方式使用通知。 ![](https://raw.githubusercontent.com/qingmei2/qingmei2-blogs-art/master/ide-plugin/part5_1.png) ## 我们要做什么? 今天的目标非常简单,我们将尝试整理插件的代码。为此,我将重点关注两个领域:**通知**...

IDE-Plugin