ダークモードについて

AndroidクライアントAndroidQはダークモードのサポートを開始しました。また、エクスペリエンスも非常に優れているため、多くの大規模なアプリもこれに適応します。適応には2つの方法があります。

1カスタムメソッド:ナイトファイルのセットを追加し、UIデザインに従ってドローアブル、色、スタイルなどをパーソナライズします。

  利点:ニーズに応じて目的の効果を達成できます

 短所:少し複雑になる可能性があります。古いプロジェクトの場合、特に色の命名が標準化されていないか、コンポーネントが多すぎると、非常に面倒です。さらに悪いことに、サードパーティベンダーが提供するコンポーネントに依存します。

2.自氏は強制的に暗くなります。<itemname = "android:forceDarkAllowed" tools:targetApi = "q"> true </ item> 

  利点:シンプルで、効果はかなり良いです。

  短所:パーソナライズされた適応を助長しません。

 

1.カスタマイズされた方法:

1.関連するリソースファイルに対応する新しいファイルセットを追加します。次の図を参照してください。

たとえば、valuesのcolors.xmlとvalues-nightのcolors.xmlは一貫性が保たれていますが、同じ名前がこれら2つのリソースの異なる色の値に対応しています。同じことが他のドローアブルスタイルにも当てはまります。AppThemeのテーマを次のように変更する必要があるだけです。

<style name="AppCompatTheme" parent="Theme.AppCompat.DayNight">

2.監視システムのダークモードスイッチ:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    int mSysThemeConfig = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
    switch (mSysThemeConfig) {
        // 亮色主题
        case Configuration.UI_MODE_NIGHT_NO:
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            recreate();
            break;
        // 深色主题
        case Configuration.UI_MODE_NIGHT_YES:
            AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            recreate();
            break;
    }

}

注:構成ファイルでアクティビティのプロパティを構成してください:android:configChanges = "uiMode"

このとき、APPのシステムダークモードスイッチを切り替えると、APPはこのページでrecreate()を実行し、コードで設定されたモードに従って、夜間に対応するリソースファイルをロードするかリソースをロードするかを一致させます暗闇を実現するために、通常モードでファイルします。適応の目的。  

注意:1。色の名前は、色に直接リンクできます。例:<color name = "color_55000000">#55000000 </ color>。ダークモードの場合、1つの色を指す複数の名前に名前を付けることができます。別々に、次に、次のように一緒にポイントします。

複数の人が一緒に適応する場合、起こりうる衝突を避けるために、特別な適応を自分の個人的な領域に別々に書くことができます。

2.コードで動的に使用される色と画像リソースに注意を払い、適応することを忘れないでください。

3.プロジェクトのコンポーネント。コンポーネント内の色やリソースファイルなどに接頭辞などを付けて名前を付ければ、メインプロジェクトと競合することはありません。現時点では、drawableに対応するcolors.xmlとスタイルと夜を調整するだけで済みます。メインプロジェクトの夜の下。ただし、名前に一貫性がない場合は、適応の競合が発生するため、この時点でコンポーネントまたはメインプロジェクトの競合を変更する必要があります。もちろん、メインプロジェクトのようなコンポーネントでナイトファイルのセットを取得することもできます。競合を変更する方法または変更する方法(コンポーネントのリソースがメインプロジェクトのリソースと同じ名前の場合、メインプロジェクトは、リソースを準パッケージ化およびマージするときに使用されます)

  4.サードパーティメーカーのコンポーネント(通常は変更できません)の場合、独自の色の名前とメインプロジェクトの色の名前が競合すると、当然、コンポーネントに暗い色と明るい色が発生します。非常に悪い。変更を加えるには、サードパーティと調整する必要があります。一般的なサードパーティベンダーのコンポーネントを適応させることはありませんが、メインプロジェクトのアクティビティがフィールドコンポーネントを継承する場合は、動的な適応が必要になる場合があります。

また、次のようにすることもできます:メインプロジェクトの値にxmlを追加し、そのスタイルと色を定義します。この時点で、彼は適応されたメインプロジェクトの色名を使用できます。ビルドに適応させたい特定の色またはスタイルの名前がこの新しいファイルの色の名前およびスタイルと同じである限り、適応も実行されます。以下に示すように:

2.フォースダークへの自動適応

1.スタイルのテーマが次のように変更されます:parent = "Theme.AppCompat.Light.NoActionBar"

2. <item name = "android:forceDarkAllowed" tools:targetApi = "q"> true </ item>

その後、それは大丈夫です。モードスイッチを切り替えると、システムが自動的に適応し、効果が良好です。

これは、ネイティブページとWebビューページの両方に適応します。これは非常に重要です。

上記の内容は基本的に満たされています。Androidクライアントはダークモードに適合していますが、開発中に他の多くの要件が存在する可能性があり、これらの要件がそれにつながります。私は2つの問題に遭遇しました

1. Webページは属性preferred-color-schemeで構成 @media され、Android Webページの暗順応を実現するために、下の図に示すように、対応するcssスタイルが判断後に照合されます。(iOSは可能ですが、多くのAndroidフォンはそれに適応できません)

