微调不换行文字 - 这是一个Android错误? [英] Spinner does not wrap text -- is this an Android bug?

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

问题描述

如果一个微调项目的文本太长,以适应单行,文本不包装,而切断。这是的只有的对于 API级的情况下> = 11 。下面是Android系统截图 4.2.2 (左),这显示了错误的行为和Android的 2.3.3 (右)它看起来如预期。

安卓SINGLELINE =假只是在这里被忽略了。因此,所有其他的尝试,比如安卓行安卓的minlines 等。的TextView 某种程度上似乎比窗口宽度宽得多。

我看到有同样的问题其他人,但没有人能找到一个解决方案。所以,这是一个系统错误?我不认为在操作系统版本之间的矛盾,可以预期的。


请注意:

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

  • 编写自定义适配器并覆盖 getView()以及 getDropDownView()。这不是这里的解决方案,因为在这一点上,仍然有原来的问题:如何布局有看起来像处理适当的换行

  • 中包装的TextView 下拉视图到父的的ViewGroup 。不与 Android的工作:layout_width =match_parent,因为父的宽度奇怪,似乎是无限的。

  • 赋予下拉查看一个固定的宽度。这是不适合与不同宽度微调可以。

  • 当然,没有任何解决方法是手动插入 s转换文字的任何地方。


再现与下面code:

更新:我也上传这个作为 GitHub上的示例项目:的Download

/res/values​​/arrays.xml:

 <字符串数组名=项目>
    <项目> Lorem存有悲坐阿梅德,consetetur sadipscing elitr,SED直径nonumy eirmod tempor invidunt< /项目>
    <项目>在维罗EOS等accusam等胡斯托二人多洛雷斯等EA rebum。 STET clita kasd gubergren,没有海takimata圣哉EST< /项目>
< /字符串数组>
 

/res/layout/spinner_item.xml:

 < TextView中的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:ID =@机器人:ID / text1中
    风格=机器人:ATTR / spinnerDropDownItemStyle
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:ellipsize =无
    机器人:=了minHeight机器人:ATTR /列表preferredItemHeight
    机器人:单线=FALSE/>
 

设置适配器

  spinner.setAdapter(ArrayAdapter.createFromResource(这一点,
            R.array.items,
            R.layout.spinner_item));
 

解决方案

在全息主题微调默认使用下拉菜单模式。和所有覆盖默认样式移动只是移动到切换微调模式对话框模式,成功地包装了多行文字在API 11相反,你可以创建微调新的微调(背景下,Spinner.MODE_DIALOG)或XML:机器人:spinnerMode =对话。但它不能解决问题,因为它是对话,而不是下拉列表。

我已经找到了这种麻烦另一种解决方案:覆盖在ArrayAdapter getDropDownView方法,并把setSingleLine(假)在视POST方法。所以,当认为完全地创建它包装的文字,以适当的行。

  @覆盖
    公共查看getDropDownView(最终诠释的立场,观点convertView,ViewGroup中父){
        如果(convertView == NULL){
            convertView =新的TextView(_context);
        }

        TextView的项目=(TextView中)convertView;
        item.setText("asddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd");
        最后的TextView finalItem =项目;
        item.post(新的Runnable(){
            @覆盖
            公共无效的run(){
                finalItem.setSingleLine(假);
            }
        });
        返回的项目;
    }
 

更新:

这里是另一种答案。

手动换行PopupWindow列表视图,并显示udner的TextView上点击和隐藏它的listItem点击。 简单的执行力度只是为了显示想法:

 公共类MySpinner扩展TextView的{
私人PopupWindow _p;
私人的ListView _lv;
公共MySpinner(上下文的背景下){
    超(上下文);
    在里面();
}
公共MySpinner(上下文的背景下,AttributeSet中的AttributeSet){
    超(背景下,AttributeSet中的);
    在里面();
}

私人无效的init(){
    setBackgroundResource(R.drawable.spinner_background);
    最后的名单,其中,字符串>名单=新的ArrayList<字符串>();
    list.add(很长的文本AAAAAAAAAAAAAAAA);
    list.add(1很长的文本AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA);
    list.add(2很长的文本A);
    list.add(3很长的文本AAAAAAAAA);

    setMinimumWidth(100);
    setMaxWidth(200);

    _lv =新的ListView(的getContext());
    _lv.setAdapter(新ArrayAdapter<字符串>(的getContext(),R.layout.simple_list_item_1,列表));
    _lv.setOnItemClickListener(新AdapterView.OnItemClickListener(){
        @覆盖
        公共无效onItemClick(适配器视图<>适配器视图,视图中查看,INT I,长L){
            _p.dismiss();
            的setText(list.get(一));
        }
    });

    setOnClickListener(新OnClickListener(){
        @覆盖
        公共无效的onClick(视图查看){

            _p =新PopupWindow(的getContext());
            _p.setContentView(_lv);
            _p.setWidth(的getWidth());
            _p.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
            _p.setTouchable(真正的);
            _p.setFocusable(真正的);
            _p.setOutsideTouchable(真正的);
            _p.showAsDropDown(视图);
        }
    });
}
 

}

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


Please note:

There were some answers suggesting relatively simple solutions.

  • 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?

  • 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.

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

  • And of course, no solution is to manually insert \ns anywhere into the text.


Reproduce with the following code:

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

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

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

Set Adapter:

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

解决方案

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.

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

UPDATE:

And here is another answer.

Manually wrap listview in PopupWindow and show it udner TextView on click and hide it on listItem click. Simple implimentation 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);
        }
    });
}

}

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

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