適配完結(jié)篇三 - 超穩(wěn)定的values-wXXXdp適配方案(原創(chuàng))

觀點(diǎn)

  • 適配還是使用百分比布局靠譜, 想一想 百分比 = match_parent其實(shí)值100%, 權(quán)重也是按比例
  • 如何合理建立多套dimen值, 用數(shù)量取勝, 枚舉市場上常見的最小寬度

下圖給的是最原始的鴻洋_的方案:
假設(shè)現(xiàn)在的UI設(shè)計(jì)圖是按照480份數(shù)*320份數(shù)設(shè)計(jì)的弟劲,且上面的寬和高的標(biāo)識(shí)都是px的值着裹,你可以直接將px轉(zhuǎn)化為x[1-320]校读,y[1-480]射沟,這樣寫出的布局基本就可以全分辨率適配了。

按px進(jìn)行劃分真的好嗎

會(huì)有什么問題?

  • 首先得有很多套布局, 這無形會(huì)增加apk體積
  • 很多情況下如果設(shè)備有虛擬按鍵, 由于分辨率是除去虛擬按鍵的寬高適配方式, 據(jù)需要再額外增加大量布局

探索新的方法

突然有一天, 我看到在官網(wǎng)看到了這么一段話: 支持多種屏幕 | Android Developers - 聲明適用于 Android 3.2 的平板電腦布局
于是有了采用sw修飾符來實(shí)現(xiàn)適配的想法. 這就需要采集手頭所有設(shè)備的分辨率并dp化.

  • 640*360 (Mobile)
  • 698*392 (Mobile)
  • 768*480 (Pad)
  • 853*533 (Pad)
  • 960*600 (Pad)
  • 1024*640 (Pad)
  • 1024*768 (Pad)
  • 1280*800 (Pad)

手機(jī)方面除了目前常用的360和392, 再考慮到一些常見的手機(jī)型號(hào)的最小寬度300,320,411,450 這四個(gè)也加上為宜.

還需要考慮哪些因素呢, 比如得考慮平板的虛擬按鍵欄, 所以還得采集具體設(shè)備的參數(shù)
例如平板M2 PLE-703L 在橫屏狀態(tài)下為1920px = 768dp, 但是如果有了虛擬按鍵, 則只剩下1830px = 732dp

取出最小寬度, 最終得到
手機(jī)版的一維數(shù)組:320,320,392,411,450"
Pad版的一維數(shù)組:480,532,640,698,732,768,800,852,912,960,1024,1280

選擇sw<N>dp 還是 w<N>dp修飾符

由于sw取得是最小寬度, 一般情況下采用sw基本夠用. 如果我們在開發(fā)時(shí)候要區(qū)分橫屏或者豎屏, 所以選擇 w<N>dp修飾符更為合適.

  • 針對(duì)豎屏設(shè)備, 取寬度則320,360,392...
  • 針對(duì)橫屏設(shè)備, 取高度則640,698,768...

假如以1280px*800px的設(shè)備, 指定 橫屏狀態(tài) 下, 可以將寬度分成了1280份數(shù), 然后之取出偶數(shù)份(剔除了奇數(shù), 覺得太多余) 1280/2 = 640份數(shù)

# 參考公式
# 假定基準(zhǔn)寬度為1280
x1 = 目標(biāo)寬度(dp) / 1280
x2 = 2 * x1
x4 = 4 * x1
x6 = 6 * x1
...

生成文件夾形如

$ ls
values-w1024dp/  values-w320dp/  values-w640dp/  values-w768dp/  values-w852dp/
values-w1280dp/  values-w480dp/  values-w698dp/  ... ... ...

且每個(gè)文件夾下都有precent_width.xml文件, 以下是values-w640dp下的xml文件

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="x2">1dp</dimen>
    <dimen name="x4">2dp</dimen>
    <dimen name="x6">3dp</dimen>
    <dimen name="x8">4dp</dimen>
    ```
    ```
    <dimen name="x1276">638dp</dimen>
    <dimen name="x1278">639dp</dimen>
    <dimen name="x1280">640dp</dimen>
</resources>

生成工具(參考了鴻洋_的代碼)改編而成

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

/**
 * 輔助生成資源文件
 * 
 * @author leiTKai
 */
public class GenerateValueFiles {
    private static final String dirStr = "./res";
    private static final String FILE_NAME = "precent_width.xml";
    private static final String TEMPLATE = "    <dimen name=\"x%d\">%sdp</dimen>\n";
    private static final String VALUE_TEMPLATE = "values-w%ddp";

    private final int mBaseWidth;
    private final String mSupportStr;

    /**
     * constructor
     * 
     * @param baseX
     *            基準(zhǔn)寬
     * @param supportStr
     */
    public GenerateValueFiles(int baseX, String supportStr) {
        this.mBaseWidth = baseX;
        this.mSupportStr = supportStr;

        System.out.println("baseW: " + this.mBaseWidth);
        System.out.println("supportStr: " + this.mSupportStr);

        File dir = new File(dirStr);
        if (!dir.exists())
            dir.mkdir();
        System.out.print("FileDir: " + dir.getAbsoluteFile());
    }

    public void generate() {
        for (String val : mSupportStr.split(",")) {
            try {
                generateXmlFile(Integer.parseInt(val));
            } catch (IOException e) {
                e.printStackTrace();
                break;
            }
        }
    }

