国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Android屏幕適配方案

XboxYan / 2938人閱讀

摘要:下圖為圖標的各個屏幕密度的對應尺寸屏幕密度圖標尺寸解析解析獲取屏幕分辨率信息的三種方法第一種第二種第三種屏幕適配出現的原因什么是像素點屏幕分辨率是指在橫縱向上的像素點數,單位是,個像素點。

目錄介紹

1.屏幕適配定義

2.相關重要的概念

2.1 屏幕尺寸[物理尺寸]

2.2 屏幕分辨率[px]

2.3 屏幕像素密度[dpi]

2.4 dp、dip、dpi、sp、px

2.5 mdpi、hdpi、xdpi、xxdpi

2.6 獲取屏幕分辨率[寬高]

3.Android屏幕適配出現的原因

3.1 什么是像素點

3.2 dp與百分比

4.Android適配問題及本質

4.1 尺寸適配

4.2 代碼適配

4.3 布局適配

4.4 權重適配

4.5 圖片適配

4.6 百分比適配

5.存在問題和困境

5.1 通配符適配困境

5.2 傳統dp適配困境

6.常用解決方案

6.1 今日頭條適配方案

6.2 鴻洋大神庫

6.3 AndroidAutoSize

1.屏幕適配定義

使得某一元素在Android不同尺寸、不同分辨率的手機上具備相同的顯示效果

2.相關重要的概念 2.1 屏幕尺寸[物理尺寸]

含義:手機對角線的物理尺寸

單位:英寸(inch),1英寸=2.54cm

Android手機常見的尺寸有5寸、5.5寸、6寸等等

2.2 屏幕分辨率[px]

含義:手機在橫向、縱向上的像素點數總和

一般描述成屏幕的"寬x高”=AxB

含義:屏幕在橫向方向(寬度)上有A個像素點,在縱向方向 (高)有B個像素點

例子:1080x1920,即寬度方向上有1080個像素點,在高度方向上有1920個像素點

單位:px(pixel),1px=1像素點

Android手機常見的分辨率:720x1280、1080x1920等等

2.3 屏幕像素密度[dpi]

含義:每英寸的像素點數

單位:dpi(dots per ich)

假設設備內每英寸有160個像素,那么該設備的屏幕像素密度=160dpi

屏幕像素密度與屏幕尺寸和屏幕分辨率有關,在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。

dpi計算公式:舉個例子:屏幕分辨率為:1920*1080,屏幕尺寸為5吋的話,那么dpi為440

注意:dpi是根據屏幕真實的分辨率和尺寸來計算的,每個設備都可能不一樣的

2.4 dp[dip]、dpi、sp、px

dp(dip):px = dp * 密度比,都是Density Independent Pixels的縮寫,即密度無關像素

dpi:開方(寬度平方 + 高度平方) / 手機的尺寸;dpi是屏幕像素密度,假如一英寸里面有160個像素,這個屏幕的像素密度就是160dpi

sp: 可以根據文字大小首選項進行放縮,是設置字體大小的御用單位。

px: 像素,px是比較熟悉,前面的分辨率就是用的像素為單位,大多數情況下,比如UI設計、Android原生API都會以px作為統一的計量單位,像素是獲取屏幕寬高等。

問題: dp和px如何換算呢?

px = density * dp;
density = dpi / 160;
px = dp * (dpi / 160);
2.5 mdpi、hdpi、xdpi、xxdpi

2.5.1 作用: mdpi、hdpi、xdpi、xxdpi用來修飾Android中的drawable文件夾及values文件夾,用來區分不同像素密度下的圖片和dimen值。

名稱像                     素密度范圍
ldpi                      0dpi~120dpi
mdpi                      120dpi~160dpi
hdpi                      120dpi~160dpi
xdpi                      160dpi~240dpi
xxdpi                     240dpi~320dpi
xxxdpi                    480dpi~640dpi

Android項目后應該可以看到很多drawable文件夾,分別對應不同的dpi
drawable-ldpi (dpi=120, density=0.75)
drawable-mdpi (dpi=160, density=1)
drawable-hdpi (dpi=240, density=1.5)
drawable-xhdpi (dpi=320, density=2)
drawable-xxhdpi (dpi=480, density=3)
對于五種主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)應按照 2:3:4:6:8 的比例進行縮放。

