Установить текстовый вид эллипсисом и добавить в конец больше

Я пытаюсь установить эллипсис текстового вида. используя следующий код. Я хочу добавить "просмотреть больше" в конце усеченной строки после трех точек. Если это было бы возможно при том же текстовом представлении, что было бы замечательно, или "просмотреть больше" в отдельном текстовом представлении также будет работать. Максимальное количество строк - 4. Я попытался установить ширину первого текстового вида, но оставил пустое пространство в конце первых 3 строк. См. Изображение ниже.

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:id="@+id/tvReviewDescription"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:maxLines="4"
        android:text="I tend to shy away from restaurant chains, but wherever I go, PF Chang&apos;s has solidly good food and, like Starbucks, they&apos;re reliable. We were staying in Boston for a week and after a long day and blah blah blah blah... "
        android:textColor="@color/black"
        android:textSize="13dp" 
        android:maxLength="280"
        android:ellipsize="end"/>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/tvReviewDescription"
        android:layout_alignParentRight="true"
        android:text="@string/label_view_more"
        android:textColor="@color/yellow" />
</RelativeLayout>

enter image description here

Ответ 1

Найти мой ответ

   public static void makeTextViewResizable(final TextView tv, final int maxLine, final String expandText, final boolean viewMore) {

    if (tv.getTag() == null) {
        tv.setTag(tv.getText());
    }
    ViewTreeObserver vto = tv.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {

            ViewTreeObserver obs = tv.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
            if (maxLine == 0) {
                int lineEndIndex = tv.getLayout().getLineEnd(0);
                String text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
                tv.setText(text);
                tv.setMovementMethod(LinkMovementMethod.getInstance());
                tv.setText(
                        addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, maxLine, expandText,
                                viewMore), TextView.BufferType.SPANNABLE);
            } else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
                int lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
                String text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + expandText;
                tv.setText(text);
                tv.setMovementMethod(LinkMovementMethod.getInstance());
                tv.setText(
                        addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, maxLine, expandText,
                                viewMore), TextView.BufferType.SPANNABLE);
            } else {
                int lineEndIndex = tv.getLayout().getLineEnd(tv.getLayout().getLineCount() - 1);
                String text = tv.getText().subSequence(0, lineEndIndex) + " " + expandText;
                tv.setText(text);
                tv.setMovementMethod(LinkMovementMethod.getInstance());
                tv.setText(
                        addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, lineEndIndex, expandText,
                                viewMore), TextView.BufferType.SPANNABLE);
            }
        }
    });

}

private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
                                                                        final int maxLine, final String spanableText, final boolean viewMore) {
    String str = strSpanned.toString();
    SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);

    if (str.contains(spanableText)) {


        ssb.setSpan(new MySpannable(false){
            @Override
            public void onClick(View widget) {
                if (viewMore) {
                    tv.setLayoutParams(tv.getLayoutParams());
                    tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                    tv.invalidate();
                    makeTextViewResizable(tv, -1, "See Less", false);
                } else {
                    tv.setLayoutParams(tv.getLayoutParams());
                    tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                    tv.invalidate();
                    makeTextViewResizable(tv, 3, ".. See More", true);
                }
            }
        }, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);

    }
    return ssb;

}

Другой класс: -

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) {


 }
}

Последний шаг для его вызова:

DetailTv.setText(discription);
makeTextViewResizable(DetailTv, 3, "See More", true);

Ответ 2

Это может быть достигнуто во время выполнения, все, что вам нужно сделать, это проверить длину строки и добавить подстрочный вид More в конце строки, подобной этой.

В качестве примера я использовал длину "20", вы можете изменить в соответствии с вашим требованием.

final TextView result = (TextView) findViewById(R.id.textview);

String text = "I tend to shy away from restaurant chains, but wherever I go, PF Chang&apos;s has solidly good food and, like Starbucks, they&apos;re reliable. We were staying in Boston for a week and after a long day and blah blah blah blah...";

if (text.length()>20) {
    text=text.substring(0,20)+"...";
    result.setText(Html.fromHtml(text+"<font color='red'> <u>View More</u></font>"));       

}

Ответ 3

Проще, чем принятый ответ:

public static final int MAX_LINES = 3;

String myReallyLongText = "Bacon ipsum dolor amet porchetta venison ham fatback alcatra tri-tip, turducken strip steak sausage rump burgdoggen pork loin. Spare ribs filet mignon salami, strip steak ball tip shank frankfurter corned beef venison. Pig pork belly pork chop andouille. Porchetta pork belly ground round, filet mignon bresaola chuck swine shoulder leberkas jerky boudin. Landjaeger pork chop corned beef, tri-tip brisket rump pastrami flank."

