[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());
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();
if (summary != null) {
sb.append("\n");
sb.append(summary);
}
holder.appDescription.setVisibility(View.VISIBLE);
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 -> {
searchView.clearFocus();
@ -273,12 +280,14 @@ public class RepoFragment extends BaseFragment implements RepoLoader.Listener {
ConstraintLayout root;
TextView appName;
TextView appDescription;
TextView hint;
ViewHolder(ItemOnlinemoduleBinding binding) {
super(binding.getRoot());
root = binding.itemRoot;
appName = binding.appName;
appDescription = binding.description;
hint = binding.hint;
}
}

View File

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

View File

@ -58,11 +58,24 @@
android:layout_gravity="center_vertical"
android:maxLines="6"
android:textAppearance="?android:attr/textAppearanceSmall"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/app_name"
app:layout_constraintTop_toBottomOf="@id/app_name"
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>
</FrameLayout>

View File

@ -1,9 +1,5 @@
// All content of this file is released to the public domain.
// 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
// This is the public API for Zygisk modules.
// DO NOT MODIFY ANY CODE IN THIS HEADER.
#pragma once
@ -12,14 +8,20 @@
#define ZYGISK_API_VERSION 1
/*
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.
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!
Example code:
static jint (*orig_logger_entry_max)(JNIEnv *env);
static jint my_logger_entry_max(JNIEnv *env) { return orig_logger_entry_max(env); }
static void example_handler(int socket) { ... }
class ExampleModule : public zygisk::ModuleBase {
public:
void onLoad(zygisk::Api *api, JNIEnv *env) override {
@ -37,8 +39,11 @@ private:
zygisk::Api *api;
JNIEnv *env;
};
REGISTER_ZYGISK_MODULE(ExampleModule)
REGISTER_ZYGISK_COMPANION(example_handler)
*/
namespace zygisk {
@ -143,6 +148,8 @@ namespace zygisk {
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 {
// 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
int Api::connectCompanion() {
return impl->connectCompanion(impl->_this);
inline int Api::connectCompanion() {
return impl->connectCompanion ? impl->connectCompanion(impl->_this) : -1;
}
void Api::setOption(Option opt) {
impl->setOption(impl->_this, opt);
inline void Api::setOption(Option opt) {
if (impl->setOption) impl->setOption(impl->_this, opt);
}
void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
impl->hookJniNativeMethods(env, className, methods, numMethods);
inline void Api::hookJniNativeMethods(JNIEnv *env, const char *className, JNINativeMethod *methods, int numMethods) {
if (impl->hookJniNativeMethods) impl->hookJniNativeMethods(env, className, methods, numMethods);
}
void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) {
impl->pltHookRegister(regex, symbol, newFunc, oldFunc);
inline void Api::pltHookRegister(const char *regex, const char *symbol, void *newFunc, void **oldFunc) {
if (impl->pltHookRegister) impl->pltHookRegister(regex, symbol, newFunc, oldFunc);
}
void Api::pltHookExclude(const char *regex, const char *symbol) {
impl->pltHookExclude(regex, symbol);
inline void Api::pltHookExclude(const char *regex, const char *symbol) {
if (impl->pltHookExclude) impl->pltHookExclude(regex, symbol);
}
bool Api::pltHookCommit() {
return impl->pltHookCommit();
inline bool Api::pltHookCommit() {
return impl->pltHookCommit != nullptr && impl->pltHookCommit();
}
} // namespace zygisk