2.5.2 在進行開發的時候,我們需要把合適大小的圖片放在合適的文件夾里面。下面以圖標設計為例進行介紹

2.5.3 在設計圖標時,對于五種主流的像素密度(MDPI、HDPI、XHDPI、XXHDPI 和 XXXHDPI)應按照 2:3:4:6:8 的比例進行縮放。

例如,一個啟動圖標的尺寸為48x48 dp,這表示在 MDPI 的屏幕上其實際尺寸應為 48x48 px,在 HDPI 的屏幕上其實際大小是 MDPI 的 1.5 倍 (72x72 px),在 XDPI 的屏幕上其實際大小是 MDPI 的 2 倍 (96x96 px),依此類推。

2.5.4 下圖為圖標的各個屏幕密度的對應尺寸:

屏幕密度                 圖標尺寸
mdpi                     48X48px
hdpi                     72X72px
xdpi                     96X96px
xxdpi                    144X144px
xxxdpi                   192X192px
2.6 DisplayMetrics解析

DisplayMetrics解析

獲取屏幕分辨率信息的三種方法:

//第一種
DisplayMetrics metrics = new DisplayMetrics();
Display display = activity.getWindowManager().getDefaultDisplay();
display.getMetrics(metrics);

//第二種
DisplayMetrics metrics= activity.getResources().getDisplayMetrics();

//第三種
Resources.getSystem().getDisplayMetrics();
3.Android屏幕適配出現的原因 3.1 什么是像素點

屏幕分辨率是指在橫縱向上的像素點數,單位是px,1px=1個像素點。

一般以縱向像素橫向像素,如19601080。 由于Android系統的開放性,任何用戶、開發者、OEM廠商、運營商都可以對Android進行定制,修改成他們想要的樣子。 屏幕尺寸這么多,為了讓我們開發的程序能夠比較美觀的顯示在不同尺寸、分辨率、像素密度(這些概念我會在下面詳細講解)的設備上,那就要在開發的過程中進行處理,至于如何去進行處理,這就是我們今天的主題。

3.2 dp與百分比 (網頁前端提供百分比,所以無需適配)

只要記住一點dp是與像素無關的,在實際使用中1dp大約等于1/160inch

那么dp究竟解決了適配上的什么問題?可以看出1dp = 1/160inch;那么它至少能解決一個問題,就是你在布局文件寫某個View的寬和高為160dp160dp,這個View在任何分辨率的屏幕中,顯示的尺寸大小是大約是一致的(可能不精確),大概是 1 inch 1 inch。

1.呈現效果仍舊會有差異,僅僅是相近而已

當設備的物理尺寸存在差異的時候,dp就顯得無能為力了。為4.3寸屏幕準備的UI,運行在5.0寸的屏幕上,很可能在右側和下側存在大量的空白。而5.0寸的UI運行到4.3寸的設備上,很可能顯示不下。

一句話,總結下,dp能夠讓同一數值在不同的分辨率展示出大致相同的尺寸大小。但是當設備的尺寸差異較大的時候,就無能為力了。

4.Android屏幕適配常見方法 4.1 適配常見方法

尺寸適配

dimen適配

布局適配

代碼適配

圖片適配

4.2 尺寸適配 4.2.1 布局文件設置寬高

寬高設置參數:有的時候用dp,有的時候用px,大多數用dp

dp:dp(dip):px = dp * 密度比,與屏幕像素有對應關系,設置成dp后,在不同分辨率的手機上有可能尺寸會不一樣

px:像素,比如小分辨率手機上一像素和大分辨率手機上一像素,所顯示的圖像是不一樣的
理解dp和px之間對應的關系,不同分辨率的手機用不同的dp值來適配

4.2.2 密度比

密度比是固定的,可以查詢文檔Develop—>API Guides—>Best Practices—>Supporting Multiple

mdpi手機:160dpi 是基準線,1px = 1dp * 1,其他手機的密度比 = 自己的dpi/160

代碼獲取密度比:getResources().getDisplayMetrics().density

ldip:120px = 160dp * 0.75
mdpi:160px = 160dp * 1
hdpi:240px = 160dp * 1.5
xhdpi:360px = 180dp * 2