    private void generateXmlFile(final int smallestWidth) throws IOException {
        final File fileDir = new File(dirStr + File.separator
                + String.format(VALUE_TEMPLATE, smallestWidth));
        fileDir.mkdir();

        final File file = new File(fileDir, FILE_NAME);
        Writer writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream(file), "UTF-8"));
        writeContent(writer, mBaseWidth, smallestWidth);
        writer.close();
    }

    private static void writeContent(Writer writer, final int baseLength,
            final int totalLength) throws IOException {
        writer.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
        writer.write("<resources>\n");
        float cell = (float) totalLength / baseLength;
        for (int i = 2; i < baseLength; i+=2) {
            writer.write(String.format(TEMPLATE, i, float2String(cell * i)));
        }
        writer.write(String.format(TEMPLATE, baseLength,
                String.valueOf(totalLength)));
        writer.write("</resources>");
    }

    /**
     * 如果float類型沒有小數(shù)部分則不輸出小數(shù)
     * 
     * @param f
     * @return
     */
    private static String float2String(float f) {
        if (Math.round(f) == f) {
            return String.valueOf((int) f);
        }
        return String.format("%.1f", f);
    }

    public static void main(String[] args) {
        int baseW = 1280;
        String addition = "320,480,532,640,698,732,768,800,852,912,960,1024,1280";
        if (args.length == 1) {
            addition = args[0];
        } else if (args.length == 2) {
            baseW = Integer.parseInt(args[0]);
            addition = args[1];
        }
        new GenerateValueFiles(baseW, addition).generate();
    }
}

平板適配的問題

團(tuán)隊(duì)有沒有專門針對(duì)平板設(shè)計(jì)UI?

  1. 如果有的話, 目前我得到的最小認(rèn)為是安卓Pad的設(shè)備是華為的PLE-703L, 邏輯分辨率為768dp*480dp, 所以我的建議已這個(gè)基準(zhǔn)進(jìn)行設(shè)配. 讓UI出圖.
  2. 平板由于屏幕大應(yīng)該顯示更多的內(nèi)容, 這就要求要設(shè)計(jì)1套以上的布局很費(fèi)事. 對(duì)UI的要求頁很高. 這樣而言如果沒有特殊的要求, 還不如手機(jī)版的一維數(shù)組再一股腦加上 Pad版的一維數(shù)組靠譜.

總結(jié)

  • 該方案不否定使用wrap_content等來布局, 活用布局才是我們追求的
  • 合理的規(guī)避了高度, 要注意設(shè)備的高度方面的些許差異.
  • 可以大膽使用x系列的dimen值, 例如x2, x4這種. 如果字體大小沒特殊要求, 也建議大家使用dp, 如果你真的做了sp的適配.
  • 需要選取以一個(gè)屏幕分辨率作為基板, 建議1920px*1080px為基準(zhǔn)
  • 缺點(diǎn)是還得窮舉所有已知屏幕的寬度, 如果各家安卓廠商的有虛擬按鍵, 寬度則需要適當(dāng)減少一些像素, 這會(huì)導(dǎo)致可能沒有對(duì)應(yīng)的w<N>dp只會(huì)就近取小于等于的dimen值, 但是此方法穩(wěn)定呀.

參考

Android 屏幕適配方案 - CSDN博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子韵洋,更是在濱河造成了極大的恐慌,老刑警劉巖黄锤,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搪缨,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸵熟,警方通過查閱死者的電腦和手機(jī)勉吻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來旅赢,“玉大人,你說我怎么就攤上這事惑惶≈笈危” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵带污,是天一觀的道長僵控。 經(jīng)常有香客問我,道長鱼冀,這世上最難降的妖魔是什么报破? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮千绪,結(jié)果婚禮上充易,老公的妹妹穿的比我還像新娘。我一直安慰自己荸型,他們只是感情好盹靴,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般稿静。 火紅的嫁衣襯著肌膚如雪梭冠。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天改备,我揣著相機(jī)與錄音控漠,去河邊找鬼。 笑死悬钳,一個(gè)胖子當(dāng)著我的面吹牛盐捷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播他去,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼毙驯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了灾测?” 一聲冷哼從身側(cè)響起爆价,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎媳搪,沒想到半個(gè)月后铭段,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秦爆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年序愚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片等限。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡爸吮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出望门,到底是詐尸還是另有隱情形娇,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布筹误,位于F島的核電站桐早,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏厨剪。R本人自食惡果不足惜哄酝,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望祷膳。 院中可真熱鬧陶衅,春花似錦、人聲如沸钾唬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至奕巍,卻和暖如春吟策,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背的止。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國打工檩坚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诅福。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓匾委,卻偏偏與公主長得像,于是被迫代替她去往敵國和親氓润。 傳聞我的和親對(duì)象是個(gè)殘疾皇子赂乐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • Android系統(tǒng)發(fā)布十多年以來,關(guān)于Android的UI的適配一直是開發(fā)環(huán)節(jié)中最重要的問題咖气,但是我看到還是有很多...
    拉丁吳閱讀 58,206評(píng)論 184 438
  • 更新:由于該適配方案越來越多人使用挨措,也有很多人遇到不太理解的問題。所以為了大家更好的使用崩溪,我將文章很多內(nèi)容更新了浅役,...
    蔡振輝閱讀 1,478評(píng)論 0 17
  • 前言 網(wǎng)上關(guān)于屏幕適配的文章已經(jīng)鋪天蓋地了,為什么我還要講伶唯?主要是好記性不如爛筆頭觉既,今天我主要說一下現(xiàn)在流行的屏幕...
    M_M_69ab閱讀 4,969評(píng)論 0 3
  • 由于Android碎片化嚴(yán)重,屏幕分辨率千奇百怪乳幸,而想要在各種分辨率的設(shè)備上顯示基本一致的效果瞪讼,適配成本越來越高。...
    acc8226閱讀 2,943評(píng)論 0 6
  • 今天跟同事聊起孩子小時(shí)候的各種趣事粹断,她小時(shí)候的一件事情突然涌入腦海尝艘。 在她剛上一年級(jí)的那年暑假,我們一...
    星月閣主閱讀 151評(píng)論 0 0