2012-07-13 19 views
7

Tôi muốn cho phép người dùng chỉnh sửa chỉ là một phần của dòng văn bản trong ứng dụng Android của tôi. Tôi thấy một lớp được gọi là EasyEditSpan nhưng khi tôi gắn nó vào một TextView thì không có gì xảy ra cả. Tôi đã thử làm cho TextView có thể chỉnh sửa được nhưng nó vẫn không có hiệu lực. Nếu chuyển sang EditText thì toàn bộ dòng văn bản có thể chỉnh sửa cũng không chính xác. Đây là mã của tôi:EasyEditSpan được sử dụng như thế nào trong Android để cho phép chỉnh sửa văn bản một phần?

@Override 
public void onCreate(Bundle savedInstanceState) { 
    TextView testView = (TextView)findViewById(R.id.text_view); 
    testView.setText(buildMiddleEditSpannable("Please enter your ", "Name", " here.")); 
} 

public static Spannable buildMiddleEditSpannable(CharSequence beginning, CharSequence middle, CharSequence end) { 
    int spanMidStart = beginning.length(); 
    int spanMidEnd = spanMidStart + middle.length(); 

    SpannableString span = new SpannableString(new StringBuilder(middle).insert(0, beginning).append(end)); 
    span.setSpan(new EasyEditSpan(), spanMidStart, spanMidEnd, 0); 
    return span; 
} 
+0

phiên bản Android mục tiêu ứng dụng của bạn để chạy là gì? Lưu ý rằng [EasyEditSpan] (http://developer.android.com/reference/android/text/style/EasyEditSpan.html) thực sự mới được giới thiệu kể từ API cấp 14. Nó có thể phá vỡ trên hệ thống Android cũ, mặc dù bạn sẽ nhận được một số ngoại lệ lỗi trong Logcat. – yorkw

+0

Tôi đang chạy và thử nghiệm trên Ice Cream Sandwich hoặc cao hơn. – satur9nine

Trả lời

5

Sau khi xem xét các mã khuôn khổ đề cập đến EasyEditSpan (EasyEditSpan, TextViewTextUtils), nó trở nên rõ ràng rằng mặc dù nó nói trong mô tả của nó:

Cung cấp một cách dễ dàng cách chỉnh sửa một phần văn bản.

Các chức năng hiện có được giới hạn chỉ là phần thứ hai của mô tả như sau:

Các TextView sử dụng khoảng thời gian này để cho phép người dùng xóa một chuck của văn bản trong một cú nhấp chuột. văn bản. TextView loại bỏ khoảng này ngay sau khi văn bản được chỉnh sửa hoặc con trỏ di chuyển.

Dưới đây là một số mẫu mã nhanh chóng mà chứng tỏ việc sử dụng nó:

public class EasyEditSpanActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     final EditText editText = new EditText(this); 
     setContentView(editText); 

     showToast("Longclick to set EasyEditSpan for the line on cursor"); 

     editText.setInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); 
     editText.setSingleLine(false); 
     editText.setText("####\n#######\n###\n######\n####".replace("#", "text ")); 
     editText.setOnLongClickListener(new OnLongClickListener() { 
      @Override 
      public boolean onLongClick(View v) { 
       final Layout layout = editText.getLayout(); 
       final int line = layout.getLineForOffset(editText.getSelectionStart()); 
       final int start = layout.getLineStart(line); 
       final int end = layout.getLineEnd(line); 
       editText.getEditableText().setSpan(new EasyEditSpan(), start, end, 
         Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
       showToast("Edit line to show EasyEdit window"); 
       return true; 
      } 
     }); 
    } 

    private void showToast(String message) { 
     Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); 
    } 

} 

Vì vậy, không may nếu bạn cần một cách để cho phép người dùng chỉnh sửa chỉ là một phần của một dòng văn bản trong ứng dụng của bạn, EasyEditSpan không dường như giúp ích nhiều. Có thể bạn sẽ cần phải thực hiện một số mã sử dụng ClickableSpan và có thể là một hộp thoại tùy chỉnh.

+0

Nhìn vào mã trong TextView, tôi không thể thấy cách EasyEditSpan thực hiện bất cứ điều gì dễ dàng để chỉnh sửa. Ngay cả Javadoc nói nó chỉ cho phép xóa văn bản. – sww314

3

