gpt4 book ai didi

android - TextView maxLines、移动方法和椭圆大小

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:37:57 34 4
gpt4 key购买 nike

我有一个 TextView 应用了 maxLines:5ellipsize:end,我也在使用 setMovementMethod(LinkMovementMethod. TextView 上的 getInstance()) 使链接可点击(HTML 内容)。

以上所有的组合禁用被截断的文本和附加的“...”后缀。

知道出了什么问题以及如何解决吗?

没有设置移动方法,一切都按预期进行。

关于赏金的更新:寻找手动设置省略号以外的解决方案

最佳答案

抱歉,我迟到了。

解决这个问题的方法很少

MainActivity

public class MainActivity extends AppCompatActivity {


TextView htmlTextView;

CustomEllipsizeTextView customEllipsizeTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);


htmlTextView = findViewById(R.id.htmlTextView1);

customEllipsizeTextView = findViewById(R.id.customEllipsizeTextView);

String value = "Hello this is a dummy textview";

String myText = "You can visit my Profile in <a href=\"https://stackoverflow.com/users/7666442/nilesh-rathod?tab=profile\">stackoverflow</a> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis bibendum mattis risus eget pulvinar. Praesenttingd" +
" commodo erat enim, id564654 congue sem tristique vitae. Proin vitae accumsan justo, ut imperdiet Mauris neque nibh, hendrerit id tortor vel, congue sagittis odio. Morbi elementum lobortis maximus. Etiam sit amet porttitor massa. Fusce sed magna quis arcu tincidunt finibus vitae id erat. " +
"commodo erat enim, id54654 congue sem tristique vitae. Proin vitae accumsan commodo erat enim, id congue sem tristique vitae. Proin vitae accumsan Pellentesque massa mi, imperdiet eget accums ";


SpannableString spanText2 = new SpannableString(myText);
htmlTextView.setText(value);

if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
customEllipsizeTextView.setText(Html.fromHtml(spanText2.toString(), Html.FROM_HTML_MODE_LEGACY));
} else {
customEllipsizeTextView.setText(Html.fromHtml(spanText2.toString()));
}

htmlTextView.setMovementMethod(LinkMovementMethod.getInstance());
customEllipsizeTextView.setMovementMethod(LinkMovementMethod.getInstance());
customEllipsizeTextView.setOnTouchListener(new TouchTextView(spanText2));

}

}

layout.activity_main

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".FirstFragment">



<TextView
android:id="@+id/htmlTextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:text="@string/link_text" />

<neel.com.demo.CustomEllipsizeTextView
android:id="@+id/customEllipsizeTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:linksClickable="true"
android:maxLines="5"
android:padding="5dp"
android:visibility="visible" />


</LinearLayout>

CustomEllipsizeTextView

public class CustomEllipsizeTextView extends android.support.v7.widget.AppCompatTextView {
public CustomEllipsizeTextView(Context context) {
super(context);
}

public CustomEllipsizeTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public CustomEllipsizeTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}


@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
StaticLayout layout = null;
Field field = null;
try {
Field staticField = DynamicLayout.class.getDeclaredField("sStaticLayout");
staticField.setAccessible(true);
layout = (StaticLayout) staticField.get(DynamicLayout.class);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}

if (layout != null) {
try {
field = StaticLayout.class.getDeclaredField("mMaximumVisibleLineCount");
field.setAccessible(true);
field.setInt(layout, getMaxLines());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (layout != null && field != null) {
try {
field.setInt(layout, Integer.MAX_VALUE);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}

TouchTextView

public class TouchTextView implements View.OnTouchListener {
Spannable spannable;

public TouchTextView (Spannable spannable){
this.spannable = spannable;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
if(!(v instanceof TextView)){
return false;
}
TextView textView = (TextView) v;
if (action == MotionEvent.ACTION_UP ||
action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();

x -= textView.getTotalPaddingLeft();
y -= textView.getTotalPaddingTop();

x += textView.getScrollX();
y += textView.getScrollY();

Layout layout = textView.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);

ClickableSpan[] link = spannable.getSpans(off, off, ClickableSpan.class);

if (link.length != 0) {
if (action == MotionEvent.ACTION_UP) {
link[0].onClick(textView);
} else if (action == MotionEvent.ACTION_DOWN) {
Selection.setSelection(spannable,
spannable.getSpanStart(link[0]),
spannable.getSpanEnd(link[0]));
}

return true;
} else {
Selection.removeSelection(spannable);
}
}

return false;
}
}

输出

enter image description here

这里是解释:

我已经调试了 TextView 并发现了以下内容:

因此,当您使用 LinkMovementMethod() 时,实际上文本充当 Spannable。在其他情况下它是字符串。

在TextView中有如下一种情况

if (mText instanceof Spannable) {
//executes incase of LinkMovementMethod
result = new DynamicLayout(mText, mTransformed, mTextPaint, wantWidth,
alignment, mTextDir, mSpacingMult, mSpacingAdd, mIncludePad,
mBreakStrategy, mHyphenationFrequency, mJustificationMode,
getKeyListener() == null ? effectiveEllipsize : null, ellipsisWidth);
} else {
//executes without any movementmethod
..create StaticLayout
}

所以 DynamicLayout 在内部调用 StaticLayout 来呈现文本,但是当来自 DynamicLayout 时,它不会在 StaticLayout 中设置 mMaximumVisibleLineCount,所以它是默认的 Integer.MAX_VALUE。但是当从 String 创建 StaticLayout 时,它实际上是将 mMaximumVisibleLineCount 设置为 maxLines。此 mMaximumVisibleLineCount 用于显示椭圆大小。这就是不显示“...”的原因。

为了显示行数,下面的代码有效

if (mMaxMode == LINES && mLayout.getLineCount() > mMaximum) {
unpaddedHeight = Math.min(unpaddedHeight, mLayout.getLineTop(mMaximum));
}

mMaximum 在这两种情况下都将设置为 maxLines,但是 mLayout.getLineCount() 将在没有 MovementMethod 的情况下设置为 maxLines,而在有 MovementMethod 的情况下它将设置为行数原始字符串

关于android - TextView maxLines、移动方法和椭圆大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056046/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com