2015-03-06 2 views
1

Я использую ImageSpan для отображения изображения в текстовом виде. TextView - это sinlgline с конечным эллипсисом. Когда изображение находится в конце текста, и для него недостаточно места. Я думаю, что он должен отображать «...». Но он отображает часть изображения. Изображение обрезается с ошибкой.android imagespan изображение вырезано ошибка в singleline textview

enter image description here

XML-:

<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:paddingLeft="@dimen/activity_horizontal_margin" 
      android:paddingRight="@dimen/activity_horizontal_margin" 
      android:paddingTop="@dimen/activity_vertical_margin" 
      android:paddingBottom="@dimen/activity_vertical_margin" 
      tools:context=".MainActivity" 
android:orientation="vertical"> 


    <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:text="insert image"/> 

    <TextView 
    android:id="@+id/text" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:singleLine="true" 
    android:ellipsize="end"/> 
</LinearLayout> 

код:

public class MainActivity extends Activity { 

private EditText editText; 
private Button button; 
private TextView 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 = (TextView) findViewById(R.id.text); 

    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); 
     } 
    }); 
} 

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()); 
} 


@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.menu_main, menu); 
    return true; 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 

    //noinspection SimplifiableIfStatement 
    if (id == R.id.action_settings) { 
     return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 


} 

ответ

2

Я использую TextUtils.ellipsize текст перед установкой его в TextView.

CharSequence cs = TextUtils.ellipsize(s, textView.getPaint(), textView.getWidth() - textView.getPaddingRight() - textView.getPaddingLeft(), TextUtils.TruncateAt.END); 
textView.setText(cs); 
+0

Что относительно многострочного TextView? – Gohan

+0

Большое спасибо. –

+0

Это не будет работать, если представление изменяет размер динамически или в списке, где ширина представления может изменяться много раз в зависимости от текста. –

0

если TextView множества wrap_content или match_parent, вам лучше позвонить TextUtils.ellipsize в textview.post();

tv.post(new Runnable() { 
     @Override 
     public void run() { 
      tv.setText(TextUtils.ellipsize(tv.getText(), (TextPaint) tv.getPaint(), tv.getWidth() - tv.getPaddingRight() - tv.getPaddingLeft(), TextUtils.TruncateAt.END)); 
     } 
    }); 
0

Вы должны обертка текста составного до того, как стать SpannedEllipsizer, Вы можете найти идеальное решение здесь: это EllipsisSpannedContainer, когда многоточие видно, он будет игнорировать пролеты на позиции многоточия. https://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/android/text/EllipsisSpannedContainer.java Строка 207 показывает вам, как использовать EllipsisSpannedContainer. https://github.com/lsjwzh/FastTextView/blob/master/widget.FastTextView/src/main/java/com/lsjwzh/widget/text/FastTextView.java

Смежные вопросы