Android屏幕适配方案: AutoDensity&smallest-width

Android开发之屏幕尺寸的兼容 阅读详情

前言

一个Android开发工程师,在其入门后遇到的第一个考验估计就是屏幕适配。按照谷歌的适配规则,使用wrap_content、match_parent、dp等,当UI工程师换一个设备验收时,提出各种问题。这时候,估计很多人一脸懵逼,难道谷歌的适配标准是错误的?其实不是,只是还不够。android屏幕碎片化问题,导致很难一次性适配所有屏幕,这就导致了百分比适配方案的刚需。因为它用最低的成本适配了尽可能多的设备。最终今日头条屏幕适配方案和最小宽度适配方案,经过考验成为最受欢迎的两种适配方案。本文在研究了smallest-width和今日头条适配方案的基础上,用kotlin实现了smallest-width的dimens生成工具,用kotlin实现了今日头条适配方案:AutoDensity。并提出,最佳实践方案:布局和代码中用一份1:1的dimens,实际用AutoDensity一行代码实现适配,这样进可攻,退可守,在开发过程中可以无缝切换,直到正式发第一个版本时,可以选择其中一个,或者仍保留两个。

一、屏幕适配的重要概念

在开始屏幕适配之前,至少对下面几个概念有个简单理解。

1.1 屏幕尺寸、屏幕分辨率、屏幕像素密度

屏幕尺寸是指屏幕的对角线物理长度,单位英寸,1英寸=2.54厘米。如4.7英寸,5.5英寸,5.8英寸…

屏幕分辨率是指屏幕x&y轴上的物理像素值,如1920*1080。

屏幕像素密度是指单位英寸上的物理像素点数,一般是指对角线上。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。

1.2 px、dp、dip、dpi

px也就是上面说的像素;dp和dip,即密度无关像素;dpi,也就是上面说的屏幕像素密度,假如一英寸里面有160个像素,这个屏幕的像素密度就是160dpi。在Android中,规定以160dpi为基准,1dip=1px,如果密度是320dpi,则1dip=2px,以此类推。

1.3 mdpi、hdpi、xdpi、xxdpi

了解了屏幕像素密度dpi,需要了解android中的mdpi,hdpi,xdpi,xxdpi…它们描述的是dp和px的关系,用两张表来说明:

名称 像素密度范围
mdpi 120dpi~160dpi
hdpi 160dpi~240dpi
xhdpi 240dpi~320dpi
xxhdpi 320dpi~480dpi
xxxhdpi 480dpi~640dpi
屏幕密度 图标尺寸
mdpi 48x48px
hdpi 72x72px
xhdpi 96x96px
xxhdpi 144x144px
xxxhdpi 192x192px

在计算dp和px时,mdpi是基准1比1,hdpi是1比1.5,xhdpi是1比2,以此类推。所以当UI给你设计稿时,一般可能只有像素,如1080*720,这时候还需要知道比例,也就是像素密度才能转化为Android用的dp单位。一般UI设计师也不知道,是多少比例,常用的是1比2。不过现在有很多工具是直接给dp单位的,如蓝湖,这就很方便来。

1.4 values-sw[xyz]dp

最小宽度限定,这就是smallest-width运行的基础。app在运行的时候会根据屏幕的最短边,选择对应适当的values-sw[xyz]dp目录里面的dimens。

二、smallest-width适配方案

如上面所说,app在运行的时候会根据屏幕的最短边,选择对应适当的values-sw[xyz]dp目录里面的dimens。这就是smallest-width适配方案的基础,系统具体是如何实现的,这里不做分析,只要知道这个结果,然后我们可以生成一系列的dimens,放在一系列的values-sw[xyz]dp目录,这样就达到来百分比布局的效果。
使用smallest-width作为适配方案,有一定的代码侵入,也就是要在布局文件中插入如:@dimen/dp48,这样的代码,也仅此而已,没有更多代码需要写。但是生成不同的dimens文件,这里给出一个kotlin写的工具,同时这个工具还提供方法,将现有布局文件中的dp值,改为生成的dimen对应值,不过请在了解它和自身的需求后慎重使用。

  1. DimenTypes
enum class DimenTypes(val smallestWith: Int) {
   
   
    SW_DP_300(300),
    SW_DP_310(310),
    SW_DP_320(320),
    SW_DP_330(330),
    SW_DP_340(340),
    SW_DP_350(350),
    SW_DP_360(360),
    SW_DP_370(370),
    SW_DP_375(375),
    SW_DP_380(380),
    SW_DP_390(390),
    SW_DP_400(400),
    SW_DP_410(410),
    SW_DP_420(420),
    SW_DP_430(430),
    SW_DP_440(440),
    SW_DP_450(450),
    SW_DP_460(460)
}
  1. DimenGenerator
package com.bottle.core.arch.smallest

import com.bottle.core.utils.domToXmlFile
import com.bottle.core.utils.writeFile
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.InputStreamReader
import java.math.BigDecimal
import java.util.regex.Pattern
import javax.xml.parsers.DocumentBuilderFactory

/**
 * 最大值
 */
private const val MAX_VALUE = 720

/**
 * 设计稿尺寸(将自己设计师的设计稿的宽度填入)
 */
private const val DESIGN_WIDTH = 375

/**
 * 设计稿的高度  (将自己设计师的设计稿的高度填入)
 */
private const val DESIGN_HEIGHT = 667

/**
 * 执行这个方法,将会在core模块的res目录下生成一系列的values-sw的dimens.xml
 */