4.2.3 dimen適配

1.在默認的values中的dimens文件下聲明(類似于Strings.xml)

    16dp
    16dp
    160dp



    
    120dip     



    
    220dip     





    
    80dip     

2.在布局文件中引用

3.新建需要適配的values-XXX(比如values-1280x720,注意規范大值在前)

4.在新建values-1280x720中的dimens.xml文件中

* 180dp

5.所有手機適配找對應的默認的dimens

    * 思考:如何計算dpi?如何計算手機密度比?能夠用dp適配所有手機嗎?
    * dp不能適配所有手機;
    * 舉個例子:按鈕占屏幕寬度一半,把寬度設置成160dp,120px和160px和240px可以占屏幕一半,但是360px則小于屏幕一半;
    * 如果把寬度設置成180dp,那么360dp可以占屏幕一半,但其他幾個又不行。
    * 如果要適配所有手機的控件寬度為屏幕寬度的一半,該怎么做呢?用dimen
4.2 代碼適配 4.3 布局適配,有可能在不同的手機布局中,控件排列的位置不一樣

1.位置不一樣

不同的手機在運行的時候選擇不同的布局(布局名稱一樣,類似于dimens),比如:

2.控件不一樣

不能用布局適配了;為什么?

布局能夠實現界面效果,但是完成布局后在代碼中,由于控件都不一樣,所以會找這兩套布局的id,還要做判斷,根據不同的布局做兩套代碼(如果頁面復雜,給控件設置參數等十分繁瑣)

3.適用場景

不同的手機的控件的位置不一樣,發生了位置變化才會用到布局適配,實際開發中用的很少

4.4 權重適配 4.5 圖片適配

1.圖片的查找順序

注意:一般手機 ldpi

注意:mdpi手機 ldpi

適配主流手機,1920 1080 1080 720 800 * 480,高清圖、背景圖(全屏展示)準備多套 。小圖片 準備一套高分辨率的;比如按鈕,圖標等

為了是apk瘦身,有些圖片不要準備多套,Android分辨率種類太多了;即使適配主流手機,展示比較清楚的背景圖(比如:歡迎界面),可以準備多套

2.在小分辨率展示高清圖,放到大分辨率會出現什么情況呢?

比如:你針對800480分辨率手機做了背景圖圖片,正好完全展示;如果把它放到大分辨率1280720上,會對圖片進行拉伸,會使像素點變大,可能會看到鋸齒或者模糊的東西

5.存在問題和困境 5.1 通配符適配困境 5.2 傳統dp適配困境

[摘自頭條]一般我們設計圖都是以固定的尺寸來設計的。比如以分辨率750px 1334px來設計,以density為3來標注,也就是屏幕其實是350dp 667dp。如果想在所有設備上顯示完全一致,其實是不現實的,因為屏幕高寬比不是固定的,各種寬高比層出不窮,寬高比不同,顯示完全一致就不可能了。但是通常下,我們只需要以寬或高一個維度去適配,比如我們Feed是上下滑動的,只需要保證在所有設備中寬的維度上顯示一致即可,再比如一個不支持上下滑動的頁面,那么需要保證在高這個維度上都顯示一致,尤其不能存在某些設備上顯示不全的情況。同時考慮到現在基本都是以dp為單位去做的適配,如果新的方案不支持dp,那么遷移成本也非常高。

因此,總結下大致需求如下:

支持以寬或者高一個維度去適配,保持該維度上和設計圖一致;注意是某一個維度

支持dp和sp單位,控制遷移成本到最小。

6.常用適配框架 6.1 今日頭條適配方案 6.1.1 兼容突破口

從dp和px的轉換公式 :px = dp * density

可以看出,如果設計圖寬為360dp,想要保證在所有設備計算得出的px值都正好是屏幕寬度的話,我們只能修改 density 的值。

