[app] Nuke markown (#767)
This commit is contained in:
parent
1ee42aea79
commit
1eebbca320
|
|
@ -206,11 +206,12 @@ dependencies {
|
||||||
implementation("androidx.browser:browser:1.3.0")
|
implementation("androidx.browser:browser:1.3.0")
|
||||||
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
|
implementation("androidx.constraintlayout:constraintlayout:2.0.4")
|
||||||
implementation("androidx.core:core:1.5.0")
|
implementation("androidx.core:core:1.5.0")
|
||||||
implementation("androidx.fragment:fragment:1.3.4")
|
implementation("androidx.fragment:fragment:1.3.5")
|
||||||
implementation("androidx.navigation:navigation-fragment:$navVersion")
|
implementation("androidx.navigation:navigation-fragment:$navVersion")
|
||||||
implementation("androidx.navigation:navigation-ui:$navVersion")
|
implementation("androidx.navigation:navigation-ui:$navVersion")
|
||||||
implementation("androidx.recyclerview:recyclerview:1.2.1")
|
implementation("androidx.recyclerview:recyclerview:1.2.1")
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
|
implementation("androidx.webkit:webkit:1.4.0")
|
||||||
implementation("com.caverock:androidsvg-aar:1.4")
|
implementation("com.caverock:androidsvg-aar:1.4")
|
||||||
implementation("com.github.bumptech.glide:glide:$glideVersion")
|
implementation("com.github.bumptech.glide:glide:$glideVersion")
|
||||||
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion")
|
implementation("com.github.bumptech.glide:okhttp3-integration:$glideVersion")
|
||||||
|
|
@ -230,13 +231,6 @@ dependencies {
|
||||||
implementation("dev.rikka.rikkax.widget:borderview:1.0.1")
|
implementation("dev.rikka.rikkax.widget:borderview:1.0.1")
|
||||||
implementation("dev.rikka.rikkax.widget:switchbar:1.0.2")
|
implementation("dev.rikka.rikkax.widget:switchbar:1.0.2")
|
||||||
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.0.1")
|
implementation("dev.rikka.rikkax.layoutinflater:layoutinflater:1.0.1")
|
||||||
implementation("io.noties.markwon:core:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:ext-strikethrough:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:ext-tables:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:ext-tasklist:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:html:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:image-glide:$markwonVersion")
|
|
||||||
implementation("io.noties.markwon:linkify:$markwonVersion")
|
|
||||||
implementation("me.zhanghai.android.appiconloader:appiconloader-glide:1.3.1")
|
implementation("me.zhanghai.android.appiconloader:appiconloader-glide:1.3.1")
|
||||||
implementation("me.zhanghai.android.fastscroll:library:1.1.6")
|
implementation("me.zhanghai.android.fastscroll:library:1.1.6")
|
||||||
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:2.0")
|
implementation("org.lsposed.hiddenapibypass:hiddenapibypass:2.0")
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@ import java.io.StringWriter;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import okhttp3.Cache;
|
import okhttp3.Cache;
|
||||||
|
import okhttp3.MediaType;
|
||||||
import okhttp3.OkHttpClient;
|
import okhttp3.OkHttpClient;
|
||||||
import okhttp3.logging.HttpLoggingInterceptor;
|
import okhttp3.logging.HttpLoggingInterceptor;
|
||||||
import rikka.material.app.DayNightDelegate;
|
import rikka.material.app.DayNightDelegate;
|
||||||
|
|
@ -62,6 +63,10 @@ public class App extends Application {
|
||||||
private static Cache okHttpCache;
|
private static Cache okHttpCache;
|
||||||
private SharedPreferences pref;
|
private SharedPreferences pref;
|
||||||
|
|
||||||
|
public static final MediaType JSON
|
||||||
|
= MediaType.get("application/json; charset=utf-8");
|
||||||
|
|
||||||
|
|
||||||
public static App getInstance() {
|
public static App getInstance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,25 @@
|
||||||
|
|
||||||
package org.lsposed.manager.ui.fragment;
|
package org.lsposed.manager.ui.fragment;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.style.ClickableSpan;
|
import android.text.style.ClickableSpan;
|
||||||
import android.text.util.Linkify;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.webkit.RenderProcessGoneDetail;
|
||||||
|
import android.webkit.WebResourceRequest;
|
||||||
|
import android.webkit.WebResourceResponse;
|
||||||
|
import android.webkit.WebSettings;
|
||||||
|
import android.webkit.WebView;
|
||||||
|
import android.webkit.WebViewClient;
|
||||||
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
@ -37,12 +46,16 @@ import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.lifecycle.Lifecycle;
|
import androidx.lifecycle.Lifecycle;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import androidx.viewpager2.widget.ViewPager2;
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
import androidx.webkit.WebSettingsCompat;
|
||||||
|
import androidx.webkit.WebViewFeature;
|
||||||
|
|
||||||
import com.google.android.material.button.MaterialButton;
|
import com.google.android.material.button.MaterialButton;
|
||||||
import com.google.android.material.progressindicator.CircularProgressIndicator;
|
import com.google.android.material.progressindicator.CircularProgressIndicator;
|
||||||
import com.google.android.material.snackbar.Snackbar;
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.android.material.tabs.TabLayoutMediator;
|
import com.google.android.material.tabs.TabLayoutMediator;
|
||||||
|
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.lsposed.manager.App;
|
||||||
import org.lsposed.manager.R;
|
import org.lsposed.manager.R;
|
||||||
import org.lsposed.manager.databinding.FragmentPagerBinding;
|
import org.lsposed.manager.databinding.FragmentPagerBinding;
|
||||||
import org.lsposed.manager.databinding.ItemRepoLoadmoreBinding;
|
import org.lsposed.manager.databinding.ItemRepoLoadmoreBinding;
|
||||||
|
|
@ -56,25 +69,15 @@ import org.lsposed.manager.repo.model.OnlineModule;
|
||||||
import org.lsposed.manager.repo.model.Release;
|
import org.lsposed.manager.repo.model.Release;
|
||||||
import org.lsposed.manager.repo.model.ReleaseAsset;
|
import org.lsposed.manager.repo.model.ReleaseAsset;
|
||||||
import org.lsposed.manager.ui.widget.LinkifyTextView;
|
import org.lsposed.manager.ui.widget.LinkifyTextView;
|
||||||
import org.lsposed.manager.util.GlideApp;
|
|
||||||
import org.lsposed.manager.util.LinearLayoutManagerFix;
|
import org.lsposed.manager.util.LinearLayoutManagerFix;
|
||||||
import org.lsposed.manager.util.NavUtil;
|
import org.lsposed.manager.util.NavUtil;
|
||||||
import org.lsposed.manager.util.chrome.CustomTabsURLSpan;
|
import org.lsposed.manager.util.chrome.CustomTabsURLSpan;
|
||||||
import org.lsposed.manager.util.chrome.LinkTransformationMethod;
|
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
|
|
||||||
import io.noties.markwon.Markwon;
|
|
||||||
import io.noties.markwon.SoftBreakAddsNewLinePlugin;
|
|
||||||
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin;
|
|
||||||
import io.noties.markwon.ext.tables.TablePlugin;
|
|
||||||
import io.noties.markwon.ext.tasklist.TaskListPlugin;
|
|
||||||
import io.noties.markwon.html.HtmlPlugin;
|
|
||||||
import io.noties.markwon.image.glide.GlideImagesPlugin;
|
|
||||||
import io.noties.markwon.linkify.LinkifyPlugin;
|
|
||||||
import io.noties.markwon.utils.NoCopySpannableFactory;
|
|
||||||
import rikka.recyclerview.RecyclerViewKt;
|
import rikka.recyclerview.RecyclerViewKt;
|
||||||
import rikka.widget.borderview.BorderNestedScrollView;
|
import rikka.widget.borderview.BorderNestedScrollView;
|
||||||
import rikka.widget.borderview.BorderRecyclerView;
|
import rikka.widget.borderview.BorderRecyclerView;
|
||||||
|
|
@ -82,7 +85,6 @@ import rikka.widget.borderview.BorderView;
|
||||||
|
|
||||||
public class RepoItemFragment extends BaseFragment implements RepoLoader.Listener {
|
public class RepoItemFragment extends BaseFragment implements RepoLoader.Listener {
|
||||||
FragmentPagerBinding binding;
|
FragmentPagerBinding binding;
|
||||||
private Markwon markwon;
|
|
||||||
private OnlineModule module;
|
private OnlineModule module;
|
||||||
private ReleaseAdapter releaseAdapter;
|
private ReleaseAdapter releaseAdapter;
|
||||||
|
|
||||||
|
|
@ -121,20 +123,69 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
RepoLoader.getInstance().addListener(this);
|
RepoLoader.getInstance().addListener(this);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
markwon = Markwon.builder(requireActivity())
|
|
||||||
.usePlugin(StrikethroughPlugin.create())
|
|
||||||
.usePlugin(TablePlugin.create(requireActivity()))
|
|
||||||
.usePlugin(TaskListPlugin.create(requireActivity()))
|
|
||||||
.usePlugin(HtmlPlugin.create())
|
|
||||||
.usePlugin(GlideImagesPlugin.create(GlideApp.with(this)))
|
|
||||||
.usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS, true))
|
|
||||||
.usePlugin(SoftBreakAddsNewLinePlugin.create())
|
|
||||||
.build();
|
|
||||||
String modulePackageName = getArguments().getString("modulePackageName");
|
String modulePackageName = getArguments().getString("modulePackageName");
|
||||||
module = RepoLoader.getInstance().getOnlineModule(modulePackageName);
|
module = RepoLoader.getInstance().getOnlineModule(modulePackageName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderGithubMarkdown(WebView view, String text, ProgressBar progressBar) {
|
||||||
|
try {
|
||||||
|
var json = new JSONObject();
|
||||||
|
json.put("text", text);
|
||||||
|
view.setBackgroundColor(Color.TRANSPARENT);
|
||||||
|
var setting = view.getSettings();
|
||||||
|
setting.setDomStorageEnabled(true);
|
||||||
|
setting.setAppCacheEnabled(true);
|
||||||
|
setting.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
||||||
|
setting.setAllowContentAccess(false);
|
||||||
|
setting.setAllowFileAccess(false);
|
||||||
|
setting.setGeolocationEnabled(false);
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
|
||||||
|
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
|
||||||
|
if (nightModeFlags == Configuration.UI_MODE_NIGHT_YES) {
|
||||||
|
WebSettingsCompat.setForceDark(setting, WebSettingsCompat.FORCE_DARK_ON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK_STRATEGY)) {
|
||||||
|
WebSettingsCompat.setForceDarkStrategy(setting, WebSettingsCompat.DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING);
|
||||||
|
}
|
||||||
|
setting.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
|
||||||
|
view.setWebViewClient(new WebViewClient() {
|
||||||
|
@Override
|
||||||
|
public void onPageFinished(WebView view, String url) {
|
||||||
|
if (progressBar != null)
|
||||||
|
progressBar.setVisibility(ProgressBar.GONE);
|
||||||
|
super.onPageFinished(view, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||||
|
if (request.getUrl().toString().equals("https://api.github.com/markdown")) return false;
|
||||||
|
Intent i = new Intent(Intent.ACTION_VIEW, request.getUrl());
|
||||||
|
startActivity(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// wrapper for https://api.github.com/markdown
|
||||||
|
/*
|
||||||
|
async function handleRequest(request) {
|
||||||
|
let response = await fetch("https://api.github.com/markdown", request);
|
||||||
|
if (!response.ok) return response;
|
||||||
|
response = new Response(`<html><head><style>body{overflow-wrap: anywhere;font-size: 3vw;}</style></head><body>${await response.text()}</body></html>`, response);
|
||||||
|
response.headers.set(
|
||||||
|
"Content-Security-Policy",
|
||||||
|
"img-src *;"
|
||||||
|
)
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
view.postUrl("https://render.lsposed.workers.dev/", json.toString().getBytes(StandardCharsets.UTF_8));
|
||||||
|
} catch (Throwable e) {
|
||||||
|
android.util.Log.e(App.TAG, "render readme", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
|
||||||
int id = item.getItemId();
|
int id = item.getItemId();
|
||||||
|
|
@ -306,10 +357,8 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
} else {
|
} else {
|
||||||
Release release = items.get(position);
|
Release release = items.get(position);
|
||||||
holder.title.setText(release.getName());
|
holder.title.setText(release.getName());
|
||||||
holder.description.setTransformationMethod(new LinkTransformationMethod(requireActivity()));
|
holder.progress.show();
|
||||||
holder.description.setSpannableFactory(NoCopySpannableFactory.getInstance());
|
renderGithubMarkdown(holder.description, release.getDescription(), holder.progress);
|
||||||
markwon.setMarkdown(holder.description, release.getDescription());
|
|
||||||
holder.description.setMovementMethod(null);
|
|
||||||
holder.openInBrowser.setOnClickListener(v -> NavUtil.startURL(requireActivity(), release.getUrl()));
|
holder.openInBrowser.setOnClickListener(v -> NavUtil.startURL(requireActivity(), release.getUrl()));
|
||||||
List<ReleaseAsset> assets = release.getReleaseAssets();
|
List<ReleaseAsset> assets = release.getReleaseAssets();
|
||||||
if (assets != null && !assets.isEmpty()) {
|
if (assets != null && !assets.isEmpty()) {
|
||||||
|
|
@ -323,14 +372,6 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
} else {
|
} else {
|
||||||
holder.viewAssets.setVisibility(View.GONE);
|
holder.viewAssets.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
holder.itemView.setOnClickListener(v -> {
|
|
||||||
ClickableSpan span = holder.description.getCurrentSpan();
|
|
||||||
holder.description.clearCurrentSpan();
|
|
||||||
|
|
||||||
if (span instanceof CustomTabsURLSpan) {
|
|
||||||
span.onClick(v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -346,7 +387,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder {
|
class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
TextView title;
|
TextView title;
|
||||||
LinkifyTextView description;
|
WebView description;
|
||||||
MaterialButton openInBrowser;
|
MaterialButton openInBrowser;
|
||||||
MaterialButton viewAssets;
|
MaterialButton viewAssets;
|
||||||
CircularProgressIndicator progress;
|
CircularProgressIndicator progress;
|
||||||
|
|
@ -363,6 +404,7 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
description = binding.description;
|
description = binding.description;
|
||||||
openInBrowser = binding.openInBrowser;
|
openInBrowser = binding.openInBrowser;
|
||||||
viewAssets = binding.viewAssets;
|
viewAssets = binding.viewAssets;
|
||||||
|
progress = binding.progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,10 +433,11 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
public void onBindViewHolder(@NonNull PagerAdapter.ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull PagerAdapter.ViewHolder holder, int position) {
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 0:
|
case 0:
|
||||||
holder.textView.setTransformationMethod(new LinkTransformationMethod(requireActivity()));
|
|
||||||
holder.scrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top));
|
holder.scrollView.getBorderViewDelegate().setBorderVisibilityChangedListener((top, oldTop, bottom, oldBottom) -> binding.appBar.setRaised(!top));
|
||||||
holder.scrollView.setTag(position);
|
holder.scrollView.setTag(position);
|
||||||
markwon.setMarkdown(holder.textView, module.getReadme());
|
holder.progress.show();
|
||||||
|
if (module != null)
|
||||||
|
renderGithubMarkdown(holder.webView, module.getReadme(), holder.progress);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
|
|
@ -426,9 +469,10 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewHolder extends RecyclerView.ViewHolder {
|
class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
TextView textView;
|
WebView webView;
|
||||||
BorderNestedScrollView scrollView;
|
BorderNestedScrollView scrollView;
|
||||||
BorderRecyclerView recyclerView;
|
BorderRecyclerView recyclerView;
|
||||||
|
CircularProgressIndicator progress;
|
||||||
|
|
||||||
public ViewHolder(@NonNull View itemView) {
|
public ViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
|
|
@ -438,8 +482,9 @@ public class RepoItemFragment extends BaseFragment implements RepoLoader.Listene
|
||||||
class ReadmeViewHolder extends PagerAdapter.ViewHolder {
|
class ReadmeViewHolder extends PagerAdapter.ViewHolder {
|
||||||
public ReadmeViewHolder(ItemRepoReadmeBinding binding) {
|
public ReadmeViewHolder(ItemRepoReadmeBinding binding) {
|
||||||
super(binding.getRoot());
|
super(binding.getRoot());
|
||||||
textView = binding.readme;
|
webView = binding.readme;
|
||||||
scrollView = binding.scrollView;
|
scrollView = binding.scrollView;
|
||||||
|
progress = binding.progress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,16 @@
|
||||||
android:paddingTop="104dp"
|
android:paddingTop="104dp"
|
||||||
app:fitsSystemWindowsInsets="top|bottom">
|
app:fitsSystemWindowsInsets="top|bottom">
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:showAnimationBehavior="outward"
|
||||||
|
app:hideAnimationBehavior="inward" />
|
||||||
|
|
||||||
<rikka.widget.borderview.BorderNestedScrollView
|
<rikka.widget.borderview.BorderNestedScrollView
|
||||||
android:id="@+id/scrollView"
|
android:id="@+id/scrollView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -35,10 +45,11 @@
|
||||||
app:borderTopDrawable="@null"
|
app:borderTopDrawable="@null"
|
||||||
app:borderBottomVisibility="never">
|
app:borderBottomVisibility="never">
|
||||||
|
|
||||||
<TextView
|
<WebView
|
||||||
android:id="@+id/readme"
|
android:id="@+id/readme"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content"
|
||||||
|
android:scrollbars="none" />
|
||||||
</rikka.widget.borderview.BorderNestedScrollView>
|
</rikka.widget.borderview.BorderNestedScrollView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
|
||||||
|
|
@ -33,11 +33,21 @@
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:clipChildren="false">
|
android:clipChildren="false">
|
||||||
|
|
||||||
|
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||||
|
android:id="@+id/progress"
|
||||||
|
android:layout_width="36dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:showAnimationBehavior="outward"
|
||||||
|
app:hideAnimationBehavior="inward" />
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
android:id="@+id/item_root"
|
android:id="@+id/item_root"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
tools:ignore="RtlSymmetry">
|
tools:ignore="RtlSymmetry">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|
@ -52,7 +62,7 @@
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
tools:text="@tools:sample/lorem" />
|
tools:text="@tools:sample/lorem" />
|
||||||
|
|
||||||
<org.lsposed.manager.ui.widget.LinkifyTextView
|
<WebView
|
||||||
android:id="@+id/description"
|
android:id="@+id/description"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
@ -62,6 +72,7 @@
|
||||||
app:layout_constraintHorizontal_bias="1.0"
|
app:layout_constraintHorizontal_bias="1.0"
|
||||||
app:layout_constraintStart_toStartOf="@+id/title"
|
app:layout_constraintStart_toStartOf="@+id/title"
|
||||||
app:layout_constraintTop_toBottomOf="@id/title"
|
app:layout_constraintTop_toBottomOf="@id/title"
|
||||||
|
android:scrollbars="none"
|
||||||
tools:text="@tools:sample/lorem" />
|
tools:text="@tools:sample/lorem" />
|
||||||
|
|
||||||
<com.google.android.material.button.MaterialButton
|
<com.google.android.material.button.MaterialButton
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue