【原】android【手机】屏幕适配解决方案,完美适配适配hdpi,xhdpi,xxhdpi的做法。
1.先说要怎么做,后面在慢慢讲解:
2.现在来讲解为什么要放这三套:
这三套其实按内容来说就两种,为什么这两种可以适配hdpi,xhdpi,xxhdpi呢?
那么两种类型的dimens就可以了,为什么要用三套,为什么默认的dimens要是hdpi的?
3.关于图片的适配
4.最后大概讲讲现有的适配方案
5.附上dimens转换的代码
dp单位解决的是你所设置的按钮的实际大小保持稳定,但是设备的物理尺寸不一定,并不能完美适配。
写这个文章的时候只是接触到目前的主流手机,所以对于如下关系是适用的,但是最近接触到电视适配之后,MD我写的这是什么鬼==。。。。当然对于平板也不适用,所以下面的内容参考参考还可以
1.先说要怎么做,后面在慢慢讲解:
1.单位全部用dp,优先使用包裹内容和填充父窗体和权重来完成布局。
2.通过dimens文件来适配,需要三套,不考虑横屏
2.1 默认的dimens.xml 放按hdpi适配的参数;
2.2 hdpi的dimens.xml 放按hdpi适配的参数;
2.3 xhdpi的dimens.xml 放按xhdpi适配的参数;
3.适配的时候只用完美的完成一套xhdpi的dimens文件,然后通过代码生成hdpi的,因为就dp来说,他们有固定的比例关系,代码后面会贴出。
2.现在来讲解为什么要放这三套:
贴一个基本知识:(仅对于一般手机来说)
这三套其实按内容来说就两种,为什么这两种可以适配hdpi,xhdpi和xxhdpi呢?
那么两种类型的dimens就可以了,为什么要用三套,为什么默认的dimens要是hdpi的?
先说测试结果:
1.没有ldpi和mdpi对应的dimens.xml的情况下:会加载默认的dimens.xml
2.而hdpi,xhdpi,xxhdpi这三种会加载最近的dimens.xml文件
下面是测试过程:
我的测试dimens:
--默认的dimens.xml
<resources>
<dimen name="activity_horizontal_margin">5dp</dimen>
<dimen name="activity_vertical_margin">5dp</dimen>
</resources>
--hdpi的dimens.xml:
<resources>
<dimen name="activity_horizontal_margin">50dp</dimen>
<dimen name="activity_vertical_margin">50dp</dimen>
</resources>
--xhdpi的dimens.xml:
<resources>
<dimen name="activity_horizontal_margin">500dp</dimen>
<dimen name="activity_vertical_margin">100dp</dimen>
</resources>
测试布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <TextView
android:layout_centerInParent="true"
android:background="#000000"
android:layout_width="@dimen/activity_horizontal_margin"
android:layout_height="@dimen/activity_vertical_margin"/> </RelativeLayout>
在不同分辨率手机下的效果:(为了好看一些,图片大小被我拉伸过),下面依次为:ldpi,mdpi,hdpi,hdpi(删除hdpi对应的dimens之后),xhdpi,xxhdpi
(ldpi) (mdpi)
(hdpi) hdpi(删除hdpi对应的dimens之后)
(xhdpi) (xxhdpi)
分析结果:
1.ldpi和mdpi在没有对应的dimens的情况下,会去加载默认的dimens。而ldpi和mdpi和hdpi可以共用一套。 所以默认的dimens放hdpi的标准。
2.hdpi,xhdpi,xxhdpi会加载最近的dimens文件,所以删除hdpi对应的之后,加载了xhdpi的dimens。 所以要放一套hdpi的dimens。
3.xhdpi和xxhdpi用的一套标准,他们又会加载最近的。 所以要放一套xhdpi的。
3.关于图片的适配
也是分两种考虑
1.大图且内容复杂的 2.小图和大图但是内容简单的
有上面贴出的基本知识可算出,ldpi,mdpi和hdpi的宽缩放比例是一样的;xhdpi和xxhpdi的长宽是一样的。
所以关于图片部分的解决方案就是:
1.小图和大图但是内容简单的:
我们就把图片的控件写死,让图片的xy适配控件,发生变形。 只用切一套图,这样图片会有拉伸的情况出现,但是大图但是比如纯色的,拉伸也看不出来,小图拉伸也不明显。所以就这样做。
所以小图或大图且内容简单的解决方案就是,写死控件,让图片的xy适配控件。
2.大图且内容复杂的:
这种图片拉伸变形明显,所以我们要针对不同分辨率做处理:
其中xhdpi(1280*720)和xxhdpi(1920*1080)他们的长宽缩放是成比例的,都是1.5。所以他们可以共用一套图片。放在xhdpi对应的drawable目录下或者xxhdpi对应的drawable目录下即可。
hdpi,mdpi,ldpi,是不成比例的,所以要想获得最佳的适配效果,我们需要分别适配这三套,但是我觉得按现在市场是的手机情况,我们在适配一下hdpi就可以了。
所以大图且复杂的解决方案就是,适配两套,xhdpi的和hdpi的。
(ps:这里讨论的是app原生布局的适配,所以不适用于填充的图片是动态变化的且长宽不成比例的情况,比如,用户上传图片,这里为健壮还要做很多处理,不在讨论的范围内)
4.最后大概讲讲现有的适配方案
除了用dimens适配还有用layout布局文件适配的方案,通过代码动态设置的方案(我之前启动界面用过一个gif图片 ,就用的动态设置)
5.附上dimens转换的代码
对于px,dp,sp,dimens,权重这些基本概念我就不在这里一一介绍了。
转换dimens的代码:old放的是适配xhdpi的,
转换比例:
水平:是xhdpi屏幕宽的一半是180dp除以hdpi屏幕宽的一半是160dp得到的1.125.
竖直:是........................320dp...................................367dp得到的1.1985
这样的话只要完美适配一套xhdpi的,然后生成hdpi的就好了。
你需要区分你布局中写的参数是水平方向的,还是竖直方向的,下面代码中changes是转换因子,转换两次,水平一次,竖直一次,自己替换转换因子;
package convert;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException; public class DimensTools {
static String oldFilePath = "src/convert/dimens.xml"; static String filePathHdpi="src/convert/dimensHdpi.xml"; static float changes = 1.125f;
public static void main(String[] args) {
String st = convertStreamToString(oldFilePath, changes);
DeleteFolder(filePathHdpi);
writeFile(filePathHdpi, st);
}
public static String convertStreamToString(String filepath, float f) {
StringBuilder sb = new StringBuilder();
try {
BufferedReader bf = new BufferedReader(new FileReader(filepath));
String line = null;
System.out.println("q1");
String endmark = "dp</dimen>";
String startmark = ">";
while ((line = bf.readLine()) != null) {
if (line.contains(endmark)) {
int end = line.lastIndexOf(endmark);
int start = line.indexOf(startmark);
String stdp = line.substring(start + 1, end);
//int dp = Integer.parseInt(stpx);
float dp=Float.parseFloat(stdp);
//float newdp = ((float) dp / f); System.out.println("dp:"+dp); float newdp=dp/f; System.out.println("newdp:"+newdp); String dpStr=String.valueOf(dp);
String newline;
if(dpStr.contains(".0")){
int x=dpStr.indexOf(".");
System.out.println("x:"+x);
dpStr= dpStr.substring(0,x);
newline= line.replace(dpStr + "dp", newdp + "dp");
}else{
newline = line.replace(dp + "dp", newdp + "dp");
} System.out.println("newline:"+newline);
sb.append(newline + "\r\n");
} else {
sb.append(line + "\r\n");
}
}
// System.out.println(sb.toString());
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
public static boolean DeleteFolder(String sPath) {
File file = new File(sPath);
if (!file.exists()) {
return true;
} else {
if (file.isFile()) {
return deleteFile(sPath);
} else {
// return deleteDirectory(sPath);
}
}
return false;
}
public static void writeFile(String filepath, String st) {
try {
FileWriter fw = new FileWriter(filepath);
BufferedWriter bw = new BufferedWriter(fw);
bw.write(st);
bw.flush();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean deleteFile(String sPath) {
boolean flag = false;
File file = new File(sPath);
if (file.isFile() && file.exists()) {
file.delete();
flag = true;
}
return flag;
}
}
补充:有人问到美工怎么出视觉规范,给android出一套xhdpi的就行,单位用px标。自己按上面的基础知识,转成xhdpi的dp单位。最后用代码自动生成hdpi的一套就好了。
最后,我也是自己摸索,有什么问题,还望大家指点。
【原】android【手机】屏幕适配解决方案,完美适配适配hdpi,xhdpi,xxhdpi的做法。的更多相关文章
- Unity3D Android手机屏幕分辨率问题
Android手机屏幕分辨率五花八门,导致开发时不好把握,还好各个引擎对这个屏幕分辨率问题都有较好的处理方式:unity3D 也为我们提供了一个不错的解决方案. 在Unity3D 进行 android ...
- 获取Android 手机屏幕宽度和高度以及获取Android手机序列号
1.获取Android 手机屏幕宽度 1 DisplayMetrics dm = new DisplayMetrics(); 2 this.getWindowManager().getDefaultD ...
- 一分钟了解Android横竖屏 mdpi hdpi xhdpi xxhdpi xxxhdpi (转)
转自:http://blog.csdn.net/a704755096/article/details/46342689 DPI:每英寸像素数 简单的屏幕分辨率计算方法: DisplayMetrics ...
- 一分钟了解Android横竖屏 mdpi hdpi xhdpi xxhdpi xxxhdpi
DPI:每英寸像素数 简单的屏幕分辨率计算方法: DisplayMetrics metrics = this.getResources().getDisplayMetrics(); float den ...
- Android开发——Android手机屏幕适配方案总结
)密度无关像素,单位为dp,是Android特有的单位 Android开发时通常使用dp而不是px单位设置图片大小,因为它可以保证在不同屏幕像素密度的设备上显示相同的效果. /** * dp与px的转 ...
- Android手机屏幕投射到电脑神器Vysor
做android开发的,经常要把手机屏幕投射到电脑,用来演示.普遍的解决方案是360或者豌豆荚的演示功能,缺点是延迟非常厉害,大概有3秒左右,非常影响演示效果.以下介绍Vysor,几乎0延迟,能与手机 ...
- Pyqt adb 获取Android手机屏幕
adb的全称为Android Debug Bridge,就是起到调试桥的作用.adb的工作方式比较特殊,采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯,默认情况下adb会da ...
- Droid@screen:在PC屏幕上显示Android手机屏幕
这里介绍一款工具——Droid@screen,用来获取手机屏幕,显示在PC屏幕上.它集截图.录像等多种功能于一体. 安装 1. 下载地址:http://droid-at-screen.org/d ...
- 用802.11n 加速,将android手机屏幕投影到win7电脑上
在做Android应用开发的时候,经常需要将已经完成的应用展示给一同开发的小伙伴,然而一直感觉没有找到一种十分方便的办法.特别是看到了开发IOS的小伙伴在做展示的时候的方便.因为Apple既做PC,也 ...
随机推荐
- 用Docker搭建一个支持https的nginx代理服务
用Docker搭建一个支持https的nginx代理服务 说明:本文所提的服务只是作者平常测试使用,可能含有未知bug或不成熟的解决方案,仅供参考,请不要用于正式环境,当然,使用过程中有任何问题欢迎提 ...
- java集合第一节,List简单介绍
Java中List集合的常用方法 List接口是继承Collection接口,所以Collection集合中有的方法,List集合也继承过来. package 集合; import java.ut ...
- Lambda函数及其用法
Lambda函数又称匿名函数,匿名函数就是没有名字的函数,函数没有名字也行? 当然可以啦.有些函数如果只是临时一用,而且它的业务逻辑也很简单时,就没必要非给它取个名字不可. 先来看个简单lambda函 ...
- Oracle数据库 常见的SQL题,复习
01.查询员工表所有数据,并说明使用*的缺点 select * from emp 02.查询职位(JOB)为'PRESIDENT'的员工的工资 select sal from emp where jo ...
- unity 截屏总结
转载与https://www.cnblogs.com/MissLi/p/8005342.html 1.针对指定的相机进行截屏 此中方式要添加yield return waitfortheEndofFr ...
- docker-compose下的java应用启动顺序两部曲之一:问题分析
在docker-compose编排多个容器时,需要按实际情况控制各容器的启动顺序,本文是<docker-compose下的java应用启动顺序两部曲>的第一篇,文中会分析启动顺序的重要性, ...
- Windows下NFS服务器SFU设置(可以共享linux系统)
一.安装SFU1.下载软件SFU http://download.microsoft.com/download/a/1/c/a1ca7af1-a6e3-46e7-874a-4c5d8c0fb3b7/S ...
- Flask:数据库的建模
学习完模板系统,接下来要研究的就是框架对数据库的操作,不论python的那个框架,直接使用数据库API(redis.pymysql等)都可以进行操作,但是这些操作不够方便,于是就有了ORM 1.Fla ...
- Educational Codeforces Round 71 (Rated for Div. 2)E. XOR Guessing
一道容斥题 如果直接做就是找到所有出现过递减的不同排列,当时硬钢到自闭,然后在凯妹毁人不倦的教导下想到可以容斥做,就是:所有的排列设为a,只考虑第一个非递减设为b,第二个非递减设为c+两个都非递减的情 ...
- python基础-流程控制(if,while,for)
今日内容总结 --流程控制(if,while,for) if:用来判断事物的对错.真假.是否执行.根据不同的情况判断,条件满足执行某条件下的语句 语法结构(3种) # 第一种,只有if结构.条件表达式 ...