Bạn có thể sử dụng ClickableSpan và bật hộp thoại để chỉnh sửa nội dung. Tuy nhiên, tôi đã cố gắng triển khai một phần chỉnh sửa văn bản. Điều này không đầy đủ và có thể có một số cạnh thô. Nó sử dụng ba nhịp và ghi đè lên các phương thức SelectSelectionChanged (int selStart, int selEnd) và onKeyDown (int keyCode, KeyEvent) để vô hiệu hóa các chỉnh sửa trong khi đích là part1 hoặc part3. Hy vọng nó giúp.

//activity_main.xml

<RelativeLayout 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" > 

    <com.sensei.partialedit.EditTextSelectable 
     android:id="@+id/text_view" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:padding="@dimen/padding_medium" 
     android:text="@string/hello_world" 
     android:background="#00000000" 
     tools:context=".MainActivity" /> 
</RelativeLayout> 

//MainActivity.java

package com.sensei.partialedit; 

import android.app.Activity; 
import android.os.Bundle; 

public class MainActivity extends Activity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     EditTextSelectable testView = (EditTextSelectable) findViewById(R.id.text_view); 
     testView.setText("Please enter your ", " Name ", " here."); 
    } 
} 

//EditTextSelectable.java

package com.sensei.partialedit; 

import android.content.Context; 
import android.graphics.Color; 
import android.text.Spannable; 
import android.text.SpannableStringBuilder; 
import android.text.method.KeyListener; 
import android.text.style.CharacterStyle; 
import android.text.style.ForegroundColorSpan; 
import android.text.style.UnderlineSpan; 
import android.util.AttributeSet; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.widget.EditText; 

public class EditTextSelectable extends EditText { 

    private String part1; 
    private String part2; 
    private String part3; 
    private ForegroundColorSpan span1; 
    private CharacterStyle span2; 
    private ForegroundColorSpan span3; 

    public EditTextSelectable(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     setTag(getKeyListener()); 
    } 

    public EditTextSelectable(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setTag(getKeyListener()); 
    } 

    public EditTextSelectable(Context context) { 
     super(context); 
     setTag(getKeyListener()); 
    } 

    public void setText(String part1, String part2, String part3) { 
     setText(buildMiddleEditSpannable(part1, part2, part3)); 
     setSelection(part1.length() + part2.length() - 1); 
    } 

    private Spannable buildMiddleEditSpannable(String part1, String part2, 
      String part3) { 
     this.part1 = part1; 
     this.part2 = part2; 
     this.part3 = part3; 
     SpannableStringBuilder spannable = new SpannableStringBuilder(part1 
       + part2 + part3); 
     span1 = new ForegroundColorSpan(Color.GRAY); 
     spannable.setSpan(span1, 0, part1.length() - 1, 
       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     span2 = new UnderlineSpan(); 
     spannable.setSpan(span2, part1.length(), 
       part1.length() + part2.length(), 
       Spannable.SPAN_INCLUSIVE_INCLUSIVE); 
     span3 = new ForegroundColorSpan(Color.GRAY); 
     spannable.setSpan(span3, (part1 + part2).length(), 
       (part1 + part2 + part3).length(), 
       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 
     return spannable; 
    } 

    @Override 
    protected void onSelectionChanged(int selStart, int selEnd) { 
     if (part1 == null) 
      return; 
     if (selStart >= getText().getSpanStart(span2) 
       && selEnd <= getText().getSpanEnd(span2)) { 
      setKeyListener((KeyListener) getTag()); 
      setCursorVisible(true); 
     } else { 
      setKeyListener(null); 
      setCursorVisible(false); 
     } 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode==KeyEvent.KEYCODE_ENTER) { 
      // Just ignore the [Enter] key 
      return true; 
     } 
     int selectionStart = getSelectionStart(); 
     int selectionEnd = getSelectionEnd(); 
     Log.d("partialedit", "OnKeyDown:" + selectionStart + ":" + selectionEnd + ":" + getText().getSpanStart(span2) + ":" + getText().getSpanEnd(span2)); 
     if (selectionStart < part1.length() + 1 
      || selectionStart >= getText().length() - part3.length()) { 
      return true; 
     } 

     // Handle all other keys in the default way 
     return super.onKeyDown(keyCode, event); 
    } 
} 
Các vấn đề liên quan