安卓:ListView中的EditText问题

10

我在应用程序中有一个列表视图,基本上是一个问卷,所以有一些EditText需要用户填写。我遇到了以下问题:

  1. 一些EditText需要数字输入,因此我在相应的xml类型中设置了inputType为numeric,但是当我点击EditText时,数字键盘出现后几乎立即消失,普通键盘显示。

  2. 可以想象,我需要存储用户输入这些EditText的值。我的问题是,在我输入某些文本到SOME EditTexts中并滚动后,当我返回时文本就会消失。您可以在我的代码中看到,我尝试防止这种情况发生,我应该提到它在复选框方面完全正常。

  3. 一开始我遇到了失去焦点的问题,但通过查看其他问题得到解决(将descendantFocusablity =“beforeDescendants”添加到ListView和windowSoftInputMode =“adjustPan”中)。除了当EditText在屏幕下半部分以下时,一旦我开始输入,它就会失去焦点。 列表适配器的getView方法:

public View getView(final int position,View result,ViewGroup parent)
{
final ViewHolder vh;
final Question question = values.get(position);
if(holders[position]==null)
    vh = new ViewHolder();
else
    vh = holders[position];

LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(question.getQuestionType().equals(Question.TYPE_CLOSED))
{
    result = inflater.inflate(R.layout.closed_question_list_item, null);
    vh.cb  = (CheckBox)result.findViewById(R.id.checkbox);
    vh.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() 
    {

        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
        {
            vh.isChecked      = isChecked;
            holders[position] = vh;
        }
    });
    vh.cb.setChecked(vh.isChecked);
}

else
{
    result = inflater.inflate(R.layout.numeric_question_list_item, null);
    vh.et  = (EditText)result.findViewById(R.id.question_et);
    vh.et.addTextChangedListener(new TextWatcher()
    {
        @Override
        public void afterTextChanged(Editable s) 
        {
            vh.tvValue = s.toString();
            holders[position] = vh;
            Log.i(TAG,"Entered afterTextChanged for "+ question.getText());
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start,int count, int after) 
        {   
        }

        @Override
        public void onTextChanged(CharSequence s, int start,int before, int count) 
        {
        }
    });
    vh.et.setText(vh.tvValue);
}
vh.tv = (TextView)result.findViewById(R.id.question_text);

vh.tv.setText(question.getText());

holders[position] = vh;
result.setTag(vh);
return result;
}

也许这可以帮助你:https://dev59.com/02oy5IYBdhLWcg3wF6QL?rq=1 - user2396641
你是如何解决第三个问题的?如果已经解决,请发布答案。 - desidigitalnomad
5个回答

19

问题 #3 的解决方案:

  1. 在列表视图中设置 descendantFocusablity="beforeDescendants"

  2. 在清单文件中设置 windowSoftInputMode="adjustPan"

  3. 调用 listview.setItemsCanFocus(true) 方法来设置列表项可获取焦点。


1
谢谢。1. android:descendantFocusability="afterDescendants"。2.编写输入文本的保存,如此处:https://dev59.com/02oy5IYBdhLWcg3wF6QL#19487574或这里:http://stackoverflow.com/a/21404201/2914140。 - CoolMind
运行良好。谢谢 :) - iffu

4
为了进一步解释aaRBiyecH的答案(如上所述),以下是您问题#1和#3的解决方案和更深入的解释(来源):
您需要将ListView的DescendantFocusability属性设置为“afterDescendants”。
您可以在XML中这样做: android:descendantFocusability="afterDescendants" 或者在代码中这样做: listview.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS) 您还需要设置项目可聚焦。
您可以在代码中这样做: listview.setItemsCanFocus(true);
此外,您需要指定当显示软键盘时您的活动的主窗口发生了什么。这是通过更改WindowSoftInputMode属性完成的。您可能希望将其设置为AdjustPan,以便您的listview不会被调整大小,从而不会再次调用GetView。当您隐藏键盘时,现在可能正在发生这种情况,GetView会再次被调用并重置EditText中的原始值。
您可以在主活动类的XML上使用属性android:windowSoftInputMode="adjustPan",或者使用编程方式getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_PAN)来完成此操作。

0

我有一个带有EditText的ListView,当我在其中输入文本时,如果在此之前滚动了ListView,则适配器会获取一些位置,而不是所选位置。

我的适配器获取各种位置,而不是我的选择位置:

etCantidad.addTextChangedListener(new TextWatcher() {
     @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
     @Override
     public void onTextChanged(CharSequence s, int start, int before, int count) {}

     @Override
     public void afterTextChanged(Editable s) {
         String cantidadTMP = etCantidad.getText().toString();
         int cantidad;
         try {
              cantidad = Integer.parseInt(cantidadTMP);
              item.setCantidad(cantidad);
              Log.i("Name",""+item.getNombre());
             }catch (Exception e){
                    cantidad = 0;
             }
         Log.i("QuantityArrayAdapter",String.valueOf(cantidad));
     }});

一个EditText选择:
09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1
09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1
09-25 09:22:10.458 12719-12719/? I/QuantityArrayAdapter: 1

所以,我将这个方法添加到onTouchListener中,只获取选择位置:
etCantidad.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            etCantidad.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
                }

                @Override
                public void afterTextChanged(Editable s) {
                    String cantidadTMP = etCantidad.getText().toString();
                    int cantidad;
                    try {
                        cantidad = Integer.parseInt(cantidadTMP);
                        item.setCantidad(cantidad);
                        Log.i("Name",""+item.getNombre());
                    }catch (Exception e){
                        cantidad = 0;
                    }
                    Log.i("QuantityArrayAdapter",String.valueOf(cantidad));
                }
            });
            return false;
        }
    });

只取我想要的那个项目,这样对我来说就行了。


0

1
谢谢,但是所有的答案都只是告诉你自己回收行,但它并没有解释如何有效地做到这一点,这正是我想知道的。你知道我可以在哪里找到类似的东西吗? - user2535545
https://dev59.com/02oy5IYBdhLWcg3wF6QL?rq=1 - user2396641
谢谢,我会看一下的。不过无论如何,我已经解决了,原来使用vh本地变量和holders数组有些多余,所以我尝试去掉所有这些多余的部分,它就正常工作了。 - user2535545

0

对我来说它正在工作... 请检查一下

listview.setItemsCanFocus(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接