//在xml中使用何種尺寸單位(dp、sp、pt、in、mm),最后在繪制時都會給我們轉成px!
public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
    switch (unit) {
        case COMPLEX_UNIT_PX:
            return value;
        case COMPLEX_UNIT_DIP:
            return value * metrics.density;
        case COMPLEX_UNIT_SP:
            return value * metrics.scaledDensity;
        case COMPLEX_UNIT_PT:
            return value * metrics.xdpi * (1.0f/72);
        case COMPLEX_UNIT_IN:
            return value * metrics.xdpi;
        case COMPLEX_UNIT_MM:
            return value * metrics.xdpi * (1.0f/25.4f);
        }
    return 0;
}
6.1.2 頭條適配方案核心代碼
public static void setCustomDensity(Activity activity, Application application) {
    DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
    if (sNoncompatDensity == 0) {
        // 系統的Density
        sNoncompatDensity = displayMetrics.density;
        // 系統的ScaledDensity
        sNoncompatScaledDensity = displayMetrics.scaledDensity;
        // 監聽在系統設置中切換字體
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                if (newConfig != null && newConfig.fontScale > 0) {
                    sNoncompatScaledDensity=application.getResources().getDisplayMetrics().scaledDensity;
                }
            }

            @Override
            public void onLowMemory() {

            }
        });
    }
    // 公司UI尺寸是750px-1334px,此處以375dp的設計圖作為例子
    float targetDensity=displayMetrics.widthPixels/375;
    float targetScaledDensity=targetDensity*(sNoncompatScaledDensity/sNoncompatDensity);
    int targetDensityDpi= (int) (160 * targetDensity);
    displayMetrics.density = targetDensity;
    displayMetrics.scaledDensity = targetScaledDensity;
    displayMetrics.densityDpi = targetDensityDpi;

    DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
    activityDisplayMetrics.density = targetDensity;
    activityDisplayMetrics.scaledDensity = targetScaledDensity;
    activityDisplayMetrics.densityDpi = targetDensityDpi;
}
6.1.3 頭條適配方案注意事項

寬度適配就已經完成啦,只需要在Activity中調用就行了,必須在setContentView()之前!

如果需要適配高度,頭條指出只要按照同樣的方法做高度適配就可以了!

實現思路:假設設計圖寬度是360dp,以寬維度來適配,那么適配后的 density = 設備真實寬(單位px) / 360,接下來只需要把我們計算好的 density 在系統中修改下即可

遇到的問題:

1.如果某個頁面不想適配該方案,該如何處理

2.滾動頁面以寬為維度適配,而某些頁面則是以高為維度適配,這種情況怎么辦?

3.針對第三方庫有何更好的方案,比如支付寶支付彈窗,或者第三方客服聊天頁面如何處理適配

6.1.4 頭條適配工具類,暫時只是用作測試項目

關于該工具類,已經用于測試項目中,逐步完善,項目可以參考:https://github.com/yangchong2...

public class ScreenDensityUtils {


    /*
     * 1.先在application中使用setup()方法初始化一下
     * 2.手動在Activity中調用match()方法做適配,必須在setContentView()之前
     * 3.建議使用dp做寬度適配,大多數時候寬度適配才是主流需要
     * 4.個人覺得在寫布局的時候,可以多用dp,如果是使用px,建議轉化成dp
     * 5.入侵性很低,不需要改動原來的代碼
     */


    /**
     * 屏幕適配的基準
     */
    private static final int MATCH_BASE_WIDTH = 0;
    private static final int MATCH_BASE_HEIGHT = 1;
    /**
     * 適配單位
     */
    private static final int MATCH_UNIT_DP = 0;
    private static final int MATCH_UNIT_PT = 1;

    // 適配信息
    private static MatchInfo sMatchInfo;
    // Activity 的生命周期監測
    private static Application.ActivityLifecycleCallbacks mActivityLifecycleCallback;