textView.setText(myReallyLongText);
textView.post(new Runnable() {
                @Override
                public void run() {
                    // Past the maximum number of lines we want to display.
                    if (textView.getLineCount() > MAX_LINES) {
                        int lastCharShown = textView.getLayout().getLineVisibleEnd(MAX_LINES - 1);

                        textView.setMaxLines(MAX_LINES);

                        String moreString = context.getString(R.string.more);
                        String suffix = TWO_SPACES + moreString;

                        // 3 is a "magic number" but it just basically the length of the ellipsis we're going to insert
                        String actionDisplayText = myReallyLongText.substring(0, lastCharShown - suffix.length() - 3) + "..." + suffix;

                        SpannableString truncatedSpannableString = new SpannableString(actionDisplayText);
                        int startIndex = actionDisplayText.indexOf(moreString);
                        truncatedSpannableString.setSpan(new ForegroundColorSpan(context.getColor(android.R.color.blue)), startIndex, startIndex + moreString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                        textView.setText(truncatedSpannableString);
                    }
                }
            });

Ответ 4

Это будет иметь эффект эллипса.

set Boolean isCheck = true;

поместите это в xml:

<TextView
        android:id="@+id/txt_id"
        android:maxLines="2"
        android:ellipsize="end"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

и код:

txt_id= (TextView)findViewById(R.id.txt_id);
txt_id.setText("data");
txt_id.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
                   if (isCheck) {
                      txt_id.setMaxLines(10);
                      isCheck = false;
                   } else {
                      txt_id.setMaxLines(2);
                      isCheck = true;
           }
       }
  }

Ответ 5

Проверьте мою библиотеку: https://github.com/AhmMhd/SeeMoreTextView-Android

<com.abdulhakeem.seemoretextview.SeeMoreTextView
    android:id="@+id/textview
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
/>

использование:

TextView seemoreTv = (TextView) findViewById(R.id.textview)

seemoreTv.setContent("some really long text here.")

это также прекрасно работает на переработчике.

Ответ 6

Спасибо Jitender answer.Improving на нем Я выполнил нижеследующую реализацию, основанную на длине текста. Это может быть не идеальным решением, если вы хотите, чтобы опция "Подробнее" была указана только после указанного количества строк, но при условии, что в ней около 50 символов однострочное решение будет хорошо работать, если вы будете настроены с количеством строк. Решение для установки будет добавлять параметр "Подробнее", если длина текста больше 150 и будет эллипсоизировать текст до 150 символов. При нажатии на "Просмотр больше" будет отображаться полный текст с Показывать меньше, и при повторном нажатии на кнопку "Показать меньше" он будет эллипсоизировать текст до 150 символов. Не требуется отдельное представление. Также он отлично работает с текстовым просмотром элементов recyclerview.

