【问题标题】:Android Labels or Bubbles in EditTextEditText 中的 Android 标签或气泡
【发布时间】:2011-11-11 07:04:41
【问题描述】:

有人能指出正确的方向吗?如何在 EditText 中制作那些气泡或标签,就像您在添加圈子或联系人时想在 Stream for Google+ 中撰写内容时看到的那样? Rectangle 是一个自动完成的编辑文本。

【问题讨论】:

  • 亲爱的把可能的快照放在你谈论的任何时候,并给出任何其他应用程序的例子,这样我们就可以准确地捕捉到。我希望你明白我的意思。 1 个快照 = 10000 个字 :)
  • 他们曾经限制图像。 >.
  • 好的,我已经更新了问题。
  • +1 无论如何是个好问题。
  • “你的圈子”和“扩展的圈子”是不同的 EditText 吗?

标签: android android-edittext


【解决方案1】:

您所显示的是与 SMS 股票应用程序相同的行为。搜索代码here 看看它是如何完成的。

编辑:

代码应位于platform_packages_apps_mms。看看RecipientsEditor 类。

【讨论】:

  • @David:创建新短信时检查短信应用程序。您将能够在多个之间进行选择。短信代码是开源的。
  • 这是一个很好的链接,它引导我阅读 MultiAutoCompleteTextView,它显示了自动完成部分的工作原理。该代码描述它由“,”或“;”分隔但上面没有显示分隔符和图像。很酷的是,当您在“气泡”上按退格键时,它会删除整个单词!文本中有背景图片还是我遗漏了什么?
  • @Maurice:我猜这是一个带有灰色 android:background 和一个 android:leftDrawableTextView
  • 据我所知,您需要使用Spannable 系统(我在另一个答案中对此进行了描述)将drawables 放入以文本形式流动的TextView/EditText。跨度>
  • 适用于 4+ 设备,但不适用于 2.3...(未在任何 3 个设备上测试)
【解决方案2】:

我构建了TokenAutoComplete on github 来解决类似的问题,它应该也适合你。下面是一个演示应用的基本实现:

public class ContactsCompletionView extends TokenCompleteTextView {
    public ContactsCompletionView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected View getViewForObject(Object object) {
        Person p = (Person)object;

        LayoutInflater l = (LayoutInflater)getContext().getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        LinearLayout view = (LinearLayout)l.inflate(R.layout.contact_token, (ViewGroup)ContactsCompletionView.this.getParent(), false);
        ((TextView)view.findViewById(R.id.name)).setText(p.getEmail());

        return view;
    }

    @Override
    protected Object defaultObject(String completionText) {
        //Stupid simple example of guessing if we have an email or not
        int index = completionText.indexOf('@');
        if (index == -1) {
            return new Person(completionText, completionText.replace(" ", "") + "@example.com");
        } else {
            return new Person(completionText.substring(0, index), completionText);
        }
    }
}

contact_token 的布局代码(您可以在此处使用任何类型的布局,或者如果您想要令牌中的图像,可以将 ImageView 放入其中)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content">

    <TextView android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/token_background"
        android:padding="5dp"
        android:textColor="@android:color/white"
        android:textSize="18sp" />

</LinearLayout>

令牌背景可绘制

<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <solid android:color="#ffafafaf" />
    <corners
        android:topLeftRadius="5dp"
        android:bottomLeftRadius="5dp"
        android:topRightRadius="5dp"
        android:bottomRightRadius="5dp" />
</shape>

人物对象代码

public class Person implements Serializable {
    private String name;
    private String email;

    public Person(String n, String e) { name = n; email = e; }

    public String getName() { return name; }
    public String getEmail() { return email; }

    @Override
    public String toString() { return name; }
}

示例活动

public class TokenActivity extends Activity {
    ContactsCompletionView completionView;
    Person[] people;
    ArrayAdapter<Person> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        people = new Person[]{
                new Person("Marshall Weir", "marshall@example.com"),
                new Person("Margaret Smith", "margaret@example.com"),
                new Person("Max Jordan", "max@example.com"),
                new Person("Meg Peterson", "meg@example.com"),
                new Person("Amanda Johnson", "amanda@example.com"),
                new Person("Terry Anderson", "terry@example.com")
        };

        adapter = new ArrayAdapter<Person>(this, android.R.layout.simple_list_item_1, people);

        completionView = (ContactsCompletionView)findViewById(R.id.searchView);
        completionView.setAdapter(adapter);
    }
}

布局代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.tokenautocomplete.ContactsCompletionView
        android:id="@+id/searchView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</RelativeLayout>

【讨论】:

  • 嘿,我收到了这个错误:java.lang.ClassNotFoundException:找不到类“com.tokenautocomplete.TokenActivity”
  • @user1051505 检查您的主 xml 文件
