列表视图中的项目似乎是随机的

时间:2012-06-22 14:43:17

标签: android listview

我在每个项目中创建了一个带有TextView和EditText的列表。 为了填充正确的值,我定义了几个“dataType”。例如,如果我们需要输入日期,我会显示日期选择器并在EditText中填充返回值,对于NumericID,我将numPad定义为软键盘。

我有一个数据ArrayList,对于每个项目,我都有这样的信息:textView的字符串,dataType和EditText的字符串。

我有两个问题,我认为它们是相关的。

首先,我的数据列表的大小只有10,所以我的列表中有10个项目。但是当创建列表时,getView()被调用超过20次,并且每次软键盘显示/隐藏时,此函数将被调用所有“位置”。好像有线,不是吗?

第二个是当我用arrayAdapter生成我的列表时,我的textViews似乎很好,但是EditTexts看起来很随机:在我的数据列表中,我有“ContactName” - “UserName” - “Jane”和“CreateDate” - “日期” - “12/02/12”等。创建列表后,一切都很好。但是当我滚动我的列表,或者我显示然后隐藏键盘,我的EditTexts与我的TextView不匹配,ContactName的editText可能是日期类型......

这是我的代码:     setListAdapter(new ArrayAdapter(this,R.layout.itemview,datalist){

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view= convertView;
            DataHolder data = getItem(position);
            final ViewHolder vholder ;
            if (null == view) {
                LayoutInflater mInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = mInflater.inflate(R.layout.itemview, null);
                vholder = new ViewHolder();
                vholder.fieldName = (TextView) view.findViewById(R.id.fieldName);
                vholder.fieldValue = (EditText) view.findViewById(R.id.fieldValue);

                vholder.fieldValue.setHint(data.detail.getFieldType().getFieldTypeName());
                // here I define some properties of the EditText, or I show a date picker then I put the 
                // result in the EditText
                vholder.fieldValue = (EditText) data.detail.getFieldType().getValue(vholder.fieldValue);
                view.setTag(vholder);
                Log.d("convertView is null?", "null "+position);
            } 
            else{
                vholder = (ViewHolder) view.getTag();
                Log.d("convertView is null?", "not null "+position);
            } 

            if(data != null){
                vholder.fieldName.setText(data.name);
                if(vholder.fieldValue == null){
                    Log.i(vholder.fieldName.getText()+" null", "data type is: "+data.detail.getFieldType().getFieldTypeName().toString());          
                }else{ 
                    String fieldValueContent = data.value;
                    if(!fieldValueContent.isEmpty())
                        vholder.fieldValue.setText(fieldValueContent);   
                    // update data if focus changes
                    final String fieldValueText = vholder.fieldValue.getText().toString();
                    vholder.fieldValue.setOnFocusChangeListener(new View.OnFocusChangeListener() {            
                        public void onFocusChange(View v, boolean hasFocus) {           
                            if((fieldValueText!=null)&&(!fieldValueText.isEmpty())){
                                // some update data instructions 
                            }
                        }  
                    }); 
                }
            }

            return view;
        }
    });
    public class DataHolder{
    public FieldDetails detail;
    public String value;
    public String name;
}
public class ViewHolder{
    public TextView fieldName;
    public EditText fieldValue;
}

public class UserName implements FieldType{
@Override
public View getValue(View input) {
    ((EditText) input).setInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME);
    return input;
}
}

2 个答案:

答案 0 :(得分:0)

First one, my data list's size is only 10, so I've 10 items in my list. But getView() is called more than 20 times when the list's created 

根据link

这不是问题,绝对不能保证调用getView()的顺序也不能保证多少次。 In your particular case you are doing the worst thing possible with a ListView by giving it a height=wrap_content. This forces ListView to measure a few children out of the adapter at layout time, to know how big it should be.这就是为ListView提供您在滚动之前传递给getView()的convertViews。

Focusable EditText inside ListView

答案 1 :(得分:0)

First one, my data list's size is only 10, so I've 10 items in my list. But getView() is called more than 20 times 

列表视图第一次创建仅供设备占用的视图(行),如果滚动列表视图,它将检查是否更改了视图类型,如果是这样它将创建新视图,否则它将重新使用您的视图只需更换您的数据..

Working of getView()

此外,如果您将列表视图高度指定为 wrap_content ,则仅将显示前三个视图(行),其余将被忽略 ..

EditText中的问题可能是由于你的if else阻止..请正确检查..你的检查

if(data=null){
  vholder.fieldName.setText(data.name);
}else{
   showing Edit Text // Check it properly
}