body {
  color: #333; /* 在 light mode 时,页面中的文字颜色 */
}
@media screen and (prefers-color-scheme: dark) {
  body {
    color: #fff; /* 如果系统切换到 dark mode 时,页面中的文字颜色改变 */
  }
}

 ただし、この属性では、カーネルブラウザのChromumバージョンが81以上である必要があり、多くの携帯電話は現在このバージョンよりも低いため、これは不可能です。

だから私は次の方法を見つけました:

1.クライアント側で、ダークスイッチのロジックに従って動的にcssスタイルを挿入します。https://blog.csdn.net/anhenzhufeng/article/details/78931586?utm_medium = distribute.pc_relevant.none-を参照できます。 task-blog-baidujs-3    この記事。  

短所:1。まず、特別な場所に適応する必要があるため、HTMLの特定の基盤が必要です。2。さらに、Webページのコントロールがまだ断片化されているため、処理が特に面倒です。

2.処理のためにJsインタラクションを介して携帯電話モードのステータスをWebページに渡します

3. 2番目の方法を使用すると、WebviewActivityに適応するだけで、スタイルをこのアクティビティに個別に適応させるだけで十分です。他のネイティブインターフェイスはカスタムの方法で適応させることができます(私はこれを使用します)

2.要件:クライアントには、第2レベルまたは第3レベルのインターフェイスでダークモードを手動で制御するスイッチがあります。携帯電話にダークモードを表示するかどうかは、携帯電話システムのダークスイッチとこのスイッチによって制限され、インターフェイスは現在のインターフェイスは、ホームページ(MainActiivtyなどの同様のプライマリインターフェイス)にジャンプすることはできません。

ホームページへのジャンプが許可されている場合、タスクスタックが空になり、リロードされるすべてのインターフェイスがホームページと同じになるため、簡単です(これは、モードを変更するインターフェイスに関係なく、WeChatの場合です。ホームページにジャンプし、しばらく点滅します)。許可されていない場合、現在のインターフェイスを強制的に特定のモードに設定しても、タスクスタックにロードされているインターフェイスは変更されません。この需要を解決する方法は?

非常に面倒で、達成することはできますが、顧客体験はあまり良くありません。以下のアイデアについてのみお話します

1.グローバルキャッシュを作成し、インターフェイスがBaseActivityにロードされるたびに、インターフェイスの現在のモード状態をキャッシュに保存します

2.特定のインターフェースでモードが切り替えられ、APPの状態を変更する必要がある場合、現在のインターフェースを直接変更できます。スタックにロードされた他のアクティビティの場合、キャッシュ内のモードはonResumeで取得され、現在表示されているはずのモードと比較されます。同じ場合は変更する必要はありません。そうでない場合は設定されます。ロジックに従って動的に。

AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); //ライトの色を動的に設定します
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //暗い色を動的に設定します

そして、キャッシュ内のこのインターフェースの状態を再変更し、破棄するときは、このインターフェースのストレージを削除します

3.古いプロジェクトの変換に関連しているため、このような問題が発生します。モード状態が変更されると、setContentView()がsuper.onCreate()の前に配置されます(論理処理が含まれる可能性があるため)。recreate()後であるはずのようにレンダリングされませんでした。この状況に対応して、私の扱いは、onRestoreInstanceStateでこの状況に対して1回リロードすることです。

@Override 
protected void onRestoreInstanceState(Bundle savedInstanceState){ 
    super.onRestoreInstanceState(savedInstanceState); 
    if(IMApp.getInstance()。isChangeConfigMode){
        文字列フラグ= MeUtils.getString(SystemParamManager.getSystemParam(SystemParam.BIG_TYPE_CUSTOMER_PARAM、SystemParam.SMALL_TYPE_ME_SETTING_DARK_SWITCH)); 
        IMApp.getInstance()。isChangeConfigMode = false; 
        if(flag.equals( "1")&&!isOncreateFirst){ 
            Intent intent = getIntent(); 
            thisActivity.finish(); 
            overridePendingTransition(0、0); 
            startActivity(intent); 
        }  
    } else {
        IMApp.getInstance()。isChangeConfigMode = false;
    } 
}

条件が設定されている限り、これらはすべてBaseで均一に処理されます。

 

概要:複雑で古いプロジェクトに長年適応する場合、さまざまな問題が発生する可能性があります。これには、絶えず努力して最適化する必要があります。

決定していません:

Huawei P30 mate30Proこれらは現在新しい携帯電話であり、システムによってのみ制御されます。ダーク効果はカスタマイズとは関係ありません。

次のように、スプラッシュインターフェイスからAPPを初めてインストールします。システムが黒+独自のスイッチがオフ= APPを強制的に明るい色に設定します。MainActivtyに入ると、最初に読み込まれたフラグメントにレンダリングの問題が発生します。一部の行またはアイコン白く表示され、レンダリングできません。ただし、他のフラグメントは問題なく、他のアクティビティも問題ありません。出て再入場しても問題ありませんし、今後も問題ないのでわかりません。

 

おすすめ

転載: blog.csdn.net/lk2021991/article/details/107517455