[app] Add Expandable TextView (#1279)

* [app] Add Expandable TextView
This commit is contained in:
Howard Wu 2021-10-15 23:58:54 +08:00 committed by GitHub
parent 233569b40e
commit b30614abe4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 137 additions and 3 deletions

View File

@ -488,7 +488,8 @@ public class ModulesFragment extends BaseFragment implements ModuleUtil.ModuleLi
sb.setSpan(foregroundColorSpan, sb.length() - recommended.length(), sb.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
}
}
holder.hint.setText(sb);
if (sb.length() == 0) holder.hint.setVisibility(View.GONE);
else holder.hint.setText(sb);
if (!isPick) {
holder.root.setAlpha(moduleUtil.isModuleEnabled(item.packageName) ? 1.0f : .5f);

View File

@ -0,0 +1,129 @@
/*
* <!--This file is part of LSPosed.
*
* LSPosed is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* LSPosed is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LSPosed. If not, see <https://www.gnu.org/licenses/>.
*
* Copyright (C) 2021 LSPosed Contributors-->
*/
package org.lsposed.manager.ui.widget;
import android.annotation.SuppressLint;
import android.content.Context;
import android.text.Layout;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.transition.TransitionManager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.lsposed.manager.R;
public class ExpandableTextView extends TextView {
private CharSequence text = null;
private int nextLines = 0;
private final int maxLines;
private final SpannableString collapse;
private final SpannableString expand;
private final SpannableStringBuilder sb = new SpannableStringBuilder();
public ExpandableTextView(Context context) {
this(context, null);
}
public ExpandableTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
maxLines = getMaxLines();
collapse = new SpannableString(context.getString(R.string.collapse));
ClickableSpan span = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
TransitionManager.beginDelayedTransition((ViewGroup) getParent());
setMaxLines(nextLines);
ExpandableTextView.super.setText(text);
}
};
collapse.setSpan(span, 0, collapse.length(), 0);
expand = new SpannableString(context.getString(R.string.expand));
expand.setSpan(span, 0, expand.length(), 0);
setMovementMethod(LinkMovementMethod.getInstance());
}
@Override
public void setText(CharSequence text, BufferType type) {
this.text = text;
super.setText(text, type);
}
@Override
public boolean onPreDraw() {
var lineCount = getLayout().getLineCount();
if (lineCount > maxLines) {
SpannableString s;
int end;
if (maxLines == getMaxLines()) {
nextLines = lineCount + 1;
end = getLayout().getLineStart(getMaxLines() - 1);
s = expand;
} else {
nextLines = maxLines;
end = text.length();
s = collapse;
}
sb.clearSpans();
sb.clear();
sb.append(text, 0, end - 1);
sb.append("\n");
sb.append(s);
super.setText(sb, BufferType.NORMAL);
}
return super.onPreDraw();
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
Layout layout = this.getLayout();
if (layout != null) {
int line = layout.getLineForVertical((int) event.getY());
int offset = layout.getOffsetForHorizontal(line, event.getX());
if (getText() instanceof Spanned) {
Spanned spanned = (Spanned) getText();
ClickableSpan[] links = spanned.getSpans(offset, offset, ClickableSpan.class);
if (links.length == 0) {
super.onTouchEvent(event);
return false;
}
}
}
return super.onTouchEvent(event);
}
}

View File

@ -35,6 +35,7 @@
android:id="@+id/item_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
tools:ignore="RtlSymmetry">
<ImageView
@ -61,11 +62,12 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/first_names" />
<TextView
<org.lsposed.manager.ui.widget.ExpandableTextView
android:id="@+id/description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxLines="5"
android:textAppearance="?android:attr/textAppearanceListItemSecondary"
android:textColor="?android:attr/textColorSecondary"
app:layout_constraintBottom_toBottomOf="@id/hint"
@ -114,8 +116,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:focusable="false"
android:clickable="false"
android:focusable="false"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -221,4 +221,6 @@
<string name="color_brown">Brown</string>
<string name="color_grey">Grey</string>
<string name="color_blue_grey">Blue grey</string>
<string name="expand">expand</string>
<string name="collapse">collapse</string>
</resources>