dimens檔案生成器
阿新 • • 發佈:2018-11-09
問題來源:自己做了一個應用,UI發過來互動文件中的尺寸單位都是px,而google推薦dp,同時為了適配不同螢幕,需要從新計算,為了減少重複性工作,該指令碼孕育而生。
實現方案:就是dimens.xml檔案中寫入UI互動文件大小,此時單位為px。通過遍歷該檔案,如果單位為px,就進行換算,如果是其他單位,如dp,就保持原來數值。關鍵就是px 與dp 換算,換算公式很簡單,但是如何獲取手機dpi 和資料夾命名就需要思考。本人採用adb 獲取螢幕大小和dpi 資訊,這樣只要插入手機執行該指令碼就能自動生成適配的values-xxx/dimens.xml檔案,值得注意的地方是adb 獲取螢幕大小,需要調換生成資料夾名。
注意
效果圖:
GenerateDimensFile.py
#coding=utf-8
#author=ao.deng
import os
import subprocess
from xml.dom.minidom import Document
import xml.dom.minidom
import collections
import re
class GenerateDimensFile:
def __init__(self):
self.xmlStringdict = collections.OrderedDict() # xml儲存
self.displaysSizeInfo=''
self.nDipInfo=0
def getCmdEexcuteResult(self,cmd):
ps = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
data =ps.stdout.readlines()
return data
def getInfoByADB(self):
cmd ="adb shell dumpsys window displays"
data =self.getCmdEexcuteResult(cmd)
row=0;
for item in data:
item = item.decode("utf-8").strip(" ").strip("\r\n")
if item=='Display: mDisplayId=0':
break
row+=1
needData=data[row+1]
dataList=needData.decode("utf-8").split(" ")
print(dataList)
self.nDipInfo=int(dataList[5].replace("dpi",""))
sizeInfo=dataList[6].replace("cur=","").split("x")
self.displaysSizeInfo=sizeInfo[1]+"x"+sizeInfo[0]
def px2dp(slef,px):
dp=int(px/(slef.nDipInfo/160))
return dp
def dp2px(slef,dp):
px=int(dp*(slef.nDipInfo/160))
return px
def getXmlNodeValue(self, childNodes):
value = ''
for childNode in childNodes:
if childNode.nodeName == '#text':
value = value + childNode.wholeText
# return childNode.wholeText
value_key = ''
if childNode.nodeName != '#text' and childNode.nodeName != '#comment':
attributeDict = childNode._attrs
if attributeDict != None:
for k, v in attributeDict.items():
value_key = value_key + ' %s="%s" ' % (k, childNode.getAttribute(k))
text = self.getXmlNodeValue(childNode.childNodes)
# print (text)
value = value + "<%s%s>%s</%s>" % (childNode.nodeName, value_key, text, childNode.nodeName)
# print(value)
return value
def parse_xml_file(self, xml_fname):
try:
DOMTree = xml.dom.minidom.parse(xml_fname)
collection = DOMTree.documentElement
stringList = collection.getElementsByTagName("dimen")
for string in stringList:
if string.hasAttribute("name"):
key = string.getAttribute("name")
print("name: %s" % key)
value = self.getXmlNodeValue(string.childNodes)
print("value: %s" % value)
self.xmlStringdict[key] = value
return True
except Exception as e:
print(e)
return False
def build_xml_file(self,saveRootPath):
if not os.path.exists(saveRootPath):
os.mkdir(saveRootPath)
if not os.path.exists(saveRootPath+"/"+"values-" + self.displaysSizeInfo):
os.mkdir(saveRootPath+"/"+"values-" + self.displaysSizeInfo)
try:
impl = xml.dom.minidom.getDOMImplementation()
doc = impl.createDocument(None, 'resources', None)
resources = doc.documentElement
for key, value in self.xmlStringdict.items():
if value[-2:]=="px":
nValue=self.px2dp(int(value[:-2]))
sVvalue ="%ddp"%nValue #螢幕匹配
else:
sVvalue=value
stringele = doc.createElement("dimen")
stringele.setAttribute("name", key)
text = doc.createTextNode(sVvalue)
stringele.appendChild(text)
resources.appendChild(stringele)
uglyXml = doc.toprettyxml(indent=' ', encoding='utf-8')
uglyXml = str(uglyXml, encoding="utf8")
if uglyXml:
uglyXml = uglyXml.replace("&", "&").replace("<", "<"). \
replace(""", "\"").replace(">", ">")
text_re = re.compile('>\n\s+([^<>\s].*?)\n\s+</', re.DOTALL)
prettyXml = text_re.sub('>\g<1></', uglyXml)
print(prettyXml)
self.xmlfd = open(os.path.join(saveRootPath+"/"+"values-" + self.displaysSizeInfo,"dimens.xml"), 'w', encoding='utf-8')
# doc.writexml(self.xmlfd,addindent=' ',newl='\n',encoding="utf-8")
self.xmlfd.write(prettyXml)
self.xmlfd.close()
print("xml生成成功")
return "xml生成成功"
except Exception as e:
print(str(e))
return "xml生成失敗"
if __name__=="__main__":
mGenerateDimensFileHelper = GenerateDimensFile()
mGenerateDimensFileHelper.getInfoByADB()
mGenerateDimensFileHelper.parse_xml_file(r"E:\python_work\GenerateDimensFile\values\dimens.xml")
mGenerateDimensFileHelper.build_xml_file(r"E:\python_work\GenerateDimensFile\values")