今日头条屏幕适配方案
程序员文章站
2022-05-24 13:23:55
...
今日头条屏幕适配方案
一句话概括实现原理:
根据设计图宽度,算出density(可以理解为密度),继而算出dpi,替换系统中的dpi.则布局文件即可按照UI所给设计图设置宽度.就可达到屏幕适配的目的。简单,粗暴,有效。我都测试过了,非常完美解决,直接上图
下图分别是在分辨率为768X1280和1080X1920的手机上测试的结果:(- 注意:未做适配之前如下图)
UI图为尺寸为1334X750,
下图分别是在分辨率为768X1280和1080X1920的手机上测试的结果:(- 注意:适配之后如下图)
UI图为尺寸为1334X750,
完美,先来看下布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<TextView
android:layout_width="200dp"
android:layout_height="match_parent"
android:background="#00ff00"
android:gravity="center"
android:text="200dp"
android:textColor="@android:color/white" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<TextView
android:layout_width="175dp"
android:layout_height="match_parent"
android:background="@color/colorAccent"
android:gravity="center"
android:text="175dp"
android:textColor="@android:color/white" />
</LinearLayout>
</LinearLayout>
显而易见,使用2个TextView做对比,设置固定的宽度,在分辨率不同的手机展示了相同的效果。
关键类
public class Density {
private static float appDensity;
private static float appScaledDensity;
private static DisplayMetrics appDisplayMetrics;
private static float WIDTH;
public static void setDensity(@NonNull final Application application, float width) {
appDisplayMetrics = application.getResources().getDisplayMetrics();
WIDTH = width;
registerActivityLifecycleCallbacks(application);
if (appDensity == 0) {
appDensity = appDisplayMetrics.density;
appScaledDensity = appDisplayMetrics.scaledDensity;
application.registerComponentCallbacks(new ComponentCallbacks() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
if (newConfig != null && newConfig.fontScale > 0) {
appScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
}
}
@Override
public void onLowMemory() {
}
});
}
}
private static void setDefault(Activity activity) {
setAppOrientation(activity);
}
private static void setAppOrientation(@Nullable Activity activity) {
float targetDensity = 0;
try {
targetDensity = appDisplayMetrics.widthPixels / WIDTH;
} catch (NumberFormatException e) {
e.printStackTrace();
}
float targetScaledDensity = targetDensity * (appScaledDensity / appDensity);
int targetDensityDpi = (int) (160 * targetDensity);
DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
activityDisplayMetrics.density = targetDensity;
activityDisplayMetrics.scaledDensity = targetScaledDensity;
activityDisplayMetrics.densityDpi = targetDensityDpi;
}
private static void registerActivityLifecycleCallbacks(Application application) {
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
setDefault(activity);
}
@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这个类里面通过Density.setDensity(this, 375f);来修改系统dip值,375f这个值,是根据UI图尺寸计算出来的,这里UI图为尺寸为1334X750,我参照的是xhdip的图进行绘制的,2px=1dp,375这个值就是宽度的像素750px/2px=375dp;