diff --git a/app/src/main/java/org/lsposed/manager/App.java b/app/src/main/java/org/lsposed/manager/App.java index 25f1a5ce..3d6d917f 100644 --- a/app/src/main/java/org/lsposed/manager/App.java +++ b/app/src/main/java/org/lsposed/manager/App.java @@ -35,6 +35,7 @@ import android.util.Log; import androidx.annotation.NonNull; import androidx.preference.PreferenceManager; +import com.google.android.material.color.DynamicColors; import com.google.gson.JsonParser; import org.lsposed.hiddenapibypass.HiddenApiBypass; @@ -161,6 +162,9 @@ public class App extends Application { DayNightDelegate.setApplicationContext(this); DayNightDelegate.setDefaultNightMode(ThemeUtil.getDarkTheme()); LocaleDelegate.setDefaultLocale(getLocale()); + if (ThemeUtil.isSystemAccent()) { + DynamicColors.applyToActivitiesIfAvailable(this); + } registerReceiver(new BroadcastReceiver() { @Override diff --git a/app/src/main/java/org/lsposed/manager/Constants.java b/app/src/main/java/org/lsposed/manager/Constants.java index d9f39d83..7fd5817a 100644 --- a/app/src/main/java/org/lsposed/manager/Constants.java +++ b/app/src/main/java/org/lsposed/manager/Constants.java @@ -21,7 +21,6 @@ package org.lsposed.manager; import android.os.IBinder; -import android.widget.Toast; import org.lsposed.manager.receivers.LSPManagerServiceHolder; diff --git a/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java b/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java index 51784d1b..b6b93fec 100644 --- a/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java +++ b/app/src/main/java/org/lsposed/manager/adapters/ScopeAdapter.java @@ -54,7 +54,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.recyclerview.widget.RecyclerView; @@ -62,6 +61,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.checkbox.MaterialCheckBox; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import org.lsposed.lspd.models.Application; @@ -226,7 +226,7 @@ public class ScopeAdapter extends RecyclerView.Adapter int itemId = item.getItemId(); if (itemId == R.id.use_recommended) { if (!checkedList.isEmpty()) { - new AlertDialog.Builder(activity) + new MaterialAlertDialogBuilder(activity) .setMessage(R.string.use_recommended_message) .setPositiveButton(android.R.string.ok, (dialog, which) -> { checkRecommended(); @@ -295,7 +295,7 @@ public class ScopeAdapter extends RecyclerView.Adapter if (info.packageName.equals("android")) { ConfigManager.reboot(false); } else { - new AlertDialog.Builder(activity) + new MaterialAlertDialogBuilder(activity) .setTitle(R.string.force_stop_dlg_title) .setMessage(R.string.force_stop_dlg_text) .setPositiveButton(android.R.string.ok, (dialog, which) -> ConfigManager.forceStopPackage(info.packageName, info.uid / 100000)) @@ -618,7 +618,7 @@ public class ScopeAdapter extends RecyclerView.Adapter public void onBackPressed() { fragment.searchView.clearFocus(); if (!refreshing && fragment.binding.masterSwitch.isChecked() && checkedList.isEmpty()) { - AlertDialog.Builder builder = new AlertDialog.Builder(activity); + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(activity); builder.setMessage(!recommendedList.isEmpty() ? R.string.no_scope_selected_has_recommended : R.string.no_scope_selected); if (!recommendedList.isEmpty()) { builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { diff --git a/app/src/main/java/org/lsposed/manager/ui/activity/base/BaseActivity.java b/app/src/main/java/org/lsposed/manager/ui/activity/base/BaseActivity.java index 500c08b6..e8a79d99 100644 --- a/app/src/main/java/org/lsposed/manager/ui/activity/base/BaseActivity.java +++ b/app/src/main/java/org/lsposed/manager/ui/activity/base/BaseActivity.java @@ -22,13 +22,13 @@ package org.lsposed.manager.ui.activity.base; import android.content.res.Resources; import android.graphics.Color; -import android.os.Build; import android.os.Bundle; import android.view.Window; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.lsposed.manager.BuildConfig; import org.lsposed.manager.ConfigManager; @@ -49,7 +49,7 @@ public class BaseActivity extends MaterialActivity { if (!ConfigManager.isBinderAlive()) return; var version = ConfigManager.getXposedVersionName(); if (BuildConfig.VERSION_NAME.equals(version)) return; - new AlertDialog.Builder(this) + new MaterialAlertDialogBuilder(this) .setMessage(BuildConfig.VERSION_NAME.compareTo(version) > 0 ? R.string.outdated_core : R.string.outdated_manager) .setPositiveButton(android.R.string.ok, (dialog, id) -> { diff --git a/app/src/main/java/org/lsposed/manager/ui/dialog/BlurBehindDialogBuilder.java b/app/src/main/java/org/lsposed/manager/ui/dialog/BlurBehindDialogBuilder.java index 09395c2d..ed50b133 100644 --- a/app/src/main/java/org/lsposed/manager/ui/dialog/BlurBehindDialogBuilder.java +++ b/app/src/main/java/org/lsposed/manager/ui/dialog/BlurBehindDialogBuilder.java @@ -30,10 +30,12 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.os.BuildCompat; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + import java.lang.reflect.Method; @SuppressWarnings({"JavaReflectionMemberAccess", "ConstantConditions"}) -public class BlurBehindDialogBuilder extends AlertDialog.Builder { +public class BlurBehindDialogBuilder extends MaterialAlertDialogBuilder { private static final boolean supportBlur = getSystemProperty("ro.surface_flinger.supports_background_blur", false) && !getSystemProperty("persist.sys.sf.disable_blurs", false); public BlurBehindDialogBuilder(@NonNull Context context) { diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/AppListFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/AppListFragment.java index 05636acc..6e4b1d2e 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/AppListFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/AppListFragment.java @@ -66,7 +66,8 @@ public class AppListFragment extends BaseFragment { if (module == null) { return binding.getRoot(); } - binding.appBar.setRaised(true); + binding.appBar.setLiftable(true); + binding.appBar.setLifted(true); String title; if (module.userId != 0) { title = String.format(Locale.US, "%s (%d)", module.getAppName(), module.userId); diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/CompileDialogFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/CompileDialogFragment.java index b1dace57..6a80fe09 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/CompileDialogFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/CompileDialogFragment.java @@ -31,10 +31,10 @@ import android.view.LayoutInflater; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatDialogFragment; import androidx.fragment.app.FragmentManager; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import org.lsposed.manager.App; @@ -76,7 +76,7 @@ public class CompileDialogFragment extends AppCompatDialogFragment { FragmentCompileDialogBinding binding = FragmentCompileDialogBinding.inflate(LayoutInflater.from(requireActivity()), null, false); final PackageManager pm = requireContext().getPackageManager(); - AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity()) + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity()) .setIcon(appInfo.loadIcon(pm)) .setTitle(appInfo.loadLabel(pm)) .setView(binding.getRoot()); diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java index 1e59e590..c9960157 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/HomeFragment.java @@ -31,6 +31,7 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.core.text.HtmlCompat; +import com.google.android.material.color.MaterialColors; import com.google.android.material.snackbar.Snackbar; import org.lsposed.manager.App; @@ -60,7 +61,8 @@ public class HomeFragment extends BaseFragment { setupToolbar(binding.toolbar, getString(R.string.app_name), R.menu.menu_home); binding.toolbar.setNavigationIcon(null); - binding.nestedScrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top)); + binding.appBar.setLiftable(true); + binding.nestedScrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top)); Activity activity = requireActivity(); binding.status.setOnClickListener(v -> { @@ -155,10 +157,10 @@ public class HomeFragment extends BaseFragment { binding.statusIcon.setImageResource(R.drawable.ic_round_error_outline_24); Snackbar.make(binding.snackbar, R.string.lsposed_not_active, Snackbar.LENGTH_INDEFINITE).show(); } - binding.status.setCardBackgroundColor(cardBackgroundColor); + binding.status.setCardBackgroundColor(MaterialColors.harmonizeWithPrimary(activity, cardBackgroundColor)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - binding.status.setOutlineSpotShadowColor(cardBackgroundColor); - binding.status.setOutlineAmbientShadowColor(cardBackgroundColor); + binding.status.setOutlineSpotShadowColor(MaterialColors.harmonizeWithPrimary(activity, cardBackgroundColor)); + binding.status.setOutlineAmbientShadowColor(MaterialColors.harmonizeWithPrimary(activity, cardBackgroundColor)); } } diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/LogsFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/LogsFragment.java index 6d3f046b..b1a6b1e3 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/LogsFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/LogsFragment.java @@ -45,6 +45,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayout; @@ -70,6 +71,8 @@ import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import rikka.core.os.FileUtils; +import rikka.core.util.ResourceUtils; +import rikka.insets.WindowInsetsHelperKt; import rikka.recyclerview.RecyclerViewKt; @SuppressLint("NotifyDataSetChanged") @@ -105,8 +108,11 @@ public class LogsFragment extends BaseFragment { binding = FragmentLogsBinding.inflate(inflater, container, false); binding.getRoot().bringChildToFront(binding.appBar); setupToolbar(binding.toolbar, R.string.Logs, R.menu.menu_logs); - binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top)); - + binding.appBar.setLiftable(true); + binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top)); + int height = ResourceUtils.resolveDimensionPixelOffset(requireActivity().getTheme(), androidx.appcompat.R.attr.actionBarSize, 0) + + getResources().getDimensionPixelOffset(R.dimen.tab_layout_height); + WindowInsetsHelperKt.setInitialPadding(binding.recyclerView, 0, height, 0, 0); binding.slidingTabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override @@ -182,7 +188,7 @@ public class LogsFragment extends BaseFragment { new LogsReader().execute(parcelFileDescriptor.getFileDescriptor()); } else { binding.slidingTabs.selectTab(binding.slidingTabs.getTabAt(0)); - new AlertDialog.Builder(requireActivity()) + new MaterialAlertDialogBuilder(requireActivity()) .setMessage(R.string.verbose_log_not_avaliable) .setPositiveButton(android.R.string.ok, null) .show(); @@ -250,7 +256,7 @@ public class LogsFragment extends BaseFragment { @Override protected void onPreExecute() { - mProgressDialog = new AlertDialog.Builder(requireActivity()).create(); + mProgressDialog = new MaterialAlertDialogBuilder(requireActivity()).create(); mProgressDialog.setMessage(getString(R.string.loading)); mProgressDialog.setCancelable(false); handler.postDelayed(mRunnable, 300); diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/ModulesFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/ModulesFragment.java index 67394684..93d4df6e 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/ModulesFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/ModulesFragment.java @@ -50,7 +50,6 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.SearchView; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; @@ -63,6 +62,7 @@ import androidx.viewpager2.widget.ViewPager2; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.checkbox.MaterialCheckBox; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; @@ -138,6 +138,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi binding.getRoot().bringChildToFront(binding.appBar); setupToolbar(binding.toolbar, R.string.Modules, R.menu.menu_modules); + binding.appBar.setLiftable(true); binding.viewPager.setAdapter(new PagerAdapter(this)); binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override @@ -145,7 +146,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi BorderRecyclerView recyclerView = binding.viewPager.findViewWithTag(position); if (recyclerView != null) { - binding.appBar.setRaised(!recyclerView.getBorderViewDelegate().isShowingTopBorder()); + binding.appBar.setLifted(!recyclerView.getBorderViewDelegate().isShowingTopBorder()); } if (position > 0) { @@ -204,7 +205,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi var rv = DialogRecyclerviewBinding.inflate(getLayoutInflater()).getRoot(); rv.setAdapter(pickAdaptor); rv.setLayoutManager(new LinearLayoutManager(requireActivity())); - var dialog = new AlertDialog.Builder(requireActivity()) + var dialog = new MaterialAlertDialogBuilder(requireActivity()) .setTitle(getString(R.string.install_to_user, user.name)) .setView(rv) .setNegativeButton(android.R.string.cancel, null) @@ -252,7 +253,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi } private void installModuleToUser(ModuleUtil.InstalledModule module, UserInfo user) { - new AlertDialog.Builder(requireActivity()) + new MaterialAlertDialogBuilder(requireActivity()) .setTitle(getString(R.string.install_to_user, user.name)) .setMessage(getString(R.string.install_to_user_message, module.getAppName(), user.name)) .setPositiveButton(android.R.string.ok, (dialog, which) -> @@ -301,7 +302,7 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi ConfigManager.startActivityAsUserWithFeature(new Intent(ACTION_APPLICATION_DETAILS_SETTINGS, Uri.fromParts("package", selectedModule.packageName, null)), selectedModule.userId); return true; } else if (itemId == R.id.menu_uninstall) { - new AlertDialog.Builder(requireActivity()) + new MaterialAlertDialogBuilder(requireActivity()) .setTitle(selectedModule.getAppName()) .setMessage(R.string.module_uninstall_message) .setPositiveButton(android.R.string.ok, (dialog, which) -> @@ -347,12 +348,16 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi ItemRepoRecyclerviewBinding binding = ItemRepoRecyclerviewBinding.inflate(getLayoutInflater(), container, false); if (fragment.adapters.size() == 1) { WindowInsetsHelperKt.setInitialPadding(binding.recyclerView, 0, ResourceUtils.resolveDimensionPixelOffset(requireActivity().getTheme(), androidx.appcompat.R.attr.actionBarSize, 0), 0, 0); + } else { + int height = ResourceUtils.resolveDimensionPixelOffset(requireActivity().getTheme(), androidx.appcompat.R.attr.actionBarSize, 0) + + getResources().getDimensionPixelOffset(R.dimen.tab_layout_height); + WindowInsetsHelperKt.setInitialPadding(binding.recyclerView, 0, height, 0, 0); } binding.recyclerView.setTag(position); binding.recyclerView.setAdapter(fragment.adapters.get(position)); RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(requireActivity()); binding.recyclerView.setLayoutManager(layoutManager); - binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> fragment.binding.appBar.setRaised(!top)); + binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> fragment.binding.appBar.setLifted(!top)); binding.recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java index 92e62ea4..d17892a3 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoFragment.java @@ -104,7 +104,8 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener { binding = FragmentRepoBinding.inflate(getLayoutInflater(), container, false); binding.getRoot().bringChildToFront(binding.appBar); setupToolbar(binding.toolbar, R.string.module_repo, R.menu.menu_repo); - binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top)); + binding.appBar.setLiftable(true); + binding.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top)); adapter = new RepoAdapter(); adapter.setHasStableIds(true); binding.recyclerView.setAdapter(adapter); diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java index ac802638..6d7ee8a0 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/RepoItemFragment.java @@ -39,12 +39,12 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.progressindicator.CircularProgressIndicator; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayout; @@ -78,6 +78,7 @@ import okhttp3.Headers; import okhttp3.Request; import okhttp3.Response; import rikka.core.util.ResourceUtils; +import rikka.insets.WindowInsetsHelperKt; import rikka.recyclerview.RecyclerViewKt; import rikka.widget.borderview.BorderNestedScrollView; import rikka.widget.borderview.BorderRecyclerView; @@ -97,6 +98,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene String moduleName = module.getDescription(); binding.getRoot().bringChildToFront(binding.appBar); setupToolbar(binding.toolbar, moduleName, R.menu.menu_repo_item); + binding.appBar.setLiftable(true); binding.toolbar.setSubtitle(modulePackageName); binding.viewPager.setAdapter(new PagerAdapter()); binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @@ -105,7 +107,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene BorderView borderView = binding.viewPager.findViewWithTag(position); if (borderView != null) { - binding.appBar.setRaised(!borderView.getBorderViewDelegate().isShowingTopBorder()); + binding.appBar.setLifted(!borderView.getBorderViewDelegate().isShowingTopBorder()); } } }); @@ -374,7 +376,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene holder.viewAssets.setOnClickListener(v -> { ArrayList names = new ArrayList<>(); assets.forEach(releaseAsset -> names.add(releaseAsset.getName())); - new AlertDialog.Builder(requireActivity()) + new MaterialAlertDialogBuilder(requireActivity()) .setItems(names.toArray(new String[0]), (dialog, which) -> NavUtil.startURL(requireActivity(), assets.get(which).getDownloadUrl())) .show(); }); @@ -441,7 +443,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene public void onBindViewHolder(@NonNull PagerAdapter.ViewHolder holder, int position) { switch (position) { case 0: - holder.scrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top)); + holder.scrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top)); holder.scrollView.setTag(position); if (module != null) renderGithubMarkdown(holder.webView, module.getReadmeHTML()); @@ -453,9 +455,12 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene } else { holder.recyclerView.setAdapter(new InformationAdapter(module)); } + int height = ResourceUtils.resolveDimensionPixelOffset(requireActivity().getTheme(), androidx.appcompat.R.attr.actionBarSize, 0) + + getResources().getDimensionPixelOffset(R.dimen.tab_layout_height); + WindowInsetsHelperKt.setInitialPadding(holder.recyclerView, 0, height, 0, 0); holder.recyclerView.setTag(position); holder.recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity())); - holder.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top)); + holder.recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setLifted(!top)); var insets = requireActivity().getWindow().getDecorView().getRootWindowInsets(); if (insets != null) holder.recyclerView.onApplyWindowInsets(insets); diff --git a/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java b/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java index 0ef7b3af..afb8c122 100644 --- a/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java +++ b/app/src/main/java/org/lsposed/manager/ui/fragment/SettingsFragment.java @@ -40,6 +40,7 @@ import androidx.preference.Preference; import androidx.preference.SwitchPreference; import androidx.recyclerview.widget.RecyclerView; +import com.google.android.material.color.DynamicColors; import com.google.android.material.snackbar.Snackbar; import com.takisoft.preferencex.PreferenceFragmentCompat; @@ -72,6 +73,7 @@ public class SettingsFragment extends BaseFragment { public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { binding = FragmentSettingsBinding.inflate(inflater, container, false); binding.getRoot().bringChildToFront(binding.appBar); + binding.appBar.setLiftable(true); setupToolbar(binding.toolbar, R.string.Settings); if (savedInstanceState == null) { getChildFragmentManager().beginTransaction() @@ -227,7 +229,7 @@ public class SettingsFragment extends BaseFragment { } SwitchPreference prefFollowSystemAccent = findPreference("follow_system_accent"); - if (prefFollowSystemAccent != null && (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || Build.VERSION.SDK_INT == Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0)) { + if (prefFollowSystemAccent != null && DynamicColors.isDynamicColorAvailable()) { if (primary_color != null) { primary_color.setVisible(!prefFollowSystemAccent.isChecked()); } @@ -302,7 +304,7 @@ public class SettingsFragment extends BaseFragment { recyclerView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> { SettingsFragment fragment = (SettingsFragment) getParentFragment(); if (fragment != null) { - fragment.binding.appBar.setRaised(!top); + fragment.binding.appBar.setLifted(!top); } }); return recyclerView; diff --git a/app/src/main/java/org/lsposed/manager/util/theme/ThemeColorPreferenceDialogFragmentCompat.java b/app/src/main/java/org/lsposed/manager/util/theme/ThemeColorPreferenceDialogFragmentCompat.java index b7187869..0e9eb7c4 100644 --- a/app/src/main/java/org/lsposed/manager/util/theme/ThemeColorPreferenceDialogFragmentCompat.java +++ b/app/src/main/java/org/lsposed/manager/util/theme/ThemeColorPreferenceDialogFragmentCompat.java @@ -19,22 +19,68 @@ package org.lsposed.manager.util.theme; +import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap; + +import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; +import android.content.Context; import android.content.DialogInterface; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; +import android.util.TypedValue; +import android.view.View; +import android.view.Window; +import androidx.annotation.AttrRes; import androidx.annotation.NonNull; +import androidx.annotation.StyleRes; +import androidx.appcompat.view.ContextThemeWrapper; +import androidx.core.view.ViewCompat; import androidx.preference.PreferenceDialogFragmentCompat; +import com.google.android.material.color.MaterialColors; +import com.google.android.material.dialog.InsetDialogOnTouchListener; +import com.google.android.material.dialog.MaterialDialogs; +import com.google.android.material.resources.MaterialAttributes; +import com.google.android.material.shape.MaterialShapeDrawable; import com.takisoft.colorpicker.ColorPickerDialog; import com.takisoft.colorpicker.OnColorSelectedListener; +@SuppressLint("RestrictedApi") public class ThemeColorPreferenceDialogFragmentCompat extends PreferenceDialogFragmentCompat implements OnColorSelectedListener { private int pickedColor; ThemeUtil.CustomThemeColors[] themeColors; private int[] colors; + @AttrRes + private static final int DEF_STYLE_ATTR = com.google.android.material.R.attr.alertDialogStyle; + @StyleRes + private static final int DEF_STYLE_RES = com.google.android.material.R.style.MaterialAlertDialog_MaterialComponents; + @AttrRes + private static final int MATERIAL_ALERT_DIALOG_THEME_OVERLAY = com.google.android.material.R.attr.materialAlertDialogTheme; + + private static int getMaterialAlertDialogThemeOverlay(@NonNull Context context) { + TypedValue materialAlertDialogThemeOverlay = + MaterialAttributes.resolve(context, MATERIAL_ALERT_DIALOG_THEME_OVERLAY); + if (materialAlertDialogThemeOverlay == null) { + return 0; + } + return materialAlertDialogThemeOverlay.data; + } + + private static Context createMaterialAlertDialogThemedContext(@NonNull Context context) { + int themeOverlayId = getMaterialAlertDialogThemeOverlay(context); + Context themedContext = wrap(context, null, DEF_STYLE_ATTR, DEF_STYLE_RES); + if (themeOverlayId == 0) { + return themedContext; + } + return new ContextThemeWrapper(themedContext, themeOverlayId); + } @NonNull @Override @@ -48,8 +94,9 @@ public class ThemeColorPreferenceDialogFragmentCompat extends PreferenceDialogFr for (int i = 0; i < themeColors.length; i++) { colors[i] = activity.getColor(themeColors[i].getResourceId()); } + Context context = createMaterialAlertDialogThemedContext(activity); - ColorPickerDialog.Params params = new ColorPickerDialog.Params.Builder(activity) + ColorPickerDialog.Params params = new ColorPickerDialog.Params.Builder(context) .setSelectedColor(selectedColor) .setColors(colors) .setSize(ColorPickerDialog.SIZE_SMALL) @@ -57,8 +104,40 @@ public class ThemeColorPreferenceDialogFragmentCompat extends PreferenceDialogFr .setColumns(0) .build(); - ColorPickerDialog dialog = new ColorPickerDialog(activity, this, params); + Resources.Theme theme = context.getTheme(); + + Rect backgroundInsets = MaterialDialogs.getDialogBackgroundInsets(context, DEF_STYLE_ATTR, DEF_STYLE_RES); + + int surfaceColor = + MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, getClass().getCanonicalName()); + MaterialShapeDrawable materialShapeDrawable = + new MaterialShapeDrawable(context, null, DEF_STYLE_ATTR, DEF_STYLE_RES); + materialShapeDrawable.initializeElevationOverlay(context); + materialShapeDrawable.setFillColor(ColorStateList.valueOf(surfaceColor)); + + // dialogCornerRadius first appeared in Android Pie + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + TypedValue dialogCornerRadiusValue = new TypedValue(); + theme.resolveAttribute(android.R.attr.dialogCornerRadius, dialogCornerRadiusValue, true); + float dialogCornerRadius = + dialogCornerRadiusValue.getDimension(getContext().getResources().getDisplayMetrics()); + if (dialogCornerRadiusValue.type == TypedValue.TYPE_DIMENSION && dialogCornerRadius >= 0) { + materialShapeDrawable.setCornerSize(dialogCornerRadius); + } + } + ColorPickerDialog dialog = new ColorPickerDialog(context, this, params); dialog.setTitle(pref.getDialogTitle()); + Window window = dialog.getWindow(); + /* {@link Window#getDecorView()} should be called before any changes are made to the Window + * as it locks in attributes and affects layout. */ + View decorView = window.getDecorView(); + if (materialShapeDrawable instanceof MaterialShapeDrawable) { + ((MaterialShapeDrawable) materialShapeDrawable).setElevation(ViewCompat.getElevation(decorView)); + } + + Drawable insetDrawable = MaterialDialogs.insetDrawable(materialShapeDrawable, backgroundInsets); + window.setBackgroundDrawable(insetDrawable); + decorView.setOnTouchListener(new InsetDialogOnTouchListener(dialog, backgroundInsets)); return dialog; } diff --git a/app/src/main/java/org/lsposed/manager/util/theme/ThemeUtil.java b/app/src/main/java/org/lsposed/manager/util/theme/ThemeUtil.java index fee9137f..468cbfe2 100644 --- a/app/src/main/java/org/lsposed/manager/util/theme/ThemeUtil.java +++ b/app/src/main/java/org/lsposed/manager/util/theme/ThemeUtil.java @@ -21,11 +21,12 @@ package org.lsposed.manager.util.theme; import android.content.Context; import android.content.SharedPreferences; -import android.os.Build; import androidx.annotation.ColorRes; import androidx.annotation.StyleRes; +import com.google.android.material.color.DynamicColors; + import org.lsposed.manager.App; import org.lsposed.manager.R; @@ -74,7 +75,7 @@ public class ThemeUtil { return preferences.getBoolean("black_dark_theme", false); } - private static boolean isSystemAccent() { + public static boolean isSystemAccent() { return preferences.getBoolean("follow_system_accent", true); } @@ -98,7 +99,7 @@ public class ThemeUtil { } public static String getColorTheme() { - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || Build.VERSION.SDK_INT == Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0) && isSystemAccent()) { + if (DynamicColors.isDynamicColorAvailable() && isSystemAccent()) { return "system"; } String primaryColorEntryName = "COLOR_PRIMARY"; @@ -113,9 +114,6 @@ public class ThemeUtil { @StyleRes public static int getColorThemeStyleRes() { - if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || Build.VERSION.SDK_INT == Build.VERSION_CODES.R && Build.VERSION.PREVIEW_SDK_INT != 0) && isSystemAccent()) { - return R.style.ThemeOverlay_system; - } Integer theme = colorThemeMap.get(getColorTheme()); if (theme == null) { return R.style.ThemeOverlay_color_primary; diff --git a/app/src/main/res/color-v31/primary_text_md3_dark.xml b/app/src/main/res/color-v31/primary_text_md3_dark.xml deleted file mode 100644 index f3908cb2..00000000 --- a/app/src/main/res/color-v31/primary_text_md3_dark.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/color-v31/primary_text_md3_light.xml b/app/src/main/res/color-v31/primary_text_md3_light.xml deleted file mode 100644 index 3013d087..00000000 --- a/app/src/main/res/color-v31/primary_text_md3_light.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/color-v31/secondary_text_md3_dark.xml b/app/src/main/res/color-v31/secondary_text_md3_dark.xml deleted file mode 100644 index b3151cda..00000000 --- a/app/src/main/res/color-v31/secondary_text_md3_dark.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/color-v31/secondary_text_md3_light.xml b/app/src/main/res/color-v31/secondary_text_md3_light.xml deleted file mode 100644 index 5e5b5871..00000000 --- a/app/src/main/res/color-v31/secondary_text_md3_light.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/color-v31/tertiary_text_md3_dark.xml b/app/src/main/res/color-v31/tertiary_text_md3_dark.xml deleted file mode 100644 index 50de8eae..00000000 --- a/app/src/main/res/color-v31/tertiary_text_md3_dark.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/color-v31/tertiary_text_md3_light.xml b/app/src/main/res/color-v31/tertiary_text_md3_light.xml deleted file mode 100644 index 41be2965..00000000 --- a/app/src/main/res/color-v31/tertiary_text_md3_light.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/layout/fragment_app_list.xml b/app/src/main/res/layout/fragment_app_list.xml index be9525e3..e439bd62 100644 --- a/app/src/main/res/layout/fragment_app_list.xml +++ b/app/src/main/res/layout/fragment_app_list.xml @@ -28,23 +28,20 @@ app:edgeToEdge="true" app:fitsSystemWindowsInsets="start|end"> - - + android:elevation="0dp" /> - + - - + android:elevation="0dp" /> - + - @@ -39,14 +38,12 @@ android:layout_height="match_parent" android:orientation="vertical"> - + android:elevation="0dp" /> - + - @@ -39,14 +38,12 @@ android:layout_height="match_parent" android:orientation="vertical"> - + android:elevation="0dp" /> - + - - + android:elevation="0dp" /> - + - - + android:elevation="0dp" /> - + + style="@style/Widget.MaterialComponents.Button.Icon" /> - - - - - @color/color_primary_md3_dark - - @color/color_background_md3_dark - - @color/color_surface_md3_dark - - @color/color_background_floating_md3_dark - - @color/primary_text_md3_dark - @color/primary_text_md3_light - @color/secondary_text_md3_dark - @color/secondary_text_md3_light - @color/tertiary_text_md3_dark - @color/tertiary_text_md3_light - diff --git a/app/src/main/res/values-v31/colors_custom.xml b/app/src/main/res/values-v31/colors_custom.xml deleted file mode 100644 index b4760d19..00000000 --- a/app/src/main/res/values-v31/colors_custom.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - @android:color/system_accent1_600 - @android:color/system_accent1_200 - @color/color_primary_md3_light - - @android:color/system_neutral1_50 - @android:color/system_neutral1_900 - @color/color_surface_md3_light - - @android:color/system_neutral1_50 - @android:color/system_neutral1_800 - @color/color_background_md3_light - - @android:color/system_neutral1_50 - @android:color/system_neutral1_800 - @color/color_background_floating_md3_light - - @color/primary_text_md3_light - @color/primary_text_md3_dark - @color/secondary_text_md3_light - @color/secondary_text_md3_dark - @color/tertiary_text_md3_light - @color/tertiary_text_md3_dark - diff --git a/app/src/main/res/values-v31/themes_custom.xml b/app/src/main/res/values-v31/themes_custom.xml deleted file mode 100644 index b29ac905..00000000 --- a/app/src/main/res/values-v31/themes_custom.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 8081c1a8..f02e6a35 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -32,12 +32,6 @@ @color/material_green_500 @color/material_blue_500 - @style/Widget.Material.ActionBar.Surface - @style/ThemeOverlay.ActionBar - @style/Widget.Material.Toolbar - - @style/Widget.AppBar.Surface.Raisable - false true false @@ -60,12 +54,6 @@ @color/material_green_200 @color/material_blue_200 - @style/Widget.Material.ActionBar.Surface - @style/ThemeOverlay.ActionBar - @style/Widget.Material.Toolbar - - @style/Widget.AppBar.Surface.Raisable - false true false @@ -77,45 +65,6 @@ - - - - - - - - - - - + + diff --git a/app/src/main/res/values/themes_override.xml b/app/src/main/res/values/themes_override.xml index 90c612cd..406ce282 100644 --- a/app/src/main/res/values/themes_override.xml +++ b/app/src/main/res/values/themes_override.xml @@ -43,7 +43,7 @@ true - - - - - - - - -