Andorid の画面適応

Andorid の画面適応

この記事へのリンク: https://blog.csdn.net/feather_wch/article/details/131672378

参考記事:Android適応概要

1. dpiとは何ですか?

  1. 画面のピクセル密度
  2. 1インチあたり160ピクセル、160dpi
  3. dpi = ピクセル/インチ

2. dpとpxの変換

  1. px = dp * (dpi / 160)
  2. 密度: dpi / 160

3. 適応戦略 (幅の割合、高さのアスペクト比)

  1. コントロールの幅は UI デザインのサイズに応じて決まります
  2. コントロールの高さはプルーフのパーセンテージに従って計算されます

Toutiao適応ソリューション

1. dp にパーセント効果を持たせる

  1. px = dp * 密度
  2. 密度の変更 (DisplayMetrics に保存)
  3. アクティビティが開始したら、関連するアダプテーション メソッドを呼び出し、アクティビティとアプリケーションを渡します (2 つの DisplayMetrics が異なる場合に対処するため)。
  4. 非常に軽量

2. DisplayMetrics の重要なプロパティとメソッドは何ですか?

  • widthPixels : 表示デバイスの幅 (ピクセル単位)。
  • heightPixels : デバイスの高さをピクセル単位で表示します。
  • density : デバイスの論理密度を表示します。これは、1 インチあたりのドット数 (dpi) を 160 で割った比率です。
  • densityDpi : デバイスの物理密度をインチあたりのドット数 (dpi) で表示します。
  • scaledDensity : テキストのスケーリングに使用されるデバイスのスケーリング密度を表示します。ユーザーがフォント サイズを変更しない限り、通常は密度と同じです。

3. 濃度を再計算する必要があるため、プルーフは360dpを標準とします

  1. 密度、densityDpi、scaledDensityを計算する
  2. DisplayMetrics セットをアプリケーションとアクティビティに割り当てます
公式:px = dp * density, density = px / dp
新density = DisplayMetrics.widthPixels / 360
公式:density = dpi / 160,dpi = density * 160
新densityDpi = 160 * 新density

// 设置DisplayMetrics
displayDensity.density = 新density
displayDensity.densityDpi = 新densityDpi

4. フォントのスケーリングに大きすぎる、または小さすぎるという問題があります。どのように対処すればよいですか? スケーリングされた密度

  1. scaledDensity は、同じ比率に従って密度密度をスケーリングする必要があります
  2. システムがフォント サイズを変更すると、インターフェイスがトリガーされ、インターフェイスのトリガー後にフォントのscaledDensity を再計算する必要があります。

割合スキーム

5. 割合スキームはどのように実現されますか?

  1. XML ファイルを計算して生成します。異なる解像度の異なる XML ファイルを生成します。
  2. dp、px は、内部で変換される x1、y1 などのパラメータを使用します。

DisplayMetrics のソース コード

1. DisplayMetrics はいつ設定されますか?

  • DisplayMetrics はWindowManagerServiceクラスで設定されます。
SystemServer.java】
private void startOtherServices() {
    
    
    final Context context = mSystemContext;
    WindowManagerService wm = null;
    InputManagerService inputManager = null;
    ...
    //创建WindowManagerService对象
    wm = WindowManagerService.main(context, inputManager,
                mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL,
                !mFirstBoot, mOnlyCore, new PhoneWindowManager());
    //添加到服务管理器
    ServiceManager.addService(Context.WINDOW_SERVICE, wm);
    ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
    ...
    //调用displayReady方法
    wm.displayReady();
    ...
}WMSpublic void displayReady() {
    
    
    synchronized (mWindowMap) {
    
    
        //初始化显示设备
        for (Display display : mDisplays) {
    
    
            DisplayContent displayContent = mRoot.getDisplayContentOrCreate(display.getDisplayId());
            //配置显示策略
            configureDisplayPolicyLocked(displayContent);
            //设置布局标志
            displayContent.layoutNeeded = true;
            //更新方向
            boolean configChanged = updateOrientationFromAppTokensLocked(false);
            //设置临时配置
            mTempConfiguration.setToDefaults();
            mTempConfiguration.fontScale = 1;
            //更新资源配置
            if (configChanged) {
    
    
                mWaitingForConfig = true;
                startFreezingDisplayLocked(false, 0, 0, displayContent);
                //发送配置变化广播
                sendNewConfiguration(display.getDisplayId());
            }
        }
        //初始化输入设备
        mInputMonitor.setUpdateInputWindowsNeededLw();
        performLayoutAndPlaceSurfacesLocked();
        mInputMonitor.updateInputWindowsLw(false /*force*/);
    }
}PhoneWindowManager- WindowManagerPolicy的实现类
private void configureDisplayPolicyLocked(DisplayContent displayContent) {
    
    
    //设置显示设备的初始尺寸和密度
    mPolicy.setInitialDisplaySize(displayContent.getDisplay(),
            displayContent.mBaseDisplayWidth, displayContent.mBaseDisplayHeight,
            displayContent.mBaseDisplayDensity);
    //设置显示设备的overscan区域
    DisplayInfo displayInfo = displayContent.getDisplayInfo();
    mPolicy.setDisplayOverscan(displayContent.getDisplay(),
            displayInfo.overscanLeft, displayInfo.overscanTop,
            displayInfo.overscanRight, displayInfo.overscanBottom);
}PhoneWindowManager- WindowManagerPolicy的实现类
public void setInitialDisplaySize(Display display, int width, int height, int density) {
    
    
    if (display.getDisplayId() == Display.DEFAULT_DISPLAY) {
    
    
        synchronized (mLock) {
    
    
            //初始化真实屏幕大小
            mOverscanScreenWidth = mOverscanScreenHeight = 0;
            mUnrestrictedScreenWidth = width;
            mUnrestrictedScreenHeight = height;
            //初始化DisplayMetrics
            mDisplayWidth = width;
            mDisplayHeight = height;
            mDisplayDensity = density;
            mSystemGestures.screenWidth = width;
            mSystemGestures.screenHeight = height;
        }
        //更新显示区域
        updateOrientationListenerLp();
        updateRotation(true);
    }
}

おすすめ

転載: blog.csdn.net/feather_wch/article/details/131672378