EditText中的可点击项

时间:2013-10-11 13:20:24

标签: android android-edittext

问题:

总而言之,我想在clickable内插入一个自定义的Drawable EditText(或类似于一个小按钮的东西,就像一个字符一样)

研究

我已经阅读了一些文档以及相关问题,我几乎达到了我想要的结果(参见“代码”部分)。这有点棘手,但我无法找到另一条出路。我正在使用Html.fromHtml(source, imageGetter, tagHandler)通过链接插入我需要的drawable,然后实现自定义LinkMovementMethod来处理对它的点击。

但我想避免一些事情:

  1. 如果我的drawable之后没有文本,即使我点击任何地方,它也会被点击。因此,如果不手动移动光标,我就无法将光标放在旁边。
  2. 在某些设备上,每次执行点击时,光标都会显示在EditText的最开头,除非我点击可绘制的情况。
  3. 代码:

    使用链接插入drawable并设置自定义LinkMovementMethod

    Html.ImageGetter imgGetter = new Html.ImageGetter() {
    
        @Override
        public Drawable getDrawable(String source) {
    
            Drawable drawable = getResources().getDrawable(R.drawable.blip_icon_read);
    
            //Making it as small as a character
            drawable.setBounds(0, 0, (int)getTextSize(), (int)getTextSize());
    
            return drawable;
        }
    };
    
    String buttonSrc = "<a href='button://" + "somedata" + "'><img src=/></a>";
    
    myEditText.append(Html.fromHtml(buttonSrc, imgGetter, null));
    myEditText.setMovementMethod(MyLinkMovementMethod.getInstance(context));
    

    自定义LinkMovementMethod

    public class MyLinkMovementMethod extends LinkMovementMethod {
    
        private static Context movementContext;
    
        private static MyLinkMovementMethod linkMovementMethod = new MyLinkMovementMethod();
    
        public boolean onTouchEvent(android.widget.TextView widget, android.text.Spannable buffer, android.view.MotionEvent event) {
    
            int action = event.getAction();
    
            if (action == MotionEvent.ACTION_UP) {
    
                int x = (int) event.getX();
                int y = (int) event.getY();
    
                x -= widget.getTotalPaddingLeft();
                y -= widget.getTotalPaddingTop();
    
                x += widget.getScrollX();
                y += widget.getScrollY();
    
                Layout layout = widget.getLayout();
                int line = layout.getLineForVertical(y);
                int off = layout.getOffsetForHorizontal(line, x);
    
                URLSpan[] link = buffer.getSpans(off, off, URLSpan.class);
                if (link.length != 0) {
    
                    URI uri;
    
                    try {
                        uri = new URI(link[0].getURL());
                    } catch (URISyntaxException e) {
                        e.printStackTrace();
                        return true;
                    }
    
                    if (uri.getScheme().equals("button")) {
                        //Doing stuff here
                    }
                    return true;
                }
            }
    
            return super.onTouchEvent(widget, buffer, event);
        }
    
        public static android.text.method.MovementMethod getInstance(Context c) {
            movementContext = c;
            return linkMovementMethod;
        }
    }
    

    布局:

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <EditText
            android:id="@+id/my_edit_text"
    
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/white"
            android:textColor="@android:color/black"
            android:scrollbars="vertical"
            android:textCursorDrawable="@null"
            android:gravity="top" >
    
        </EditText>
    
    </LinearLayout>
    

    问题:

    1. 有没有办法避免使用这种方法在“研究”部分末尾描述的内容?
    2. 我应该使用另一种方法吗?
    3. 很高兴阅读建议或任何想法。谢谢。

2 个答案:

答案 0 :(得分:0)

这似乎有用(除非我真的不明白你的想法)

public class MyMovementMethod extends ArrowKeyMovementMethod {
    @Override
    public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            x -= widget.getTotalPaddingLeft();
            y -= widget.getTotalPaddingTop();

            x += widget.getScrollX();
            y += widget.getScrollY();

            Layout layout = widget.getLayout();
            int line = layout.getLineForVertical(y);
            int off = layout.getOffsetForHorizontal(line, x);

            MyClickableSpan[] link = buffer.getSpans(off, off, MyClickableSpan.class);

            if (link.length != 0 && off != buffer.length()) {
                link[0].doSomething();
                return true;
            }
        }
        return super.onTouchEvent(widget, buffer, event);
    }
}

class MyClickableSpan extends ImageSpan {
    public MyClickableSpan(Bitmap b) {
        super(b);
    }
    public void doSomething() {
        Log.d(TAG, "doSomething ***********************************************");
    }
}

测试它在Activity.onCreate中添加以下内容:

LinearLayout ll = new LinearLayout(this);
EditText et = new EditText(this);
SpannableStringBuilder b = new SpannableStringBuilder();
b.append("Attach the specified markup object to the ");
int start = b.length();
b.append("x");
int end = b.length();
b.append(" range start end of the text, or move the object to that range if it was...");
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
b.setSpan(new MyClickableSpan(bitmap), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

et.setText(b);
et.setMovementMethod(new MyMovementMethod());
ll.addView(et);
setContentView(ll);

答案 1 :(得分:0)

只需使用ScrollView,因为parentView会帮助您。 喜欢这个

<ScrollView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layout_marginBottom="45dp"
     android:layout_below="@id/header_container"
     >
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical"
         >
         <EditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:id="@+id/title"
             android:hint="输入标题"
             android:layout_marginStart="15dp"
             android:layout_marginLeft="15dp"
             android:layout_marginRight="15dp"
             android:layout_marginEnd="15dp"
             android:inputType="text"
             android:textSize="22sp"
             android:singleLine="true"
             android:textCursorDrawable="@color/cursor_white"
             android:background="@drawable/bg_edittext_title_white"
             android:padding="5dp"
             >
         </EditText>

         <EditText
             android:id="@+id/content"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:background="@null"
             android:gravity="start|top"
             android:layout_marginLeft="15dp"
             android:layout_marginStart="15dp"
             android:layout_marginRight="15dp"
             android:layout_marginEnd="15dp"
             android:layout_marginTop="10dp"
             android:inputType="textMultiLine"
             android:minHeight="220dp"
             android:singleLine="false"
             android:textCursorDrawable="@color/cursor_white"
             android:hint="输入内容"
             android:padding="5dp"
             />
     </LinearLayout>

 </ScrollView>