安卓版本apk UI 适配问题:
安卓手机生产大厂多,手机屏幕分辨率也是多,安卓开发要适配真的头疼。我也不知道其他开发遇到这个问题怎么办,unity 引擎 UGUI也有适配对应解决方案,但是不适合项目要求(我也还没体会到它的使用*-*),可是项目要求不能多个版本不同然后就重复做UI摆放,这真是个无聊又费精神的工作,主要是公司也不会同意。
适配原理:
ipad 的分辨率是按1024 X 768 做原始值,其他版本多是按它放大,(有特殊的请提示),做ipad的UI摆放只要做好锚点,然后按做的UI的分辨率与实际屏幕的分辨率的大小缩放就可以很快解决问题。可是安卓的不能这样,比如1920*1080 与 1920*1200,这总不能不同屏幕分辨率就不同的做法。为了比较好的效果,同时节省多个版本的现象就去一个原始分辨率,UI设计师按原始的分辨率设计UI,在unity里按原始分辨率排版,然后计算实际屏幕分辨率(x,y)跟原始分辨率(x,y)的比例值,X、Y的比例值,取小的等比缩放,取大的进行部分UI的分辨率缩放。在屏幕划分9个区域,分别是
【Center,//中 Left,//左 Rigth,//右 TopLeft,//顶 左 Top,//顶 TopRight,//顶 右 BottomLeft,//底 左 BottomRight,//底 右 Bottom,//底 CenterLeft,//中左 CenterRigth,//中右】
,作为锚点
效果:
的
1:1024*768
2:1920*1080
# 代码: 1;等比缩放:
void OnGUI()
{
print("--GUI--");
switch (SlideAnctor)
{
case Slide.Bottom:
gameObject.transform.localPosition = new Vector3(0 + Deviation_Value.x, -Screen.height / 2 + Deviation_Value.y, 0);
break;
case Slide.Center:
gameObject.transform.localPosition = new Vector3(0 + Deviation_Value.x, 0 + Deviation_Value.y, 0);
break;
case Slide.CenterLeft:
gameObject.transform.localPosition = new Vector3(Screen.width / 2 + Deviation_Value.x, 0 + Deviation_Value.y, 0);
break;
case Slide.CenterRigth:
gameObject.transform.localPosition = new Vector3(-Screen.width / 2 + Deviation_Value.x, 0 + Deviation_Value.y, 0);
break;
case Slide.Top:
gameObject.transform.localPosition = new Vector3(0 + Deviation_Value.x, Screen.height / 2 + Deviation_Value.y, 0);
gameObject.transform.localPosition = new Vector3(0 + Deviation_Value.x, Screen.height / 2 + Deviation_Value.y, 0);
break;
case Slide.TopLeft:
gameObject.transform.localPosition = new Vector3(-Screen.width / 2 + Deviation_Value.x, Screen.height / 2 + Deviation_Value.y, 0);
break;
case Slide.TopRight:
gameObject.transform.localPosition = new Vector3(Screen.width / 2 + Deviation_Value.x, Screen.height / 2 + Deviation_Value.y, 0);
break;
case Slide.BottomLeft:
gameObject.transform.localPosition = new Vector3(-Screen.width / 2 + Deviation_Value.x, -Screen.height / 2 + Deviation_Value.y, 0);
break;
case Slide.BottomRight:
gameObject.transform.localPosition = new Vector3(Screen.width / 2 + Deviation_Value.x, -Screen.height / 2 + Deviation_Value.y, 0);
break;
}
// print(gameObject.transform.localPosition);
switch (style)
{
case Style.NormalBehavior:
break;
case Style.Both:
sceenValue = new Vector2(Screen.width, Screen.height);
gameObject.GetComponent<RectTransform>().sizeDelta = sceenValue;
break;
case Style.Heigth:
sizeDelta = gameObject.GetComponent<RectTransform>().sizeDelta;
sizeValue = sizeDelta.x * (Screen.height / sizeDelta.y);
gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(sizeValue, Screen.height);
break;
case Style.Width:
sizeDelta = gameObject.GetComponent<RectTransform>().sizeDelta;
sizeValue = sizeDelta.y * (Screen.width / sizeDelta.x);
gameObject.GetComponent<RectTransform>().sizeDelta = new Vector2(Screen.width, sizeValue);
break;
case Style.proportion:
sizeDelta = gameObject.GetComponent<RectTransform>().sizeDelta;
sizeDelta = sizeDelta * value; print("1:" + value);
gameObject.GetComponent<RectTransform>().sizeDelta = sizeDelta;
break;
}
_isActor = true;
}
2;像素改变:
/*
获取原始UI像素,保存,初始化需要原始数据
*/
public void GetSizeDelta()
{
sizeDelta = new List<Vector2>();
ratioSceen = new List<Vector2>();
//gameObject.tag = "Stretching";
Vector2 size = new Vector2();
if (Stretching.Count > 0)
{
foreach (GameObject g in Stretching)
{
g.tag = "Stretching";
size = g.GetComponent<RectTransform>().sizeDelta;
ratioSceen.Add(new Vector2(size.x / layoutScale.x, size.y / layoutScale.y));
sizeDelta.Add(size);
if (!sizeDic.ContainsKey(g))
sizeDic.Add(g, size);
else
sizeDic[g] = size;
}
}
}
/*
摆放屏幕:实际的屏幕
*/
public void SetSizeDelta(Vector2 stretch)
{
Vector2 size = new Vector2();
nowSizeDelta = new List<Vector2>();
if (stretch.x > stretch.y)
{
if (stretch.y > 2)
{
// return;
}
else
{
//如果长、宽比例差太多,取1.3做比例值(初始UI设计的高宽比例大概1.3,如果长或者宽拉的过于大,图片失真的会很明显)
if (stretch.x / stretch.y > 1.3f)
{
stretch.x = stretch.y * 1.3f;
}
int v1 = (Mathf.FloorToInt((stretch.x/stretch.y) * 10));
float v = v1 * 0.1f;
foreach (GameObject g in sizeDic.Keys)
{
size = new Vector2(sizeDic[g].x * v, sizeDic[g].y);
nowSizeDelta.Add(size);
g.GetComponent<RectTransform>().sizeDelta = size;
}
print(v);
}
}
else if (stretch.y > stretch.x)
{
if (stretch.x > 2)
{
}
else
{
//如果长、宽比例差太多,取1.3做比例值
if (stretch.x / stretch.y > 1.3f)
{
stretch.x = stretch.y * 1.3f;
}
int v1 = (Mathf.FloorToInt((stretch.x / stretch.y) * 10));
float v = v1 * 0.1f;
foreach (GameObject g in sizeDic.Keys)
{
size = new Vector2(sizeDic[g].x, sizeDic[g].y * v);
nowSizeDelta.Add(size);
g.GetComponent<RectTransform>().sizeDelta = size;
}
}
print("c2:" + stretch);
}
else
{
int i = 0;
foreach (GameObject g in sizeDic.Keys)
{
g.GetComponent<RectTransform>().sizeDelta = sizeDelta[i];
i++;
}
}
}
3,位置移动
/*
获取原始UI位置
*/
public void GetDisplacementObject()
{
displacement = new List<GameObject>();
displacementPos = new List<Vector3>();
displaceDic = new Dictionary<GameObject, Vector3>();
if (displacementParent.Count>0)
{
int count = 0;
GameObject game;
foreach (GameObject g in displacementParent)
{
count = g.transform.childCount;
for (int i = 0; i < count; i++)
{
if (g.transform.GetChild(i).gameObject.tag == "Displacement")
{
game = g.transform.GetChild(i).gameObject;
displacement.Add(game);
displacementPos.Add(game.transform.localPosition);
if (displaceDic.ContainsKey(game))
{
displaceDic[game] = game.transform.localPosition;
}
else
displaceDic.Add(game, game.transform.localPosition);
}
}
}
}
else
{
int count = gameObject.transform.childCount;
GameObject game;
for (int i = 0; i < count; i++)
{
if (gameObject.transform.GetChild(i).gameObject.tag == "Displacement")
{
game = gameObject.transform.GetChild(i).gameObject;
displacement.Add(game);
displacementPos.Add(game.transform.localPosition);
if (displaceDic.ContainsKey(game))
{
displaceDic[game] = game.transform.localPosition;
}
else
displaceDic.Add(game, game.transform.localPosition);
}
}
}
}
/*
屏幕像素变了,一些UI的位置也是需要调整
*/
public void DisplacementValue(Vector2 stretch)
{
if (stretch.x > stretch.y)
{
if (stretch.y > 2)
{
}
else
{
if (stretch.x / stretch.y > 1.3f)
{
stretch.x = stretch.y * 1.3f;
}
//int v0 = (Mathf.FloorToInt((stretch.x - stretch.y + 1) * 100));
int v1 = (Mathf.FloorToInt((stretch.x / stretch.y) * 10));
float v = v1 * 0.1f;
foreach (GameObject g in displaceDic.Keys)
{
g.transform.localPosition = new Vector3(displaceDic[g].x * v, displaceDic[g].y, displaceDic[g].z);
}
}
}
else if (stretch.y > stretch.x)
{
/*if (stretch.y > 2)
return;*/
if (stretch.y / stretch.x > 1.3f)
{
stretch.y = stretch.x * 1.3f;
}
//int v0 = (Mathf.FloorToInt((stretch.y - stretch.x + 1) * 100));
int v1 = (Mathf.FloorToInt((stretch.x / stretch.y) * 10));
float v = v1 * 0.1f;
foreach (GameObject g in displaceDic.Keys)
{
g.transform.localPosition = new Vector3(displaceDic[g].x, displaceDic[g].y * v, displaceDic[g].z);
}
}
else
{
foreach (GameObject g in displaceDic.Keys)
{
g.transform.localPosition = displaceDic[g];
}
}
}
心得:
效果目前看着还可以,这个项目可能效果还行,但是拿出到其他项目可能会有很多其他的问题,希望能得到更多的人的修改意见,然后可以修改成比较好的适配效果,主要是想有其他思路。