我已TextView
申请了maxLines:5
并ellipsize:end
,我也在setMovementMethod(LinkMovementMethod.getInstance())
上使用TextView
来点击链接(HTML含量)。
上述所有内容的组合会禁用正在截断的文字以及' ...'后缀将被追加。
知道出了什么问题以及如何解决它?
如果不设置移动方法,一切都会按预期工作。
关于赏金的更新: 寻找除手动设置省略号之外的解决方案
答案 0 :(得分:3)
对不起,我迟到了。
在这方面几乎没有解决办法
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;
}
}
输出
以下是说明:
我已经调试了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,但是对于没有MovementMethod的元素,mLayout.getLineCount()
将是maxLines,对于MovingmotionMethod的元素,它将是原始字符串的行数
答案 1 :(得分:1)
试试这段代码。
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textStyle="bold"
android:textSize="20dp"
android:id="@+id/txtTitle"
android:text="" />
String message="<font color='gray'>"+"YOUR CONTENT"+ "<br>" +"<font color='cyan'>"+"<font size='5'>"+" "+"</font>";
txtTitle.setBackgroundColor(Color.TRANSPARENT);
txtTitle.setText(message);
答案 2 :(得分:1)
尝试此代码。
XML
<TextView
android:id="@+id/tvcondition1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/white"
android:textStyle="bold"
android:ellipsize="end"
android:maxLines="5"
android:textSize="15sp" />
Java文件代码
String strTeamsCondition = "<b><u> Terms & Condition </u></b>";
String conditionlimit = "Terms & Condition";
String strConditionFirstLine = getString(R.string.condition_1);
String condition_1_1 = getString(R.string.condition_1_1);
String htmlAsString2 = strConditionFirstLine + strTeamsCondition + condition_1_1;
Spanned htmlAsSpannedCondition = Html.fromHtml(htmlAsString2);
tvcondition1.setText(htmlAsSpannedCondition);
Spannable spanText = new SpannableString(htmlAsSpannedCondition);
spanText.setSpan(new MyClickableSpan(htmlAsSpannedCondition), strConditionFirstLine.length(), strConditionFirstLine.length() + conditionlimit.length() + 1, 0);
tvcondition1.setText(spanText);
tvcondition1.setMovementMethod(LinkMovementMethod.getInstance());
触摸选中的文本
class MyClickableSpan extends ClickableSpan {
public MyClickableSpan(Spanned string) {
super();
}
public void onClick(View tv) {
Toast.makeText(getApplicationContext(), "Thanks for the click!",
Toast.LENGTH_SHORT).show();
}
public void updateDrawState(TextPaint ds) {
ds.setColor(getResources().getColor(R.color.black));
ds.setUnderlineText(true); // set to false to remove underline
}
}
答案 3 :(得分:0)
<TextView
android:id="@+id/html"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="5"
android:ellipsize="end"/>
//inside your activity
public class A extends AppCompatActivity{
TextView html = (TextView) view.findViewById(R.id.html);
html.setText(Html.fromHtml("this is an example <a href=\"www.google.com\">google</a> link to google"));
html.setMovementMethod(LinkMovementMethod.getInstance());
.
.
.
}
答案 4 :(得分:0)
试试这个。
方式1 。使用setMovementMethod
和Html.fromHtml
我没有设置maxLines
和ellipsize
。它工作正常。
在您的XML代码中
<TextView
android:id="@+id/tv_html"
android:ellipsize="end"
android:maxLines="5"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
然后在您的java代码中
TextView tv_html = (TextView) findViewById(R.id.tv_html);
tv_html.setText(Html.fromHtml("google:" + "<a href='https://www.google.com.hk'>link to it</a> "));
tv_html.setMovementMethod(LinkMovementMethod.getInstance());// make it active
方式2 。在XML代码中使用android:autoLink="all"
<TextView
android:id="@+id/tv_html"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"/>
然后在你的java代码中。
TextView tv_html = (TextView) findViewById(R.id.tv_html);
tv_html.setText("google: https://www.google.com.hk"));
方式3 。在代码中使用SpannableString
。
TextView tv_html = (TextView) findViewById(R.id.tv_html);
SpannableString ss = new SpannableString("google: link to google");
ss.setSpan(new URLSpan("https://www.google.com.hk"), 8, 22, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
tv_html.setText(ss);
tv_html .setMovementMethod(LinkMovementMethod.getInstance());
修改强>
它可以滚动但不显示...
。
您可以添加
android:scrollbars="vertical"
答案 5 :(得分:0)
可能的解决方法是。
import android.graphics.Color;
import android.text.TextPaint;
import android.text.style.ClickableSpan;
import android.view.View;
public class MySpannable extends ClickableSpan {
private boolean isUnderline = true;
/**
* Constructor
*/
public MySpannable(boolean isUnderline) {
this.isUnderline = isUnderline;
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(isUnderline);
ds.setColor(Color.parseColor("#1b76d3"));
}
@Override
public void onClick(View widget) {
}
}
可扩展类:
myTextView.setText(discription);
makeTextViewResizable(myTextView, 3, "See More", true);
以这种方式调用:
b
答案 6 :(得分:0)
如果我使用TextView和android:autoLink =“ email | web”,这就是我所拥有的
<TextView
android:id="@+id/text_link"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="end"
android:autoLink="email|web"
android:maxLines="1"
android:text="https://stackoverflow.com/questions/46056046/textview-maxlines-movement-method-and-ellipsize"
android:textColorLink="?attr/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_link_attribute"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
如果我们使用自定义TextView(inspired by):
class NoScrollTextView : androidx.appcompat.widget.AppCompatTextView {
constructor(context: Context?) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr
)
override fun scrollTo(x: Int, y: Int) {
super.scrollTo(x, 0)
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
super.onLayout(changed, left, top, right, bottom)
post { moveCursorToVisibleOffset() }
}
}
和
<com.YOU_PACKAGE_NAME_HERE.NoScrollTextView
android:id="@+id/text_link"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="end"
android:autoLink="email|web"
android:singleLine="true"
android:text="https://stackoverflow.com/questions/46056046/textview-maxlines-movement-method-and-ellipsize"
android:textColorLink="?attr/colorAccent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_link_attribute"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
关键特征(它们是必要和充分的):