Android style&Theme再探査(三)-カスタムThemeの例とピットの大まとめ

60400 ワード

最初の2つの文章の探究に基づいて、今回は皮膚の切り替えと夜間のモードの切り替えをもたらし、書き換えの一部のコントロールに基づいてThemeの役割を示した.実際に使った時の説明、踏んだ穴のまとめ
Android Theme切り替えテーマまとめ
筆者は肌の入れ替えや日夜モードの切り替えを実践する簡単なデモについて述べる
Android Demo展示解説
効果の表示
図から分かるように、この例は複数のThemeと夜間モードが組み合わせて効果を示し、既存のactivityに対しても変換されている.これも私が現在見ている多くの既存のブログdemo欠落部分であり、既存のacitivityに対してどのように処理するかである.
コード構想展示
  • まずstyleのThemeに対する設定:
  •  
        <style name="ehiTheme" 
        parent="@style/Theme.AppCompat.DayNight.NoActionBar">
        
            
            "buttonStyle">@style/ehiButton
             
            
            "checkboxStyle">@style/ehiCheckBox
            
            "alertDialogTheme">@style/AppTheme.blue.AlertDialog
            "radioButtonStyle">@style/ehiRadioButton
        style>
    
        
        <style name="ehiButton" parent="@style/Base.Widget.AppCompat.Button">
            "android:background">?colorAccent
            "android:textColor">@color/white
            "android:textAppearance">@style/Base.TextAppearance.AppCompat.Small
        style>
    
  • 複数のTheme
  • を定義
         
           <style name="ehiTheme" 
        parent="@style/Theme.AppCompat.DayNight.NoActionBar">
            
        style> 
        <style name="AppTheme" parent="ehiTheme">
            
             
        style> 
        
         <style name="AppTheme.blue">
            "colorPrimary">@color/colorPrimaryBlue
            "colorPrimaryDark">@color/colorPrimaryBlueDark
            "colorAccent">@color/colorPrimaryBlueDark
            "alertDialogTheme">@style/AppTheme.blue.AlertDialog
        style>
         
         <style name="AppTheme.Purple" >
            "colorPrimary">@color/colorPrimaryPurple
            "colorPrimaryDark">@color/colorPrimaryPurpleDark
            "colorAccent">@color/colorPrimaryPurpleDark
            "alertDialogTheme">@style/AppTheme.Purple.AlertDialog
        style>
    
         <application
            android:allowBackup="false"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:name=".DemoApplication"
            android:theme="@style/AppTheme.blue">style>
            
    
  • 日夜モードのリソースファイルに対する調整
  • 既存のvalueフォルダのほか、values-night
  • を作成します.
  • colorファイルを2つ作成し、異なる色に置き換える(ps:ナイトモードで置き換える色をnightファイルに定義すればよい、その他の色はデフォルトフォルダに保持すればよい)
  • .
    valueファイルのcolor
    
          <color name="colorAccent">@color/colorPrimaryBlueDarkcolor>
        <color name="colorPrimary">@color/colorPrimaryBluecolor>
        <color name="colorBackgroundTrans">#AAFAFAFAcolor>
    
        <color name="colorPrimaryBlue">#bbdefbcolor>
        <color name="colorPrimaryBlueDark">#90caf9color>
    
         <color name="colorPrimaryPurple">#e1bee7color>
        <color name="colorPrimaryPurpleDark">#ce93d8color>
    

    value-nightファイルのcolor
    
          <color name="colorAccent">@color/colorPrimaryBlueDarkcolor>
        <color name="colorPrimary">@color/colorPrimaryBluecolor>
        <color name="colorBackgroundTrans">#AAFAFAFAcolor>
    
       <color name="colorPrimaryBlue">#82b1ffcolor>
        <color name="colorPrimaryBlueDark">#2962ffcolor>
    
        <color name="colorPrimaryPurple">#d500f9color>
        <color name="colorPrimaryPurpleDark">#aa00ffcolor>
    
  • コードでは、マルチThemeとデイナイトモード
  • が使用されます.
  • 設定キャッシュTheme変化後の設定の保存場所本demoではアプリケーションを使用して保存しますが、実際の項目はxmlなどの永続化方式でユーザー設定
  • を保存してください.
    public class DemoApplication extends Application {
        private static DemoApplication demoApplication;
       private static final int defaultStyle = R.style.AppTheme_blue;//     
       private static int tempNightMode = AppCompatDelegate.MODE_NIGHT_NO;//      
        private static int style = defaultStyle;
        @Override
        public void onCreate() {
            super.onCreate();
            demoApplication = this;
        }
    
        //getter   setter     
    
    }
    
    
  • インタフェースのレイアウトファイル
  • を設定する.
    
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".MDActivity">
    
        <Button
            android:id="@+id/btn"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="    " />
        <RadioGroup
            android:id="@+id/rg_theme"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
              <RadioButton
                android:id="@+id/pink"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="  " />
            <RadioButton
                android:id="@+id/blue"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="  " />
            <RadioButton
                android:id="@+id/Purple"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="  " />
    
        RadioGroup>
    
        <Switch
            android:id="@+id/switch_day_night"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="       "
            android:checked="false"
            />
        
    LinearLayout>
    
  • インタフェースjavaコード
  • を設定する
    public class MDActivity extends AppCompatActivity {
         //       
        private RadioGroup rg;
        private Switch switchDayNight;
        private RadioButton pink;
        private RadioButton blue;
        private RadioButton Purple;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            //activiy   ,      style
            setTheme(DemoApplication.getStyle());
            super.onCreate(savedInstanceState);
            //activiy   ,           
            if (DemoApplication.getTempNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
            } else {
                AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
            }
            setContentView(R.layout.activity_md);
        initView();
        }
        //     
         private void initView() {
             //activiy   ,  switch  
            switchDayNight = findViewById(R.id.switch_day_night);
            if (AppCompatDelegate.getDefaultNightMode() == AppCompatDelegate.MODE_NIGHT_YES) {
                switchDayNight.setChecked(true);
            } else {
                switchDayNight.setChecked(false);
            }
            //  
            switchDayNight.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked) {
                        DemoApplication.setTempNightMode(AppCompatDelegate.MODE_NIGHT_YES);
                        Intent intent = getIntent();
                        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        setResult(RESULT_OK);
                        finish();
                        startActivity(intent);
                        overridePendingTransition(0, 0);
                    } else {
                        DemoApplication.setTempNightMode(AppCompatDelegate.MODE_NIGHT_NO);
                        Intent intent = getIntent();
                        intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        setResult(RESULT_OK);
                        finish();
                        startActivity(intent);
                        overridePendingTransition(0, 0);
                    }
                }
            });
            pink = findViewById(R.id.pink);
            blue = findViewById(R.id.blue);
            Purple = findViewById(R.id.Purple);
            rg = findViewById(R.id.rg_theme);
            setCheck();
            rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(RadioGroup group, int checkedId) {
                    switch (checkedId) {
                        case R.id.pink:
                            setStyle(R.style.AppTheme_Pink);
                            break;
                        case R.id.blue:
                            setStyle(R.style.AppTheme_blue);
                            break;
                        case R.id.Purple:
                            setStyle(R.style.AppTheme_Purple);
                            break;
                        default:
                            setStyle(R.style.AppTheme_blue);
                    }
    
    
                }
            });
        }
        //       
        private void setCheck() {
    
            switch (DemoApplication.getStyle()){
                case R.style.AppTheme_Pink:
                    pink.setChecked(true);
                    break;
                case R.style.AppTheme_blue:
                    blue.setChecked(true);
                    break;
                case R.style.AppTheme_Purple:
                    Purple.setChecked(true);
                    break;
                default:
                    blue.setChecked(true);
            }
        }
       // style    ,       
        private void setStyle(int appTheme) {
            //    ,     activity
            if (DemoApplication.getStyle() == appTheme) {
                return;
            }
            //         
            DemoApplication.setStyle(appTheme);
            Intent intent = getIntent();
            //   activity       
            intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            //   Result  ,       
            setResult(RESULT_OK);
            finish();
            startActivity(intent);
            //      
            overridePendingTransition(0, 0);
        }
    
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            if ((keyCode == KeyEvent.KEYCODE_BACK)) {
                setResult(RESULT_OK);//         ,  
                finish();
                return true;
            }
            return super.onKeyDown(keyCode, event);
        }
    
    
    
  • は、設定画面前の画面
  • に入る.
    public class MainActivity extends AppCompatActivity {
        //   setting  
        private int SETTINGS_ACTION = 1;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            //    style
            setTheme(DemoApplication.getStyle());
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
       //          ,     style      
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == SETTINGS_ACTION && resultCode == RESULT_OK){
                finish();
                Intent intent = getIntent();
                startActivity(intent);
            }
        }
    }
    
  • 実現構想
  • 主な実現構想は非常に簡単です.
    a.実はユーザーが対応するスタイルとナイトモードを選択してから、アニメーションをオフにした場合、設定したactivityを再起動します
    b.前の画面に戻ると、画面styleまたは夜間モードが変更されて画面が設定されます
    setResult(RESULT_OK);
    前のインタフェースで取得し、インタフェースを再起動すればいいです.
    if (requestCode == SETTINGS_ACTION && resultCode == RESULT_OK){
                finish();
                Intent intent = getIntent();
                startActivity(intent);
            }
    
  • まとめ
  • 総じて言えば、実はthemeのテーマを切り替えること自体はあまり深い技術に関与していません.ただ、私たちが知っている基礎的な内容を組み合わせて、私たちはこれらの簡単な知識でより良いユーザー体験を作成することができます.
  • 注意点
  • themeでは
    <style name="ehiTheme" 
      parent="@style/Theme.AppCompat.DayNight.NoActionBar">
    
    を直接引用するのではなく、
  • を再び継承すべきである.
     <style name="AppTheme" parent="ehiTheme">
    

    これにより、ehiThemeはすべてのandroidバージョンのデフォルトスタイルを管理し、AppThemeは複数のvalueでいくつかのバージョンの新しいプロパティプロパティを定義するために使用されます.
  • 日ナイトモードとテーマの切り替えは、すでに生きているactivityには役に立たない.本稿では、アニメーションなしでactivityを再作成する考え方を採用している.この方式の劣勢は、appのいくつかの状態を保存し、再作成後にユーザーが編集した内容が失われないことを保証することである.
  • ナイトモードのcolor,styleのような変化が必要な部分の色やスタイルのみを定義し,他のナイトで使用する統一スタイルを2部コピーすることなく,不要なメンテナンスコスト
  • を回避する.



  • 特集シリーズ:Android style&Theme再探析(一)--StyleとThemeを本当に知っていますか?Android style&Theme再探析(二)--一統View規範の大殺器-material design Android style&Theme再探析(三)--カスタムTheme例と日夜モード踏坑大まとめAndroid style&Theme再探析(四)--業務実践心得まとめ
    ブロガーブログ:http://www.whdreamblog.cn/