    private ScreenDensityUtils() {
        throw new UnsupportedOperationException("u can"t instantiate me...");
    }

    /**
     * 初始化
     * @param application                   需要在application中初始化
     */
    public static void setup(@NonNull final Application application) {

        /*
        //獲取屏幕分辨率信息的三種方法
        //第一種
        DisplayMetrics metrics = new DisplayMetrics();
        Display display = activity.getWindowManager().getDefaultDisplay();
        display.getMetrics(metrics);
        //第二種
        DisplayMetrics metrics= activity.getResources().getDisplayMetrics();
        //第三種
        Resources.getSystem().getDisplayMetrics();
        */

        //注意這個是獲取系統的displayMetrics
        final DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
        if (sMatchInfo == null) {
            // 記錄系統的原始值
            sMatchInfo = new MatchInfo();
            sMatchInfo.setScreenWidth(displayMetrics.widthPixels);
            sMatchInfo.setScreenHeight(displayMetrics.heightPixels);
            sMatchInfo.setAppDensity(displayMetrics.density);
            sMatchInfo.setAppDensityDpi(displayMetrics.densityDpi);
            sMatchInfo.setAppScaledDensity(displayMetrics.scaledDensity);
            sMatchInfo.setAppXdpi(displayMetrics.xdpi);
        }
        // 添加字體變化的監聽
        // 調用 Application#registerComponentCallbacks 注冊下 onConfigurationChanged 監聽即可。
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                // 字體改變后,將 appScaledDensity 重新賦值
                if (newConfig != null && newConfig.fontScale > 0) {
                    float scaledDensity = displayMetrics.scaledDensity;
                    sMatchInfo.setAppScaledDensity(scaledDensity);
                }
            }

            @Override
            public void onLowMemory() {

            }
        });
    }

    /**
     * 在 application 中全局激活適配(也可多帶帶使用 match() 方法在指定頁面中配置適配)
     */
    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static void register(@NonNull final Application application, final float designSize, final int matchBase, final int matchUnit) {
        if (mActivityLifecycleCallback == null) {
            mActivityLifecycleCallback = new Application.ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    if (activity != null) {
                        match(activity, designSize, matchBase, matchUnit);
                    }
                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityResumed(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {

                }
            };
            application.registerActivityLifecycleCallbacks(mActivityLifecycleCallback);
        }
    }

    /**
     * 全局取消所有的適配
     */
    @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static void unregister(@NonNull final Application application, @NonNull int... matchUnit) {
        if (mActivityLifecycleCallback != null) {
            application.unregisterActivityLifecycleCallbacks(mActivityLifecycleCallback);
            mActivityLifecycleCallback = null;
        }
        for (int unit : matchUnit) {
            cancelMatch(application, unit);
        }
    }


    /**
     * 適配屏幕(放在 Activity 的 setContentView() 之前執行)
     *
     * @param context                               上下文
     * @param designSize                            設計圖的尺寸
     */
    public static void match(@NonNull final Context context, final float designSize) {
        match(context, designSize, MATCH_BASE_WIDTH, MATCH_UNIT_DP);
    }


    /**
     * 適配屏幕(放在 Activity 的 setContentView() 之前執行)
     *
     * @param context                               上下文
     * @param designSize                            設計圖的尺寸
     * @param matchBase                             適配基準
     */
    public static void match(@NonNull final Context context, final float designSize, int matchBase) {
        match(context, designSize, matchBase, MATCH_UNIT_DP);
    }

    /**
     * 適配屏幕(放在 Activity 的 setContentView() 之前執行)
     *
     * @param context                               上下文
     * @param designSize                            設計圖的尺寸
     * @param matchBase                             適配基準
     * @param matchUnit                             使用的適配單位
     */
    private static void match(@NonNull final Context context, final float designSize, int matchBase, int matchUnit) {
        if (designSize == 0) {
            throw new UnsupportedOperationException("The designSize cannot be equal to 0");
        }
        if (matchUnit == MATCH_UNIT_DP) {
            matchByDP(context, designSize, matchBase);
        } else if (matchUnit == MATCH_UNIT_PT) {
            matchByPT(context, designSize, matchBase);
        }
    }

    /**
     * 重置適配信息,取消適配
     */
    public static void cancelMatch(@NonNull final Context context) {
        cancelMatch(context, MATCH_UNIT_DP);
        cancelMatch(context, MATCH_UNIT_PT);
    }

    /**
     * 重置適配信息,取消適配
     *
     * @param context                       上下文
     * @param matchUnit                     需要取消適配的單位
     */
    private static void cancelMatch(@NonNull final Context context, int matchUnit) {
        if (sMatchInfo != null) {
            final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
            if (matchUnit == MATCH_UNIT_DP) {
                if (displayMetrics.density != sMatchInfo.getAppDensity()) {
                    displayMetrics.density = sMatchInfo.getAppDensity();
                }
                if (displayMetrics.densityDpi != sMatchInfo.getAppDensityDpi()) {
                    displayMetrics.densityDpi = (int) sMatchInfo.getAppDensityDpi();
                }
                if (displayMetrics.scaledDensity != sMatchInfo.getAppScaledDensity()) {
                    displayMetrics.scaledDensity = sMatchInfo.getAppScaledDensity();
                }
            } else if (matchUnit == MATCH_UNIT_PT) {
                if (displayMetrics.xdpi != sMatchInfo.getAppXdpi()) {
                    displayMetrics.xdpi = sMatchInfo.getAppXdpi();
                }
            }
        }
    }


    public static MatchInfo getMatchInfo() {
        return sMatchInfo;
    }


    /**
     * 使用 dp 作為適配單位(適合在新項目中使用,在老項目中使用會對原來既有的 dp 值產生影響)
     * 
*
    * dp 與 px 之間的換算: *
  • px = density * dp
  • *
  • density = dpi / 160
  • *
  • px = dp * (dpi / 160)
  • *
* * @param context 上下文 * @param designSize 設計圖的寬/高(單位: dp) * @param base 適配基準 */ private static void matchByDP(@NonNull final Context context, final float designSize, int base) { final float targetDensity; if (base == MATCH_BASE_WIDTH) { targetDensity = sMatchInfo.getScreenWidth() * 1f / designSize; } else if (base == MATCH_BASE_HEIGHT) { targetDensity = sMatchInfo.getScreenHeight() * 1f / designSize; } else { targetDensity = sMatchInfo.getScreenWidth() * 1f / designSize; } final int targetDensityDpi = (int) (targetDensity * 160); final float targetScaledDensity = targetDensity * (sMatchInfo.getAppScaledDensity() / sMatchInfo.getAppDensity()); final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); displayMetrics.density = targetDensity; displayMetrics.densityDpi = targetDensityDpi; displayMetrics.scaledDensity = targetScaledDensity; } /** * 使用 pt 作為適配單位(因為 pt 比較冷門,新老項目皆適合使用;也可作為 dp 適配的補充, * 在需要同時適配寬度和高度時,使用 pt 來適配 dp 未適配的寬度或高度) *
*

pt 轉 px 算法: pt * metrics.xdpi * (1.0f/72)

* * @param context 上下文 * @param designSize 設計圖的寬/高(單位: pt) * @param base 適配基準 */ private static void matchByPT(@NonNull final Context context, final float designSize, int base) { final float targetXdpi; if (base == MATCH_BASE_WIDTH) { targetXdpi = sMatchInfo.getScreenWidth() * 72f / designSize; } else if (base == MATCH_BASE_HEIGHT) { targetXdpi = sMatchInfo.getScreenHeight() * 72f / designSize; } else { targetXdpi = sMatchInfo.getScreenWidth() * 72f / designSize; } final DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); displayMetrics.xdpi = targetXdpi; } /** * 適配信息 */ private static class MatchInfo { private int screenWidth; private int screenHeight; private float appDensity; private float appDensityDpi; private float appScaledDensity; private float appXdpi; int getScreenWidth() { return screenWidth; } void setScreenWidth(int screenWidth) { this.screenWidth = screenWidth; } int getScreenHeight() { return screenHeight; } void setScreenHeight(int screenHeight) { this.screenHeight = screenHeight; } float getAppDensity() { return appDensity; } void setAppDensity(float appDensity) { this.appDensity = appDensity; } float getAppDensityDpi() { return appDensityDpi; } void setAppDensityDpi(float appDensityDpi) { this.appDensityDpi = appDensityDpi; } float getAppScaledDensity() { return appScaledDensity; } void setAppScaledDensity(float appScaledDensity) { this.appScaledDensity = appScaledDensity; } float getAppXdpi() { return appXdpi; } void setAppXdpi(float appXdpi) { this.appXdpi = appXdpi; } } }
6.2 鴻洋大AutoLayout框架