fun main(args: Array<String>) {
   
   
   val generate = true
    if (gen
【Android Studio 屏幕适配】AndroidAutoSize基本用法介绍 文章目录前言一、屏幕适配的内在逻辑1.dp、px、dpi和density2.获取手机屏幕尺寸/dp二、AndroidAutoSize使用1.基本用法2.简单自定义方法总结 前言 屏幕适配是一款APP的基本素养,需要保证在不同型号的手机上都能正常显示,并且各部件的显示比例和设计图一致。本文我们来介绍一下dp、dpi、density这些名词之间的关系,以及大神 JessYan 的屏幕适配算法AndroidAutoSize的基本用法。 Github导航:AndroidAutoSize官方代码 一、屏幕适配 阅读详情

相关推荐

android 屏幕适配的总结,适合面试

1.支持各种屏幕尺寸: 使用wrap_content, match_parent, weight.要确保布局的灵活性并适应各种尺寸的屏幕,应使用 “wrap_content” 和 “match_parent” 控制某些视图组件的宽度和高度。 2.使用相对布局,禁用绝对布局在开发中,我们大部分时候使用的都是线性布局、相对布局和帧布局,绝对布局由于适配性极差,所以极少使用。 3.使用尺寸限定符。通

三石的专栏 9870

讲一下Android屏幕适配的smallwidth方案

最小宽度是指屏幕的短边尺寸(以 dp 为单位),无论设备的方向如何,这个值都是固定的。例如,一个设备的分辨率为 1080x1920,那么它的最小宽度就是 1080dp(假设屏幕密度为 1)。方案是一种有效的 Android 屏幕适配方法,可以帮助开发人员实现更加灵活和精细的界面适配。通过合理地划分最小宽度范围、创建资源目录和定义资源,可以为不同屏幕尺寸的设备提供最佳的用户体验。方案是一种屏幕适配方案,主要用于解决不同屏幕尺寸和分辨率下应用界面的适配问题。在 Android 中,

challenge51all的专栏 1822

深入解析.Net中SM2与sm-crypto的跨平台加解密实践

本文深入探讨了在.Net平台与前端sm-crypto库之间实现SM2国密算法跨平台加解密的实践方案。针对对接中常见的密钥格式、密文拼接顺序(C1C3C2与C1C2C3)等核心难点,提供了基于BouncyCastle的完整工具类实现、前后端联调示例及问题排查指南,旨在帮助开发者构建安全、兼容的数据加密通道。

weixin_29322855的博客 370

深入浅出:拆解RK3588 DVP摄像头驱动框架,从DTS配置到V4L2子系统

本文深入解析RK3588 DVP摄像头驱动框架,从DTS配置到V4L2子系统的完整实现。详细介绍了瑞芯微RK3588的多媒体子系统架构、设备树配置逻辑、rkcif驱动与V4L2框架的交互机制,以及用户空间调试与性能优化技巧,帮助开发者解决DVP摄像头驱动中的常见问题。

weixin_42525632的博客 267

数码管动态扫描避坑指南:如何用188芯片实现50Hz无闪烁显示?

本文深入解析188数码管动态扫描技术,提供工业级无闪烁显示方案。通过优化轮询扫描机制、硬件电路设计和软件架构,实现50Hz高刷新率显示,解决亮度不均和鬼影问题,适用于医疗设备和工业控制面板等高要求场景。

hhh00的博客 975

基于Cesium移动的天空云

天空中的云朵也算是一种天气气候的效果,它能更加逼真的反映当前的天气状况,可以是白云朵朵,也可以是乌云密布,结合其他天气效果,可以组合形成较为真实的三维可视化场景。

星云数海的博客,一个专注GIS十多年的GISer人。 448

JavaScript高级程序设计

作者:禅与计算机程序设计艺术 1.简介 JavaScript(简称JS)是一种直截了当、简单易用的动态脚本语言。它最初由Netscape公司的Brendan Eich(布兰登·艾奇)于1995年创建,但后来逐渐成为事实上的通用编程语言。目前,JS已经成为世界上最流行的客户端脚本语言,广泛用于网页开发、移

AI天才研究院 2268

Ambari 安装部署教程(手把手教学)【超级详细】

本文为读者提供了一套超详细的 Apache Ambari 安装部署教程,采用手把手教学方式,适合初学者及大数据运维人员。内容涵盖前期准备、环境配置、Ambari Server 与 Agent 安装、集群初始化配置、常见问题排查等全流程操作,确保用户能够顺利搭建稳定的 Hadoop 大数据平台管理系统。

Five的博客 1万+

YOLO11 改进系列 | 引入2023年 MLCA 的 C3k2_MLCA 模块,近零参数开销的本地-全局通道注意力,适合检测与分割特征增强

本文提出将MLCA(混合局部通道注意力)模块嵌入YOLOv11的C3k2框架中,形成C3k2_MLCA改进结构。该模块通过5×5局部池化和1×1全局池化双路融合,结合ECA式Conv1d生成通道注意力,在几乎不增加参数量的前提下(仅增加66个参数),实现了局部空间信息与全局通道统计的联合建模。相比传统SE和ECA注意力,MLCA保留了空间分布信息,更适合实例分割等需要精细定位的任务。实验表明改进后模型参数量仅增加0.002%,计算量基本不变,是一种高效的注意力增强方案。

qq_44224801的博客 93

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

QGis二次开发 —— 2、第一个程序 - 加载栅格tif与矢量shp文件(附源码)

1100

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: Android WorkFlow 助你轻松构建复杂流程
下一篇: AspectJ 编程指南
半瓶子响叮当
博客等级 码龄9年 17粉丝 31原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值