首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spinner不会对文本进行换行--这是Android的bug吗?

Spinner不会对文本进行换行--这是Android的bug吗?
EN

Stack Overflow用户
提问于 2013-01-03 20:37:32
回答 14查看 43.8K关注 0票数 69

如果Spinner项目的文本太长,无法放入一行,则文本不会换行,而是会被截断。这只适用于应用编程接口级别的>= 11。这是Android 4.2.2 (左)和Android 2.3.3 (右)的截图,显示了错误的行为。

android:singleLine="false"在这里被忽略了。因此,像android:linesandroid:minLines等所有其他尝试一样,TextView似乎以某种方式比窗口宽度宽得多。

我看到其他人也有同样的问题,但没有人能找到解决方案。那么,这是一个系统错误吗?我不认为操作系统版本之间的这种不一致是故意的。

请注意:

有一些答案建议了相对简单的解决方案。

  • 编写自定义Adapter并覆盖getView()getDropDownView()。这不是这里的解决方案,因为在这一点上,仍然存在原始的问题:布局必须看起来如何处理正确的行wrapping?
  • Wrapping下拉式视图的TextView到父ViewGroup中。不适用于android:layout_width="match_parent",因为奇怪的是,父对象的宽度似乎是下拉式视图的固定宽度。这不适合不同宽度的Spinner
  • 当然,没有解决方案是手动将\n插入到文本中的任何位置。

使用以下代码进行重现:

更新:我也将其作为示例项目上传到GitHubDownload

/res/values/arrays.xml:

代码语言:javascript
运行
复制
<string-array name="items">
    <item>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt.</item>
    <item>At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est.</item>
</string-array>

/res/layout/spinner_item.xml:

代码语言:javascript
运行
复制
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    style="?android:attr/spinnerDropDownItemStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:ellipsize="none"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:singleLine="false" />

设置Adapter

代码语言:javascript
运行
复制
spinner.setAdapter(ArrayAdapter.createFromResource(this,
            R.array.items,
            R.layout.spinner_item));
EN

回答 14

Stack Overflow用户

回答已采纳

发布于 2013-11-15 12:44:49

在全息主题微调器默认情况下使用下拉模式。所有使用覆盖默认样式的操作都会切换到对话框模式,这样就可以像在API11中那样成功地对多行文本进行换行。相反,您可以使用new Spinner(context, Spinner.MODE_DIALOG)或在xml:android:spinnerMode="dialog"中创建微调器。但它并没有解决问题,因为它是对话框,而不是下拉列表。

我已经为这个问题找到了另一个解决方案:覆盖ArrayAdapter中的getDropDownView方法,并将setSingleLine(false)放在视图的post方法中。因此,当视图完全创建时,它会将文本换行到适当的行。

代码语言:javascript
运行
复制
@Override
public View getDropDownView(final int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = new TextView(_context);
    }

    TextView item = (TextView) convertView;
    item.setText("asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
    final TextView finalItem = item;
    item.post(new Runnable() {
        @Override
        public void run() {
            finalItem.setSingleLine(false);
        }
    });
    return item;
}

更新:

这是另一个答案。

在PopupWindow中手动包装listview,并在单击时将其显示在TextView下,在listItem单击时将其隐藏。

简单的实现只是为了展示一下想法:

代码语言:javascript
运行
复制
public class MySpinner extends TextView {
    private PopupWindow _p;
    private ListView _lv;
    public MySpinner(Context context) {
        super(context);
        init();
    }
    public MySpinner(Context context, AttributeSet attributeSet){
        super(context, attributeSet);
        init();
    }

    private void init(){
        setBackgroundResource(R.drawable.spinner_background);
        final List<String> list = new ArrayList<String>();
        list.add("Very long text AAAAAAAAAAAAAAAA");
        list.add("1 Very long text AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
        list.add("2 Very long text A");
        list.add("3 Very long text AAAAAAAAA");

        setMinimumWidth(100);
        setMaxWidth(200);

        _lv = new ListView(getContext());
        _lv.setAdapter(new ArrayAdapter<String>(getContext(), R.layout.simple_list_item_1, list));
        _lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                _p.dismiss();
                setText(list.get(i));
            }
        });

        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                _p = new PopupWindow(getContext());
                _p.setContentView(_lv);
                _p.setWidth(getWidth());
                _p.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
                _p.setTouchable(true);
                _p.setFocusable(true);
                _p.setOutsideTouchable(true);
                _p.showAsDropDown(view);
            }
        });
    }
}
票数 36
EN

Stack Overflow用户

发布于 2015-04-23 17:05:37

这里只有一个解决方案的组合对我有效(也是在Android 5.1上测试的):

spinner_item.xml

代码语言:javascript
运行
复制
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:layout_width="match_parent"
             android:layout_height="wrap_content">

  <TextView
    android:id="@android:id/text1"
    style="?android:attr/spinnerItemStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:singleLine="false"
    android:textAlignment="inherit"/>
</LinearLayout>

代码

代码语言:javascript
运行
复制
  final ArrayAdapter<String> spinnerArrayAdapter=new ArrayAdapter<String>(activity,R.layout.spinner_item,android.R.id.text1,spinnerItemsList)
  {
  @Override
  public View getDropDownView(final int position,final View convertView,final ViewGroup parent)
    {
    final View v=super.getDropDownView(position,convertView,parent);
    v.post(new Runnable()
    {
    @Override
    public void run()
      {
      ((TextView)v.findViewById(android.R.id.text1)).setSingleLine(false);
      }
    });
    return v;
    }
  };
  spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
票数 17
EN

Stack Overflow用户

发布于 2013-07-19 14:28:48

我已经通过切换到对话框样式的微调器解决了这个问题:

代码语言:javascript
运行
复制
<Spinner
  ...
android:spinnerMode="dialog" />
票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14139106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档