【解决方案3】:

您可以通过创建android.text.style.DynamicDrawableSpan 的子类来做到这一点。 ImageSpan 就是一个例子:它将文本的跨度(范围)替换为图像。

此示例将在编辑字段中添加一个星号,替换文本“test”。在您的布局中创建一个 ID 为“text”的 EditText,并将其放入 onCreate()(或任何位置):

    EditText mText = (EditText) findViewById(R.id.text);
    final Editable e = mText.getEditableText();
    final SpannableStringBuilder sb = new SpannableStringBuilder();
    sb.append("test");
    sb.setSpan(new ImageSpan(this, android.R.drawable.btn_star), 0, 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    e.append(sb);

我没有看到任何看起来可以将普通文本包装在可绘制对象中的类,但这可以通过重写 getDrawable() 方法并自己渲染文本来轻松解决。

【讨论】:

  • 这很有趣。您可以将图像放入编辑文本中,但您必须退格 4 次才能删除整个图像。
  • 我怀疑上面的“你的圈子”是文本中的“你的圈子”,但被这个答案中描述的图像覆盖。现在要弄清楚当你删除分隔符时如何删除整个文本......
  • 退格几次实际上取决于跨度的 Spannable.SPAN_INCLUSIVE_EXCLUSIVE 部分。尝试使用几种不同的设置 - 总共有 4 种。
  • 就文本中的“你的圈子”而言,您可能是对的。您还可以使用 Macarse 的答案中指向的 Annotation 类将额外信息添加到文本流中。我怀疑最终的答案会同时使用这两个类。
  • 4个都不行,试了一下。我猜它与文本观察器有关。
【解决方案4】:

我在这里解决了这个问题Contact Bubble EditText

final SpannableStringBuilder sb = new SpannableStringBuilder();
TextView tv = createContactTextView(contactName);
BitmapDrawable bd = (BitmapDrawable) convertViewToDrawable(tv);
bd.setBounds(0, 0, bd.getIntrinsicWidth(),bd.getIntrinsicHeight());

sb.append(contactName + ",");
sb.setSpan(new ImageSpan(bd), sb.length()-(contactName.length()+1),sb.length()-1,Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
to_input.setText(sb);

public static Object convertViewToDrawable(View view) {
  int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
  view.measure(spec, spec);
  view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
  Bitmap b = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
        Bitmap.Config.ARGB_8888);
  Canvas c = new Canvas(b);
  c.translate(-view.getScrollX(), -view.getScrollY());
  view.draw(c);
  view.setDrawingCacheEnabled(true);
  Bitmap cacheBmp = view.getDrawingCache();
  Bitmap viewBmp = cacheBmp.copy(Bitmap.Config.ARGB_8888, true);
  view.destroyDrawingCache();
  return new BitmapDrawable(viewBmp);

}

public TextView createContactTextView(String text){
  //creating textview dynamically
  TextView tv = new TextView(this);
  tv.setText(text);
  tv.setTextSize(20);
  tv.setBackgroundResource(R.drawable.oval);
  tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, R.drawable.ic_clear_search_api_holo_light, 0);
  return tv;
}

【讨论】:

  • 上面的图片没有任何分隔符....是否可以有一个空分隔符而不是使用","..我试过没有给出任何分词器,但 multiautocompletetextview 没有显示任何建议..
【解决方案5】:

如果您指的是提示,您可以简单地添加:

android:hint="@string/myHint"

这会将灰色标签在 EditText 为空时放入。

【讨论】:

  • 不是提示,它看起来像一个对象。
【解决方案6】:

要设置EditText左侧的圆圈图标,您可以更改leftDrawable

您可以在布局 xml 文件 android:drawableRight="@drawable/search_icon" 上执行此操作,或以编程方式使用 setCompoundDrawablesWithIntrinsicBounds 函数。

如果您还想赋予气泡样式,则必须将背景可绘制对象更改为具有该样式的9-patchhere你有一个谷歌地图的 9 补丁气泡教程。

希望对您有所帮助! :)

【讨论】:

  • 我不认为这是他要问的。他只有一个编辑文本,并且文本条目可以设置样式。对吗?
【解决方案7】:

我认为它使用 setCompoundDrawables() 方法将该图片插入到编辑文本中

【讨论】:

  • 这已经在 J​​ordi 的回答中提出了建议,但是这种可绘制对象并没有像发帖者想要的那样随文本流动。
【解决方案8】:

我决定回馈社区,并创建了旨在解决您遇到的这个确切问题的库。 GitHub 上提供了该库和示例项目:https://github.com/RafalManka/BubbleEditText

【讨论】:

    猜你喜欢
    • 2016-05-22
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多