[app] Fix hint text (#1397)

* [app] Fix hint text

* Fix text underline
This commit is contained in:
LoveSy 2021-11-12 20:28:38 +08:00 committed by GitHub
parent 09656bb497
commit 6dcceec3c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 38 deletions

View File

@ -198,31 +198,38 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener {
holder.appName.setText(module.getDescription()); holder.appName.setText(module.getDescription());
SpannableStringBuilder sb = new SpannableStringBuilder(module.getName()); SpannableStringBuilder sb = new SpannableStringBuilder(module.getName());
ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(module.getName());
if (installedModule != null) {
var ver = repoLoader.getModuleLatestVersion(installedModule.packageName);
if (ver != null && ver.upgradable(installedModule.versionCode, installedModule.versionName)) {
sb.append("\n");
String recommended = getString(R.string.update_available, ver.versionName);
sb.append(recommended);
final ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ResourceUtils.resolveColor(requireActivity().getTheme(), androidx.appcompat.R.attr.colorAccent));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
final TypefaceSpan typefaceSpan = new TypefaceSpan(Typeface.create("sans-serif-medium", Typeface.NORMAL));
sb.setSpan(typefaceSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
} else {
final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
sb.setSpan(styleSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
sb.setSpan(foregroundColorSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
}
String summary = module.getSummary(); String summary = module.getSummary();
if (summary != null) { if (summary != null) {
sb.append("\n"); sb.append("\n");
sb.append(summary); sb.append(summary);
} }
holder.appDescription.setVisibility(View.VISIBLE);
holder.appDescription.setText(sb); holder.appDescription.setText(sb);
sb = new SpannableStringBuilder();
ModuleUtil.InstalledModule installedModule = ModuleUtil.getInstance().getModule(module.getName());
if (installedModule != null) {
var ver = repoLoader.getModuleLatestVersion(installedModule.packageName);
if (ver != null && ver.upgradable(installedModule.versionCode, installedModule.versionName)) {
String hint = getString(R.string.update_available, ver.versionName);
sb.append(hint);
final ForegroundColorSpan foregroundColorSpan = new ForegroundColorSpan(ResourceUtils.resolveColor(requireActivity().getTheme(), androidx.appcompat.R.attr.colorAccent));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
final TypefaceSpan typefaceSpan = new TypefaceSpan(Typeface.create("sans-serif-medium", Typeface.NORMAL));
sb.setSpan(typefaceSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
} else {
final StyleSpan styleSpan = new StyleSpan(Typeface.BOLD);
sb.setSpan(styleSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
sb.setSpan(foregroundColorSpan, sb.length() - hint.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
}
if (sb.length() > 0) {
holder.hint.setVisibility(View.VISIBLE);
holder.hint.setText(sb);
} else {
holder.hint.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(v -> { holder.itemView.setOnClickListener(v -> {
searchView.clearFocus(); searchView.clearFocus();
@ -273,12 +280,14 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener {
ConstraintLayout root; ConstraintLayout root;
TextView appName; TextView appName;
TextView appDescription; TextView appDescription;
TextView hint;
ViewHolder(ItemOnlinemoduleBinding binding) { ViewHolder(ItemOnlinemoduleBinding binding) {
super(binding.getRoot()); super(binding.getRoot());
root = binding.itemRoot; root = binding.itemRoot;
appName = binding.appName; appName = binding.appName;
appDescription = binding.description; appDescription = binding.description;
hint = binding.hint;
} }
} }

View File

@ -71,6 +71,7 @@ public class ExpandableTextView extends MaterialTextView {
@Override @Override
public void updateDrawState(@NonNull TextPaint ds) { public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setTypeface(Typeface.DEFAULT_BOLD); ds.setTypeface(Typeface.DEFAULT_BOLD);
} }
}; };

View File

@ -58,11 +58,24 @@
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:maxLines="6" android:maxLines="6"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/app_name" app:layout_constraintStart_toStartOf="@+id/app_name"
app:layout_constraintTop_toBottomOf="@id/app_name" app:layout_constraintTop_toBottomOf="@id/app_name"
tools:text="@tools:sample/lorem" /> tools:text="@tools:sample/lorem" />
<TextView
android:id="@+id/hint"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/description"
tools:text="@tools:sample/lorem" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout> </FrameLayout>

View File

@ -1,9 +1,5 @@
// All content of this file is released to the public domain. // This is the public API for Zygisk modules.
// DO NOT MODIFY ANY CODE IN THIS HEADER.
// This file is the public API for Zygisk modules.
// DO NOT use this file for developing Zygisk modules as it might contain WIP changes.
// Always use the following header for development as those are finalized APIs:
// https://github.com/topjohnwu/zygisk-module-sample/blob/master/module/jni/zygisk.hpp
#pragma once #pragma once
@ -12,14 +8,20 @@
#define ZYGISK_API_VERSION 1 #define ZYGISK_API_VERSION 1
/* /*
Define a class and inherit zygisk::ModuleBase to implement the functionality of your module. Define a class and inherit zygisk::ModuleBase to implement the functionality of your module.
Use the macro REGISTER_ZYGISK_MODULE(className) to register that class to Zygisk. Use the macro REGISTER_ZYGISK_MODULE(className) to register that class to Zygisk.
Please note that modules will only be loaded after zygote has forked the child process. Please note that modules will only be loaded after zygote has forked the child process.
THIS MEANS ALL OF YOUR CODE RUNS IN THE APP/SYSTEM SERVER PROCESS, NOT THE ZYGOTE DAEMON! THIS MEANS ALL OF YOUR CODE RUNS IN THE APP/SYSTEM SERVER PROCESS, NOT THE ZYGOTE DAEMON!
Example code: Example code:
static jint (*orig_logger_entry_max)(JNIEnv *env); static jint (*orig_logger_entry_max)(JNIEnv *env);
static jint my_logger_entry_max(JNIEnv *env) { return orig_logger_entry_max(env); } static jint my_logger_entry_max(JNIEnv *env) { return orig_logger_entry_max(env); }
static void example_handler(int socket) { ... } static void example_handler(int socket) { ... }
class ExampleModule : public zygisk::ModuleBase { class ExampleModule : public zygisk::ModuleBase {
public: public:
void onLoad(zygisk::Api *api, JNIEnv *env) override { void onLoad(zygisk::Api *api, JNIEnv *env) override {
@ -37,8 +39,11 @@ private:
zygisk::Api *api; zygisk::Api *api;
JNIEnv *env; JNIEnv *env;
}; };
REGISTER_ZYGISK_MODULE(ExampleModule) REGISTER_ZYGISK_MODULE(ExampleModule)
REGISTER_ZYGISK_COMPANION(example_handler) REGISTER_ZYGISK_COMPANION(example_handler)
*/ */
namespace zygisk { namespace zygisk {
@ -143,6 +148,8 @@ namespace zygisk {
DLCLOSE_MODULE_LIBRARY = 1, DLCLOSE_MODULE_LIBRARY = 1,
}; };
// All API functions will stop working after post[XXX]Specialize as Zygisk will be unloaded
// from the specialized process afterwards.
struct Api { struct Api {
// Connect to a root companion process and get a Unix domain socket for IPC. // Connect to a root companion process and get a Unix domain socket for IPC.
@ -264,23 +271,23 @@ void zygisk_companion_entry(int client) { func(client); }
} // namespace internal } // namespace internal
int Api::connectCompanion() { inline int Api::connectCompanion() {
return impl->connectCompanion(impl->_this); return impl->connectCompanion ? impl->connectCompanion(impl->_this) : -1;
} }
void Api::setOption(Option opt) { inline void Api::setOption(Option opt) {
impl->setOption(impl->_this, opt); if (impl->setOption) impl->setOption(impl->_this, opt);
} }
void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) { inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
impl->hookJniNativeMethods(env, className, methods, numMethods); if (impl->hookJniNativeMethods) impl->hookJniNativeMethods(env, className, methods, numMethods);
} }
void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) { inline void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) {
impl->pltHookRegister(regex, symbol, newFunc, oldFunc); if (impl->pltHookRegister) impl->pltHookRegister(regex, symbol, newFunc, oldFunc);
} }
void Api::pltHookExclude(const char *regex, const char *symbol) { inline void Api::pltHookExclude(const char *regex, const char *symbol) {
impl->pltHookExclude(regex, symbol); if (impl->pltHookExclude) impl->pltHookExclude(regex, symbol);
} }
bool Api::pltHookCommit() { inline bool Api::pltHookCommit() {
return impl->pltHookCommit(); return impl->pltHookCommit != nullptr && impl->pltHookCommit();
} }
} // namespace zygisk } // namespace zygisk