今日頭條的安卓適配方案,值得收藏
阿新 • • 發佈:2018-12-04
文章連結,之前確實沒有接觸過,我簡單看了一遍,可以說,這也是相對比較完美的方案,我先簡單說一下這個方案的思路,它是通過修改density值,強行把所有不同尺寸解析度的手機的寬度dp值改成一個統一的值,這樣就解決了所有的適配問題。
比如,設計稿寬度是360px,那麼開發這邊就會把目標dp值設為360dp,在不同的裝置中,動態修改density值,從而保證(手機畫素寬度)px/density這個值始終是360dp,這樣的話,就能保證UI在不同的裝置上表現一致了。
這個方案侵入性很低,而且也沒有涉及私有API,應該也是極不錯的方案,我暫時也想不到強行修改density是否會有其他影響,既然有今日頭條的大廠在用,穩定性應當是有保證的。
但是根據我的觀察,這套方案對老專案是不太友好的,因為修改了系統的density值之後,整個佈局的實際尺寸都會發生改變,如果想要在老專案檔案中使用,恐怕整個佈局檔案中的尺寸都可能要重新按照設計稿修改一遍才行。因此,如果你是在維護或者改造老專案,使用這套方案就要三思了。
具體程式碼實現為:
// 今日頭條的螢幕適配方案 // 通過修改density值,強行把所有不同尺寸解析度的手機的寬度dp值改成一個統一的值,這樣就解決了所有的適配問題 // @param activity // @param application private static float sNoncompatDensity; private static float sNoncompatScaledDensity; public static void setCustomDensity(@NonNull Activity activity, @NonNull final Application application){ DisplayMetrics appDisplayMetrics=application.getResources().getDisplayMetrics(); if (sNoncompatDensity==0){ sNoncompatDensity=appDisplayMetrics.density; sNoncompatScaledDensity=appDisplayMetrics.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() { } }); } float targetDensity=appDisplayMetrics.widthPixels/360; float targetScaleDensity=targetDensity*(sNoncompatScaledDensity/sNoncompatDensity); int targetDensityDpi=(int)(160*targetDensity); appDisplayMetrics.density=targetDensity; appDisplayMetrics.scaledDensity=targetScaleDensity; appDisplayMetrics.densityDpi=targetDensityDpi; final DisplayMetrics activityDisplayMetrics=activity.getResources().getDisplayMetrics(); activityDisplayMetrics.density=targetDensity; activityDisplayMetrics.scaledDensity=targetScaleDensity; activityDisplayMetrics.densityDpi=targetDensityDpi; }