Android自動適配工具

** 1、問題來了 **

在上一篇文章中,我們講述了一個利用values-wNdp資源路徑命名的方式來做分辨率的適配的方案;
理論上來說,我們只需要配置values-w360dp的資源文件就好了,但是我們無法預(yù)估廠商的行為,以及一些怪異的配置,還得考慮兼容240dp ,270dp ,320dp,400dp等設(shè)備;
作為一個高效(偷懶)的程序員,我們明顯不會傻乎乎的在每個路徑下都計算dimens后加入進(jìn)去,我們想要一個雙擊就能生成多套配置文件的方案。

** 2、新的解決方案**

解決問題的思路是這個樣子的:

  • 根據(jù)UI設(shè)計圖,我們先在values下面寫一套默認(rèn)配置文件dimens.xml;
  • 從dimens.xml 文件夾中讀取每個 dimens配置的name 和 value,存到一個list中 ;
  • 根據(jù)需要適配的設(shè)備配置,重新計算每個dimens 對應(yīng)的值,形成一個新的值,存到新的newList中;
  • 根據(jù)xml文檔結(jié)構(gòu),將newList中的值重新拼接,形成一個字符串,寫入到新的目錄下的values.xml文件中。

** 3、代碼走讀**

3.1 代碼結(jié)構(gòu)
- Config.java
- DimensCreator.java
- DimensParser.java
- DimensValues.java
- Test

3.2 Test.java--入口主控類,讀取默認(rèn)配置文件,生成多套適配文件;
<code>
DimensParser parser = new DimensParser();
List<DimenValues> list = parser.parse(new FileInputStream(Config.path + File.separator + "dimens.xml"));
DimensCreator creator = new DimensCreator(Config.path, list);creator.createAll();</code>
3.3 Config.java
<code>public class Config {
//需要適配的設(shè)備配置
public final static int[] supportDevices = {240, 270, 320, 360, 400};
//dimens.xml 計算基礎(chǔ) 360dp public final static int defaultValue = 360;
//values 文件夾路徑 。默認(rèn)在此路徑下存放dimens.xml
public final static String path = "D:\app\src\main\res\values" ;
}</code>
3.4 DimensParser.java 解析values/dimens.xml文件 ,讀取數(shù)據(jù)到內(nèi)存中
<code>
private class InnerHandler extends DefaultHandler {
private DimenValues dimenValues;
private StringBuilder stringBuilder = new StringBuilder();
private String tempName;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (qName.equals("dimen")) {
tempName = qName;
dimenValues = new DimenValues();
stringBuilder.setLength(0);
dimenValues.name = attributes.getValue("name");
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equals("dimen")) {
list.add(dimenValues);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
stringBuilder.append(ch, start, length);
if (tempName != null && tempName.equals("dimen")) {
dimenValues.value = stringBuilder.toString();
}
}
}</code>
3.5 DimensCreator.java
3.5.1 xml 文件生成模塊:
<code>
private final String xmlHeader = "<?xml version="1.0" encoding="utf-8"?>\n" + "<resources>";
private final String xmlFooter = "</resources>";
private final String DIRTEMPLATE = "values-w%sdp";
private final String dimenTemplate = "<dimen name="%s">%sdp</dimen>";</code>
3.5.2 根據(jù)需要適配的設(shè)備,遍歷生成多個文件
<code>public void createAll() {
for (int i : Config.supportDevices) {
//生成values-wNdp的資源目錄
String dir = DIRPath.replace("values", "").trim() + File.separator + String.format(DIRTEMPLATE, "" + i);
File dirFile = new File(dir);
if (!dirFile.exists()) {
dirFile.mkdirs();
}
//在values-wNdp的資源目錄生成文件
File file = new File(dirFile.getPath() + File.separator + "dimens.xml");
//dimens 值計算時候的比例
float scale = (float) i / Config.defaultValue;
createSingleFile(file, scale);
}}</code>
3.5.3 重新計算value ,寫入文件中
<code>
//寫入xml文件頭
String data = xmlHeader;for (DimenValues values : list) {
String itemValue = values.value;
//計算新的dp值
if (values.value.contains("dp")) {
float v = Float.parseFloat(values.value.replace("dp", "").trim());
itemValue = formatDimen(v * scale);
}
//拼接每一行的dimen值
String itemData = String.format(dimenTemplate, values.name, itemValue) + "\n";
data += itemData;
}
//寫入xml文件尾部
data += xmlFooter;FileOutputStream outputStream = null;
ByteArrayInputStream inputStream = null;
try {
outputStream = new FileOutputStream(file);
inputStream = new ByteArrayInputStream(data.getBytes());
byte[] buffer = new byte[inputStream.available()];
while (inputStream.read(buffer) != -1) {
outputStream.write(buffer);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();}
}</code>

4、友情提示

  1. 代碼中的dimen最好不要用模塊相關(guān)名稱命名,采用中性化命名,比如dimenSize_180dp ;對應(yīng)w360dP設(shè)備的時候等于180dp,w320dP設(shè)備的時候等于160dp......
  2. 完整代碼地址:源碼地址
  3. 如果有特殊需求,請自行閱讀代碼,然后根據(jù)自己需求修改完善
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容