我記得上上一個公司的項目投資界就是用的這個屏幕適配庫……哈哈

該庫的想法非常好:對照設計圖,使用px編寫布局,不影響預覽;繪制階段將對應設計圖的px數值計算轉換為當前屏幕下適配的大小;為簡化接入,inflate時自動將各Layout轉換為對應的AutoLayout,從而不需要在所有的xml中更改。但是同時該庫也存在以下等問題:

擴展性較差。對于每一種ViewGroup都要對應編寫對應的AutoLayout進行擴展,對于各View的每個需要適配的屬性都要編寫代碼進行適配擴展;

在onMeasure階段進行數值計算。消耗性能,并且這對于非LayoutParams中的屬性存在較多不合理之處。比如在onMeasure時對TextView的textSize進行換算并setTextSize,那么玩家在代碼中動態設置的textSize都會失效,因為在每次onMesasure時都會重新被AutoLayout重新設置覆蓋。

issue較多并且作者已不再維護。

個人覺得AutoLayout的設計思想非常優秀,但是將LayoutParams與屬性作為切入口在mesure過程中進行轉換計算的方案存在效率與擴展性等方面的問題。那么Android計算長度的收口在哪里,能不能在Android計算長度時進行換算呢?如果能在Android計算長度時進行換算,那么就不需要一系列多余的計算以及適配,一切問題就都迎刃而解了