if(inputText.length()>150)
        {
            String text=inputText.substring(0,150)+"...";
            final String fulltext=inputText;

            final SpannableString ss = new SpannableString(text+"View More");

            ClickableSpan span1 = new ClickableSpan() {
                @Override
                public void onClick(View textView) {
                    // do some thing
                    SpannableString ss1 = new SpannableString(fulltext+"Show Less");
                    ClickableSpan span2 = new ClickableSpan() {
                        @Override
                        public void onClick(View textView) {
                            // do some thing
                            textView.setText(ss);
                            textView.setMovementMethod(LinkMovementMethod.getInstance());

                        }
                    };
                    ss1.setSpan(span2, fulltext.length(), ss1.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
                    ss1.setSpan(new ForegroundColorSpan(Color.BLUE), fulltext.length(), ss1.length(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);


                    textView.setText(ss1);
                    textView.setMovementMethod(LinkMovementMethod.getInstance());
                }
            };
            ss.setSpan(span1, 153, 162, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            ss.setSpan(new ForegroundColorSpan(Color.BLUE), 153,162,
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            textView.setText(ss);
            textView.setMovementMethod(LinkMovementMethod.getInstance());
        }
else
        {
            textView.setText(inputText);
        }

Ответ 7

Это решение немного проще реализовать в коде. Он не поддерживает изменения "на лету", но может быть легко изменен для этого.

public class ExpandableTextView extends TextView {

    private final String readMoreText = "...read more";
    private final int readMoreColor = Color.parseColor("#4A0281");

    private int _maxLines = 4;
    private CharSequence originalText;

    public ExpandableTextView(Context context) {
        super(context);
        init(context);
    }

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

    public ExpandableTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {

        ViewTreeObserver vto = getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

            @SuppressWarnings("deprecation")
            @Override
            public void onGlobalLayout() {

                ViewTreeObserver obs = getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);

                truncateText();
            }
        });
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, type);

        if (originalText == null) {
            originalText = text;
        }
    }

    @Override
    public int getMaxLines() {
        return _maxLines;
    }

    @Override
    public void setMaxLines(int maxLines) {
        _maxLines = maxLines;
    }

    public void truncateText() {

        int maxLines = _maxLines;
        String text = getText().toString();

        if (getLineCount() >= maxLines) {

            int lineEndIndex = getLayout().getLineEnd(maxLines - 1);

            String truncatedText = getText().subSequence(0, lineEndIndex - readMoreText.length() + 1) + readMoreText;

            Spannable spannable = new SpannableString(truncatedText);
            spannable.setSpan(new ForegroundColorSpan(readMoreColor), truncatedText.length() - readMoreText.length(), truncatedText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            setText(spannable, TextView.BufferType.SPANNABLE);

            super.setMaxLines(_maxLines);
        }
    }

    public void expandText() {
        setText(originalText);
        super.setMaxLines(1000);
    }

    public void reset() {
        originalText = null;
    }
}

Ответ 8

Вы можете использовать код ниже для этого;

 holder.tvMoreInfo.setText(horizontalList.get(position));

        holder.tvMoreInfo.post(new Runnable() {
            @Override
            public void run() {
                int lineCount = holder.tvMoreInfo.getLineCount();
                if (lineCount<3)
                {

                }else
                {
                    makeTextViewResizable(holder.tvMoreInfo, 3, "...More", true);
                }
            }
        });



 public static void makeTextViewResizable(final TextView tv, final int maxLine, final String expandText, final boolean viewMore) {

    if (tv.getTag() == null) {
        tv.setTag(tv.getText());
    }
    ViewTreeObserver vto = tv.getViewTreeObserver();
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        @SuppressWarnings("deprecation")
        @Override
        public void onGlobalLayout() {
            String text;
            int lineEndIndex;
            ViewTreeObserver obs = tv.getViewTreeObserver();
            obs.removeGlobalOnLayoutListener(this);
            if (maxLine == 0) {
                lineEndIndex = tv.getLayout().getLineEnd(0);
                text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
            } else if (maxLine > 0 && tv.getLineCount() >= maxLine) {
                lineEndIndex = tv.getLayout().getLineEnd(maxLine - 1);
                text = tv.getText().subSequence(0, lineEndIndex - expandText.length() + 1) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
            } else {
                lineEndIndex = tv.getLayout().getLineEnd(tv.getLayout().getLineCount() - 1);
                text = tv.getText().subSequence(0, lineEndIndex) + " " + "<font color=\"#F15d36\">" + expandText + "</font>";
            }
            tv.setText(Html.fromHtml(text));
            tv.setMovementMethod(LinkMovementMethod.getInstance());

            tv.setText(
                    addClickablePartTextViewResizable(Html.fromHtml(tv.getText().toString()), tv, lineEndIndex, expandText,
                            viewMore), TextView.BufferType.SPANNABLE);
        }
    });
}

private static SpannableStringBuilder addClickablePartTextViewResizable(final Spanned strSpanned, final TextView tv,
                                                                        final int maxLine, final String spanableText, final boolean viewMore) {
    String str = strSpanned.toString();
    SpannableStringBuilder ssb = new SpannableStringBuilder(strSpanned);

    if (str.contains(spanableText)) {
        ssb.setSpan(new MySpannable(false) {

            @Override
            public void onClick(View widget) {
                tv.setLayoutParams(tv.getLayoutParams());
                tv.setText(tv.getTag().toString(), TextView.BufferType.SPANNABLE);
                tv.invalidate();
                if (viewMore) {
                    makeTextViewResizable(tv, -1, "...Less", false);
                } else {
                    makeTextViewResizable(tv, 3, "...More", true);
                }

            }
        }, str.indexOf(spanableText), str.indexOf(spanableText) + spanableText.length(), 0);

    }
    return ssb;

}

Ответ 9

это прекрасно работает с textview, listview, recyclerview и любым другим видом проверенных представлений. а также прост в реализации. сделано в XML нет внутреннего кода. Ссылка здесь просто прокрутите вниз и нажмите на ссылку получить внизу

Ответ 10

Вместо использования android: layout_alignParentLeft = "true" в первом использовании текстового поля андроид: layout_toLeftOf = "@+ идентификатор /textView 1"

Это должно заботиться о перекрывающемся тексте