Spinner 不换行文本——这是 Android 错误吗? [英] Spinner does not wrap text -- is this an Android bug?

查看:38
本文介绍了Spinner 不换行文本——这是 Android 错误吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果 Spinner 项目的文本太长而无法放入一行,文本不会被换行而是被切断.这是API 级别>= 11 的情况.以下是显示错误行为的 Android 4.2.2(左)和 Android 2.3.3(右)的屏幕截图.

If the text of a Spinner item is too long to fit into a single line, the text is not wrapped but cut off. This is only the case for API level >= 11. Here are screenshots of Android 4.2.2 (left) which shows the wrong behavior and Android 2.3.3 (right) where it looks as expected.

android:singleLine="false" 在这里被忽略了.就像所有其他尝试一样 android:linesandroid:minLines 等.TextView 不知何故似乎比窗口宽度宽得多.

android:singleLine="false" simply gets ignored here. So as all other tries like android:lines, android:minLines, etc. The TextView somehow seems to be much wider than the window width.

我看到其他人也有同样的问题,但没有人能找到解决办法.那么,这是系统错误吗?我不认为操作系统版本之间存在这种不一致.

I saw other people having the same problem, but no one could find a solution. So, is this a system bug? I don't think this inconsistency between the OS versions can be intended.

有一些答案提出了相对简单的解决方案.

There were some answers suggesting relatively simple solutions.

  • 编写自定义Adapter 并覆盖getView() 以及getDropDownView().这不是这里的解决方案,因为此时仍然存在原始问题:布局必须如何处理正确的换行?

  • Writing a custom Adapter and overriding getView() as well as getDropDownView(). This is not the solution here, because at this point, there is still the original problem: How does the layout have to look like to handle proper line wrapping?

将下拉视图的 TextView 包装到父 ViewGroup 中.不适用于 android:layout_width="match_parent" 因为奇怪的是父的宽度似乎是无限的.

Wrapping the TextView of the drop down view into a parent ViewGroup. Does not work with android:layout_width="match_parent" because the width of the parent strangely seems to be unlimited.

给下拉视图一个固定的宽度.这不适合 Spinner 可以具有的不同宽度.

Giving the drop down view a fixed width. This is not suitable with the different widths the Spinner can have.

当然,没有解决方案是手动将 s 插入文本的任何位置.

And of course, no solution is to manually insert s anywhere into the text.

更新:我还在 GitHub 上上传了这个示例项目:下载

UPDATE: I also uploaded this as a sample project on GitHub: Download

/res/values/arrays.xml:

/res/values/arrays.xml:

<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:

/res/layout/spinner_item.xml:

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

设置适配器:

spinner.setAdapter(ArrayAdapter.createFromResource(this,
            R.array.items,
            R.layout.spinner_item));

推荐答案

在全息主题微调器中默认使用下拉模式.并且所有具有覆盖默认样式的移动只是将微调器模式切换到对话模式,该模式成功地包装了多行文本,如 api 11 中一样.相反,您可以使用 new Spinner(context, Spinner.MODE_DIALOG) 或在创建微调器xml:android:spinnerMode="dialog".但这并不能解决问题,因为它是对话框,而不是下拉菜单.

In holo theme spinner by default uses dropdown mode. And all moves with overriding default styles just move to switching spinner mode to dialog mode which succesfully wraps multiline text as in api 11. Instead you can create spinner with new Spinner(context, Spinner.MODE_DIALOG) or in xml: android:spinnerMode="dialog". But it's not resolve the problem, because it's dialog, not dropdown.

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

I have found another solution for this trouble: Override getDropDownView method in ArrayAdapter and put setSingleLine(false) in post method of view. So when view completely created it wraps the text to appropriate lines.

@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 时隐藏它.

Manually wrap listview in PopupWindow and show it under TextView on click and hide it on listItem click.

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

Simple implementation just to show idea:

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

这篇关于Spinner 不换行文本——这是 Android 错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