Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image span appearing even after Ellipsize in Android textView

Tags:

android

I have a Text View which has image span content. I have given ellipsize = "end" for Text View . After ellipsize, the image span appears after it.

like image 914
Nabajyoti Avatar asked Oct 26 '12 08:10

Nabajyoti


1 Answers

Use the EllipsizedTextView class from iosched. To set the text in the view use method

setText(CharSequence text, BufferType type) 

for Spannable you can use

textView.setText(text, TextView.BufferType.SPANNABLE);

also in your xml file you will need to define android:ellipsize and android:maxLines or you can set them programmatically as well.

Putting code here to try it out. Code is modified, taken from this question

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MainActivity extends AppCompatActivity {

    private EditText editText;
    private Button button;
    private EllipsizedTextView textView;

    private static final String PATTERN = "\\[\\w+?\\]";
    private Pattern pattern;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        editText = (EditText) findViewById(R.id.edittext);
        button = (Button) findViewById(R.id.btn);
        textView = (EllipsizedTextView) findViewById(R.id.text);
        //programmatic way of setting max lines and ellipsize
        textView.setMaxLines(2);
        textView.setEllipsize(TextUtils.TruncateAt.END);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                insertImageSpan();
            }
        });

        pattern = Pattern.compile(PATTERN);



        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                textView.setText(s, TextView.BufferType.SPANNABLE);
            }
        });
    }

    private void insertImageSpan(){
        insertTextInCurrentPosition(editText,"[face]");
        int select = editText.getSelectionStart();
        editText.setText(spanText(editText.getText()));
        editText.setSelection(select);
    }

    public CharSequence spanText(CharSequence text) {
        SpannableStringBuilder t = null;
        if(text instanceof SpannableStringBuilder){
            t = (SpannableStringBuilder) text;
        }else{
            t = new SpannableStringBuilder(text);
        }
        Matcher m = pattern.matcher(text);
        while (m.find()) {
            String mResult = m.group();
            String key = mResult.substring(1, mResult.length() - 1);

            ImageSpan[] spans = t.getSpans(m.start(),m.end(),ImageSpan.class);
            if(spans== null || spans.length==0 ){
                try{
                    ImageSpan span = new ImageSpan(this , R.drawable.ic_launcher);
                    t.setSpan(span , m.start() , m.end() , Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }catch (Exception e){
                    continue;
                }
            }

        }
        return t;
    }

    public static void insertTextInCurrentPosition(EditText tv, CharSequence str) {
        if (tv == null || TextUtils.isEmpty(str)) return;
        tv.getText().replace(tv.getSelectionStart() , tv.getSelectionEnd() , str , 0 , str.length());
    }
}

and EllipsizedTextView

import android.content.Context;
import android.content.res.TypedArray;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * A simple {@link TextView} subclass that uses {@link TextUtils#ellipsize(CharSequence,
 * android.text.TextPaint, float, android.text.TextUtils.TruncateAt, boolean,
 * android.text.TextUtils.EllipsizeCallback)} to truncate the displayed text. Th
 */
public class EllipsizedTextView extends TextView {
    private static final int MAX_ELLIPSIZE_LINES = 100;

    private int mMaxLines;

    public EllipsizedTextView(Context context) {
        this(context, null, 0);
    }

    public EllipsizedTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public EllipsizedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        // Attribute initialization
        final TypedArray a = context.obtainStyledAttributes(attrs, new int[]{
                android.R.attr.maxLines
        }, defStyle, 0);

        mMaxLines = a.getInteger(0, 1);
        a.recycle();
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        CharSequence newText = getWidth() == 0 || mMaxLines > MAX_ELLIPSIZE_LINES ? text :
                TextUtils.ellipsize(text, getPaint(), getWidth() * mMaxLines,
                        TextUtils.TruncateAt.END, false, null);
        super.setText(newText, type);
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
        super.onSizeChanged(width, height, oldWidth, oldHeight);
        if (width > 0 && oldWidth != width) {
            setText(getText());
        }
    }

    @Override
    public void setMaxLines(int maxlines) {
        super.setMaxLines(maxlines);
        mMaxLines = maxlines;
    }
}

and activity_main

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp">

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

        <EditText
            android:id="@+id/edittext"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/edittext" />

        <com.anirudha.experiment.EllipsizedTextView
            android:id="@+id/text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:maxLines="2"
            android:singleLine="false"/>
    </RelativeLayout>
</ScrollView>
like image 124
Anirudha Agashe Avatar answered Sep 18 '22 17:09

Anirudha Agashe