6.3 AndroidAutoSize

已經用于現在正式庫,代碼量多,且注釋也比較項目,作者更新很頻繁,極力維護并解決bug,非常不錯!

關于其他內容介紹 01.關于博客匯總鏈接

1.技術博客匯總

2.開源項目匯總

3.生活博客匯總

4.喜馬拉雅音頻匯總

5.其他匯總

02.關于我的博客

我的個人站點:www.yczbj.org,www.ycbjie.cn

github:https://github.com/yangchong211

知乎:https://www.zhihu.com/people/...

簡書:http://www.jianshu.com/u/b7b2...

csdn:http://my.csdn.net/m0_37700275

喜馬拉雅聽書:http://www.ximalaya.com/zhubo...

開源中國:https://my.oschina.net/zbj161...

泡在網上的日子:http://www.jcodecraeer.com/me...

郵箱:yangchong211@163.com

阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV

segmentfault頭條:https://segmentfault.com/u/xi...

03.參考博客

一種極低成本的Android屏幕適配方式:https://mp.weixin.qq.com/s/d9...

Android 屏幕適配從未如斯簡單:https://juejin.im/post/5b6250...

今日頭條適配方案:https://www.jianshu.com/p/55e...

Android 目前最穩定和高效的UI適配方案:https://www.jianshu.com/p/a4b...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77124.html

相關文章

  • Android屏幕適配方案分析

    摘要:下面來看看常見的三種比較成熟的屏幕適配方案,并分析這幾種方案的優劣。屏幕適配方案寬高限定符適配設定一個基準的分辨率,也就是設計圖對應的分辨率,其他分辨率都根據這個基準分辨率來計算,在不同的尺寸文件夾內部,根據該尺寸編寫對應的文件。 為什么要屏幕適配 Android開發過程中我們常用的尺寸單位有px、dp,還有一種sp一般是用于字體的大小。但是由于px是像素單位,比如我們通常說的手機分辨...

    Achilles 評論0 收藏0
  • Android屏幕適配方案

    摘要:下圖為圖標的各個屏幕密度的對應尺寸屏幕密度圖標尺寸解析解析獲取屏幕分辨率信息的三種方法第一種第二種第三種屏幕適配出現的原因什么是像素點屏幕分辨率是指在橫縱向上的像素點數,單位是,個像素點。 目錄介紹 1.屏幕適配定義 2.相關重要的概念 2.1 屏幕尺寸[物理尺寸] 2.2 屏幕分辨率[px] 2.3 屏幕像素密度[dpi] 2.4 dp、dip、dpi、sp、px 2.5 md...

    Sourcelink 評論0 收藏0
  • 屏幕適配全方位解析

    摘要:需要注意的是,這種通過限定符分辨屏幕尺寸的方法,適用于之前。這種最小寬度限定符適用于之后,所以如果要適配全部的版本,就要使用限定符和文件同時存在于項目目錄下。 1.屏幕適配概念 而隨著支持Android系統的設備(手機、平板、電視、手表)的增多,設備碎片化、品牌碎片化、系統碎片化、傳感器碎片化和屏幕碎片化的程度也在不斷地加深。而我們今天要探討的,則是對我們開發影響比較大的——屏幕的碎片...

    mochixuan 評論0 收藏0

發表評論

0條評論

XboxYan

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<