【问题标题】:Setting multiple custom elements to MultiAutoCompleteTextView : Android将多个自定义元素设置为 MultiAutoCompleteTextView :Android
【发布时间】:2013-11-07 14:09:46
【问题描述】:

从我的previous 帖子继续,我能够为MultiAutoCompleteTextView 设置多个元素,但我无法像链接图片中那样使用自定义背景和关闭按钮来包装这些项目。

我能够对单个元素执行相同的操作,但对于多个元素,运气不佳。

这是我尝试过的。

//将文本设置为MultiAutoCompleteTextView

private void setTextSample(String contactName) {

    final SpannableStringBuilder sb = new SpannableStringBuilder();
    TextView tv = (TextView) LayoutInflater.from(this).inflate(R.layout.textview, null);
    tv.setText(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);

    mMultiAutoCompleteTextView.setText(sb);
}

// 用自定义元素换行

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

非常感谢任何帮助。

编辑:

如果我这样做

mMultiAutoCompleteTextView.setText(mMultiAutoCompleteTextView.getText().toString()+", "+sb);

我收到多个文本,但它们没有用自定义背景包裹。 没有找到我要去的地方。

编辑:

示例多个元素看起来像这样

【问题讨论】:

  • 十字按钮?什么十字按钮?
  • 我的意思是关闭按钮,用作删除项目的指示器
  • 如果你这样写mMultiAutoCompleteTextView.setText(sb);,它可以工作吗?

标签: android canvas bitmap custom-controls autocompletetextview


【解决方案1】:

试试这个:

class MyMultiAutoCompleteTextView extends MultiAutoCompleteTextView {

    public MyMultiAutoCompleteTextView(Context context) {
        super(context);
    }

    @Override
    protected void replaceText(CharSequence text) {
        Log.d(TAG, "replaceText " + text.getClass() + " " + text);
        super.replaceText(getSpanned(text.toString()));
    }
}

private Spanned getSpanned(String name) {
    TextView tv = (TextView) LayoutInflater.from(this).inflate(R.layout.test, null);
    tv.setText(name);
    SpannableStringBuilder sb = new SpannableStringBuilder(name);
    sb.setSpan(new ViewReplacementSpan(tv), 0, sb.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    return sb;
}

class ViewReplacementSpan extends DynamicDrawableSpan {
    private View v;
    private Drawable drawable;

    public ViewReplacementSpan(View v) {
        super(ALIGN_BOTTOM);
        this.v = v;
        int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        v.measure(spec, spec);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        drawable = new SpanDrawable();
        drawable.setBounds(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
    }

    @Override
    public Drawable getDrawable() {
        return drawable;
    }

    class SpanDrawable extends Drawable {
        @Override
        public void draw(Canvas canvas) {
            canvas.clipRect(getBounds());
            v.draw(canvas);
        }

        @Override
        public void setAlpha(int alpha) {
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
        }

        @Override
        public int getOpacity() {
            return PixelFormat.TRANSLUCENT;
        }
    }
}

在 onCreate() 中使用以下内容对其进行测试:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

MultiAutoCompleteTextView mactv = new MyMultiAutoCompleteTextView(this);
ArrayAdapter<Spanned> a = new ArrayAdapter<Spanned>(this, android.R.layout.simple_dropdown_item_1line);
String[] names = { "Jane", "John", "Mary", "Mark" };
for (String name: names) {
    a.add(getSpanned(name));
}

Tokenizer tokenizer = new MultiAutoCompleteTextView.CommaTokenizer();
mactv.setTokenizer(tokenizer);
mactv.setAdapter(a);
mactv.setThreshold(1);
SpannableStringBuilder sb = new SpannableStringBuilder();
for (int i = 0; i < 2; i++) {
    sb.append(tokenizer.terminateToken(a.getItem(i)));
}
mactv.setText(sb);
ll.addView(mactv);

TextView tv = new TextView(this);
tv.setGravity(Gravity.CENTER);
tv.setText("try: Jane, John, Mary or Mark");
tv.setTextSize(32);
ll.addView(tv);
setContentView(ll);

【讨论】:

  • 它现在可以正确设置初始项目,但是如果我从建议下拉列表中删除和/或尝试设置项目,我会得到纯文本。
  • 不,下拉列表中的项目作为跨度插入到 mactv,你运行了我的所有代码还是只运行了一部分?
  • 哎呀...如果我将它作为单独的应用程序运行,工作正常。与现有应用程序集成有问题。过段时间会恢复的。谢谢。
  • 搞定了。非常感谢您的回复。最后是我缺少的 SpannableStringBuilder。
  • @pskink 这是什么 R.layout.test?
【解决方案2】:

我觉得你这里有问题:

mMultiAutoCompleteTextView.setText(mMultiAutoCompleteTextView.getText().toString()+", "+sb);

当您调用 mMultiAutoCompleteTextView.getText().toString() 时,您会将 spannableString 转换为普通字符串,该字符串不能保存背景或其他内容。

尝试将您当前的 SpannableStringBuilder 保存在某处并像这样工作:

mBuilder.append(sb);
  mMultiAutoCompleteTextView.setText(mBuilder);

【讨论】:

  • 非常感谢您的回复。会试试的。
  • 搞定了。非常感谢您的回复。最后是我缺少的 SpannableStringBuilder
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-23
相关资源
最近更新 更多