diff --git a/app/build.gradle b/app/build.gradle index bcabb7e46..89423e131 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -25,7 +25,7 @@ android { } defaultConfig { applicationId "io.github.nekoinverter.ehviewer" - minSdkVersion 21 + minSdkVersion 23 targetSdkVersion 30 versionCode 143 versionName "1.7.22" @@ -114,6 +114,7 @@ dependencies { implementation 'androidx.biometric:biometric:1.1.0' implementation "androidx.browser:browser:1.3.0" implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.core:core:1.5.0-beta03' implementation 'androidx.dynamicanimation:dynamicanimation:1.1.0-alpha03' implementation "androidx.fragment:fragment:1.3.1" implementation "androidx.preference:preference:1.1.1" @@ -145,6 +146,12 @@ dependencies { implementation 'com.takisoft.preferencex:preferencex:1.1.0' implementation 'com.github.NekoInverter:Image:8fd6c1e1df' implementation 'com.gitlab.NekoInverter:yorozuya:723dc867a9' + implementation 'dev.rikka.rikkax.appcompat:appcompat:1.2.0-rc01' + implementation 'dev.rikka.rikkax.core:core:1.3.0' + implementation 'dev.rikka.rikkax.material:material:1.6.0' + implementation 'dev.rikka.rikkax.recyclerview:recyclerview-adapter:1.2.0' + implementation 'dev.rikka.rikkax.recyclerview:recyclerview-ktx:1.2.0' + implementation 'dev.rikka.rikkax.widget:borderview:1.0.1' implementation 'dev.rikka.rikkax.preference:simplemenu-preference:1.0.2' implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1' implementation 'org.greenrobot:greendao:3.3.0' @@ -163,5 +170,6 @@ configurations.all { exclude group: 'com.github.seven332', module: 'okhttp' exclude group: 'com.github.seven332', module: 'image' exclude group: 'com.github.seven332', module: 'yorozuya' + exclude group: 'androidx.appcompat', module: 'appcompat' } } diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.java b/app/src/main/java/com/hippo/ehviewer/EhApplication.java index fd174adb4..b109c3d60 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.java +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.java @@ -31,7 +31,6 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatDelegate; import androidx.collection.LruCache; import com.hippo.a7zip.A7Zip; @@ -84,6 +83,8 @@ import okhttp3.Call; import okhttp3.HttpUrl; import okhttp3.OkHttpClient; import okhttp3.Request; +import rikka.material.app.DayNightDelegate; +import rikka.material.app.LocaleDelegate; public class EhApplication extends RecordingApplication { @@ -336,7 +337,9 @@ public class EhApplication extends RecordingApplication { Analytics.start(this); - AppCompatDelegate.setDefaultNightMode(Settings.getTheme()); + LocaleDelegate.setDefaultLocale(Settings.getLocale()); + DayNightDelegate.setApplicationContext(this); + DayNightDelegate.setDefaultNightMode(Settings.getTheme()); // Do io tasks in new thread //noinspection deprecation diff --git a/app/src/main/java/com/hippo/ehviewer/Settings.java b/app/src/main/java/com/hippo/ehviewer/Settings.java index 4f11e8926..b76cb272c 100755 --- a/app/src/main/java/com/hippo/ehviewer/Settings.java +++ b/app/src/main/java/com/hippo/ehviewer/Settings.java @@ -311,6 +311,16 @@ public class Settings { //} } + public static Locale getLocale() { + Locale locale = null; + String language = Settings.getAppLanguage(); + if (language != null && !language.equals("system")) { + return Locale.forLanguageTag(language); + } else { + return Locale.getDefault(); + } + } + private static EhConfig loadEhConfig() { EhConfig ehConfig = new EhConfig(); ehConfig.imageSize = getImageResolution(); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.java index 9bb9d9d12..633381bb4 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/EhActivity.java @@ -19,21 +19,20 @@ package com.hippo.ehviewer.ui; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.os.Build; import android.os.Bundle; import android.view.WindowManager; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.StyleRes; -import androidx.appcompat.app.AppCompatActivity; import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; -import java.util.Locale; +import rikka.material.app.MaterialActivity; -public abstract class EhActivity extends AppCompatActivity { +public abstract class EhActivity extends MaterialActivity { private static final String THEME_DEFAULT = "DEFAULT"; private static final String THEME_BLACK = "BLACK"; @@ -55,21 +54,13 @@ public abstract class EhActivity extends AppCompatActivity { } @Override - protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) { - // apply real style and our custom style - if (getParent() == null) { - theme.applyStyle(resid, true); - } else { - try { - theme.setTo(getParent().getTheme()); - } catch (Exception e) { - // Empty - } - theme.applyStyle(resid, false); - } + public void onApplyUserThemeResource(@NonNull Resources.Theme theme, boolean isDecorView) { theme.applyStyle(getThemeStyleRes(this), true); - // only pass theme style to super, so styled theme will not be overwritten - super.onApplyThemeResource(theme, R.style.ThemeOverlay, first); + } + + @Override + public String computeUserThemeKey() { + return getTheme(this); } @StyleRes @@ -83,11 +74,6 @@ public abstract class EhActivity extends AppCompatActivity { } } - @Override - protected void onNightModeChanged(int mode) { - getTheme().applyStyle(getThemeStyleRes(this), true); - } - @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -112,48 +98,4 @@ public abstract class EhActivity extends AppCompatActivity { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } } - - @Override - protected void attachBaseContext(Context newBase) { - super.attachBaseContext(newBase); - applyOverrideConfiguration(new Configuration()); - } - - @Override - public void applyOverrideConfiguration(Configuration newConfig) { - super.applyOverrideConfiguration(updateConfigurationIfSupported(newConfig)); - } - - private Configuration updateConfigurationIfSupported(Configuration config) { - // Configuration.getLocales is added after 24 and Configuration.locale is deprecated in 24 - if (Build.VERSION.SDK_INT >= 24) { - if (!config.getLocales().isEmpty()) { - return config; - } - } else { - if (config.locale != null) { - return config; - } - } - Locale locale = null; - String language = Settings.getAppLanguage(); - if (language != null && !language.equals("system")) { - String[] split = language.split("-"); - if (split.length == 1) { - locale = new Locale(split[0]); - } else if (split.length == 2) { - locale = new Locale(split[0], split[1]); - } else if (split.length == 3) { - locale = new Locale(split[0], split[1], split[2]); - } - } else { - Resources res = EhApplication.getInstance().getResources(); - Configuration configuration = res.getConfiguration(); - locale = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ? configuration.getLocales().get(0) : configuration.locale; - } - if (locale != null) { - config.setLocale(locale); - } - return config; - } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java index 723afacc0..ccbbd7940 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/GalleryActivity.java @@ -54,7 +54,6 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.widget.SwitchCompat; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; @@ -99,6 +98,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import rikka.material.app.DayNightDelegate; + public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChangeListener, GalleryView.Listener { @@ -302,19 +303,30 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan } @Override - @SuppressWarnings({"WrongConstant"}) - protected void onCreate(@Nullable Bundle savedInstanceState) { + protected void attachBaseContext(@NonNull Context newBase) { switch (Settings.getReadTheme()) { case 0: - getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_UNSPECIFIED); + DayNightDelegate.setDefaultNightMode(Settings.getTheme()); break; case 1: - getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES); + DayNightDelegate.setDefaultNightMode(DayNightDelegate.MODE_NIGHT_YES); break; case 2: - getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO); + DayNightDelegate.setDefaultNightMode(DayNightDelegate.MODE_NIGHT_NO); break; } + super.attachBaseContext(newBase); + } + + @Override + public void finish() { + DayNightDelegate.setDefaultNightMode(Settings.getTheme()); + super.finish(); + } + + @Override + @SuppressWarnings({"WrongConstant"}) + protected void onCreate(@Nullable Bundle savedInstanceState) { if (Settings.getReadingFullscreen()) { Window w = getWindow(); w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, @@ -1041,6 +1053,7 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan int screenLightness = mScreenLightness.getProgress(); boolean oldReadingFullscreen = Settings.getReadingFullscreen(); + int oldReadTheme = Settings.getReadTheme(); Settings.putScreenRotation(screenRotation); Settings.putReadingDirection(layoutMode); @@ -1074,17 +1087,6 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan break; } setRequestedOrientation(orientation); - switch (Settings.getReadTheme()) { - case 0: - getDelegate().setLocalNightMode(AppCompatDelegate.getDefaultNightMode()); - break; - case 1: - getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_YES); - break; - case 2: - getDelegate().setLocalNightMode(AppCompatDelegate.MODE_NIGHT_NO); - break; - } mGalleryView.setLayoutMode(layoutMode); mGalleryView.setScaleMode(scaleMode); mGalleryView.setStartPosition(startPosition); @@ -1110,7 +1112,7 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan mLayoutMode = layoutMode; updateSlider(); - if (oldReadingFullscreen != readingFullscreen) { + if (oldReadingFullscreen != readingFullscreen || oldReadTheme != readTheme) { recreate(); } } @@ -1222,25 +1224,4 @@ public class GalleryActivity extends EhActivity implements SeekBar.OnSeekBarChan } } } - - @Override - public void applyOverrideConfiguration(Configuration newConfig) { - // **Magic** - super.applyOverrideConfiguration(updateConfigurationIfSupported(newConfig)); - } - - private Configuration updateConfigurationIfSupported(Configuration config) { - switch (Settings.getReadTheme()) { - case 0: - config.uiMode = Configuration.UI_MODE_NIGHT_UNDEFINED | Configuration.UI_MODE_NIGHT_MASK; - break; - case 1: - config.uiMode = Configuration.UI_MODE_NIGHT_YES | Configuration.UI_MODE_NIGHT_MASK; - break; - case 2: - config.uiMode = Configuration.UI_MODE_NIGHT_NO | Configuration.UI_MODE_NIGHT_MASK; - break; - } - return config; - } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java index 598ccaca7..d51625e94 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java @@ -92,6 +92,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; +import rikka.material.app.DayNightDelegate; + public final class MainActivity extends StageActivity implements NavigationView.OnNavigationItemSelectedListener { @@ -317,7 +319,8 @@ public final class MainActivity extends StageActivity mDisplayName = (TextView) ViewUtils.$$(headerLayout, R.id.display_name); ViewUtils.$$(headerLayout, R.id.night_mode).setOnClickListener(v -> { int theme = (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) > 0 ? AppCompatDelegate.MODE_NIGHT_NO : AppCompatDelegate.MODE_NIGHT_YES; - AppCompatDelegate.setDefaultNightMode(theme); + DayNightDelegate.setDefaultNightMode(theme); + recreate(); if (Settings.getTheme() != AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) { Settings.putTheme(theme); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java index e8cbfe63c..cf0f941d0 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/AdvancedFragment.java @@ -47,9 +47,12 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.Arrays; +import java.util.Locale; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import rikka.material.app.LocaleDelegate; + public class AdvancedFragment extends BasePreferenceFragment { private static final String KEY_DUMP_LOGCAT = "dump_logcat"; @@ -271,7 +274,12 @@ public class AdvancedFragment extends BasePreferenceFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { String key = preference.getKey(); if (KEY_APP_LANGUAGE.equals(key)) { - ((EhApplication) getActivity().getApplication()).recreate(); + if ("system".equals(newValue)) { + LocaleDelegate.setDefaultLocale(LocaleDelegate.getSystemLocale()); + } else { + LocaleDelegate.setDefaultLocale(Locale.forLanguageTag((String) newValue)); + } + requireActivity().recreate(); return true; } return false; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/fragment/EhFragment.java b/app/src/main/java/com/hippo/ehviewer/ui/fragment/EhFragment.java index b7d75c07a..789e720fd 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/fragment/EhFragment.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/fragment/EhFragment.java @@ -21,14 +21,14 @@ import android.content.res.Configuration; import android.os.Bundle; import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatDelegate; import androidx.preference.Preference; -import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; import com.hippo.ehviewer.client.EhTagDatabase; +import rikka.material.app.DayNightDelegate; + public class EhFragment extends BasePreferenceFragment { @Override @@ -62,7 +62,8 @@ public class EhFragment extends BasePreferenceFragment { public boolean onPreferenceChange(Preference preference, Object newValue) { String key = preference.getKey(); if (Settings.KEY_THEME.equals(key)) { - AppCompatDelegate.setDefaultNightMode(Integer.parseInt((String) newValue)); + DayNightDelegate.setDefaultNightMode(Integer.parseInt((String) newValue)); + requireActivity().recreate(); return true; } else if (Settings.KEY_GALLERY_SITE.equals(key)) { requireActivity().setResult(Activity.RESULT_OK); @@ -80,7 +81,7 @@ public class EhFragment extends BasePreferenceFragment { } } else if (Settings.KEY_BLACK_DARK_THEME.equals(key)) { if ((requireActivity().getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_YES) > 0) { - ((EhApplication) requireActivity().getApplication()).recreate(); + requireActivity().recreate(); } return true; } diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml index d06531e7a..02bed0bb7 100644 --- a/app/src/main/res/values-night/themes.xml +++ b/app/src/main/res/values-night/themes.xml @@ -1,44 +1,7 @@ - + +