我的以爲今日頭條的適配方案多是最簡單也是開發起來最輕鬆的方案啦!它的核心代碼也就區區幾十行。 這裏我只說下原理,其詳細過程仍是參考今日頭條團隊的文章吧今日頭條適配方案。 經過修改系統的 density, densityDpi,若是不知道這個兩個變量的意思的話請先看 Android 屏幕適配方案。android
首先就是須要尋找兼容的突破口,根據公式 px = density * dp, 在這個公式中可變的是什麼呢? 答案就是:density, 相同或不一樣的屏幕尺寸這個值可能都不一樣。 假定屏幕分辨率爲 1080 * 1920, 若是咱們這裏已知設計稿的 dp = 480, 那麼可得 density = 1080 / 480 = 2.25, dpi = density * 160。 這樣咱們就能夠根據設計稿的設計尺寸,而不假思索的編寫佈局啦。bash
public class BaseUiActivity extends AppCompatActivity {
public static final int WIDTH = 480;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DisplayMetrics appDisplayMetrics = getApplication().getResources().getDisplayMetrics();
// 設計稿的寬的到適配目標的 density, densityDpi
float targetDensity = (float) appDisplayMetrics.widthPixels / WIDTH;
int targetDensityDpi = (int) (targetDensity * 160);
DisplayMetrics activityDisplayMetrics = this.getResources().getDisplayMetrics();
activityDisplayMetrics.density = activityDisplayMetrics.scaledDensity = targetDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
}
複製代碼
若是直接使用上面的代碼進行適配,仍是有問題的,好比在某些設備上字體變小,以及設置字體的大小無效等。 最終解決方案以下:app
// 經過建立基類,若是須要這種適配方案的話就將 Activity 繼承自它便可, 而後就能夠在佈局中愉快的填寫 dp
public class BaseUiActivity extends AppCompatActivity {
public static final int WIDTH = 480;
private float mAppScaleDensity;
private float mAppDensity;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Application app = getApplication();
DisplayMetrics appDisplayMetrics = app.getResources().getDisplayMetrics();
if (mAppDensity == 0) {
mAppDensity = appDisplayMetrics.density;
mAppScaleDensity = appDisplayMetrics.scaledDensity;
app.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig != null && newConfig.fontScale > 0) {
mAppScaleDensity = app.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
// 設計稿的寬的到適配目標的 density, densityDpi
float targetDensity = (float) appDisplayMetrics.widthPixels / WIDTH;
int targetDensityDpi = (int) (targetDensity * 160);
float targetScaleDensity = targetDensity * (mAppScaleDensity / mAppDensity);
// 將適配的 activity 修改成計算事後的值.
DisplayMetrics activityDisplayMetrics = this.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
activityDisplayMetrics.scaledDensity = targetScaleDensity;
}
}
複製代碼
使用以下,這裏這是水平等分十份的 textView。ide
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".UIAdapter3Activity">
<TextView
android:textColor="#ffffff"
android:background="@color/colorAccent"
android:gravity="center"
android:text="1"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="2"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorAccent"
android:gravity="center"
android:text="3"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="4"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorAccent"
android:gravity="center"
android:text="5"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="6"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorAccent"
android:gravity="center"
android:text="7"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="8"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorAccent"
android:gravity="center"
android:text="9"
android:layout_width="48dp"
android:layout_height="48dp" />
<TextView
android:textColor="#ffffff"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="10"
android:layout_width="48dp"
android:layout_height="48dp" />
</LinearLayout>
複製代碼
顯示效果以下: 佈局
固然我這裏只是以寬的緯度來適配,若是要以高的話把上面的代碼拷貝一份改成高便可。通常狀況若是內容過長,高的緯度都採用滾動的方式佈局。post