前言
今天給大家推薦一個簡單易行的適配不同安卓機型的方案柿菩,重點突出簡單蘸吓,大約花5~10分鐘就能讓現有的Android項目支持大部分設備状您。
簡書中已有作者更詳細的闡述http://www.reibang.com/p/1302ad5a4b04傀蓉,此文只做補充欧漱,特別補充如何替換現有項目layout文件中的dp、sp
一葬燎、是否合適使用此方案误甚?
UI設計一般以一套dp尺寸作為基準,或者使用Sketch Measure切圖工具生成可切換多個尺寸谱净,如圖:
靶草。
二、安裝ScreenMatch插件
ScreenMatch
在Android Studio 安裝插件
三岳遥、自動生成dimens.xml
在項目的默認 values 文件夾中需要一份 dimens.xml 文件
dimens.xml模板下載下來后放入工程即可奕翔。
1.右鍵項目后彈出菜單欄選中ScreenMatch
2.選擇工程module,一般優(yōu)先選擇各個模塊都能訪問的資源模塊或者通用模塊里生成浩蓉,方便各個模塊都能使用派继。
3.生成dimens
三、使用dp_10捻艳、sp_12代替10dp驾窟、12sp寫法
以后在layout中使用新的寫法代替∪瞎欤可以打開dimens.xml看一下名稱定義規(guī)則绅络,
整數:dp_10、sp_12 代表10dp嘁字、12sp
小數:dp_0_5 代表0.5dp
負數:dp_m_16 代表-16dp
四恩急、常見問題
如果是新工程問題不大,生成好dimens.xml后改用新的寫法就好纪蜒。那么對于以后的老工程怎么辦衷恭?手動替換layout文件中的dp、sp值顯然是巨大的勞動成本纯续,而且還可能漏掉某個沒改的就更不好了随珠。對于這類問題當然最理想的解決方案是用腳本批量替換。但是筆者找了一圈并沒有現成腳本猬错,所以自己寫了一個python腳本窗看。
# -*-coding:utf-8-*-
import re
import os
# 替換所有res/layout目錄下的xml
def replace_res_layout(file_dir):
for root, dirs, files in os.walk(file_dir):
for name in files:
file_name = os.path.join(root, name).replace('\\', '/')
if re.search(r'/res/layout/\w+.xml', file_name, re.S):
replace_layout_file(file_name)
pass
# 替換單個layout文件
def replace_layout_file(path):
layout_file_path = path
# 讀取layout文件內容
layout_file = open(layout_file_path, 'r')
layout_lines = layout_file.read()
# 正則匹配
new_lines = replace_layout(layout_lines)
if layout_lines != new_lines:
print(path)
# 重新寫入正則替換后的內容
layout_file = open(layout_file_path, 'w')
layout_file.writelines(new_lines)
pass
# 正則匹配dp、sp值
def replace_layout(search_text):
# 匹配整數倦炒,如10dp显沈,轉成@dimens/dp_10
result = re.sub(r'"(?!(0dp))(\d+)([sd]p)"', r'"@dimen/\3_\2"', search_text)
# 匹配小數,如0.5dp析校,轉成@dimens/dp_0_5
result = re.sub(r'"(\d+)(?:.)(\d+)([sd]p)"', r'"@dimen/\3_\1_\2"', result)
# 匹配負數构罗,如-60dp铜涉,轉成@dimens/dp_m_60
result = re.sub(r'"-(\d+)([sd]p)"', r'"@dimen/\2_m_\1"', result)
return result
if __name__ == '__main__':
replace_res_layout(r'/替換你的工程目錄位置/xxxx')
底部replace_res_layout字符串里修改你對應工程目錄位置,親測在python2.7遂唧、python3.7環(huán)境中可正常運行芙代。
如果碰到dimens.xml沒有定義尺寸怎么辦,比如dp_800盖彭?
很簡單纹烹,只要在dimens.xml一下,然后右鍵工程菜單欄screenmatch重新生成一下即可召边。
/*獲取sp值*/
float pxValue = getResources().getDimension(R.dimen.sp_15);//獲取對應資源文件下的sp值
int spValue = ConvertUtils.px2sp(this, pxValue);//將px值轉換成sp值
mTvShowParams.setTextSize(spValue);//設置文字大小
/*獲取dp值*/
float pxValue2 = getResources().getDimension(R.dimen.dp_360);//獲取對應資源文件下的dp值
int dpValue = ConvertUtils.px2dp(this, pxValue2);//將px值轉換成dp值