2014-01-23 3 views
1

Iam, имеющего ViewHolder класс, как этотНеожиданное поведение от GetView() из CustomAdapter

static class ViewHolder { 
    protected String fileName; 
    protected Bitmap bitmap = null; 
    protected CheckBox checkBox; 
    protected int position; 
    protected int resourceId = 0; 
    protected ImageView imageView; 
    protected TextView textView; 
} 

и в пределах моих getView()

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    final ViewHolder viewHolder; 

    if(convertView != null) 
    { 
     ViewHolder holder = (ViewHolder) convertView.getTag(); 
     if(!holder.fileName.equals(fileList.get(position))) 
      convertView = null; 
    } 
    if(convertView == null) 
    { 
     convertView = inflater.inflate(R.layout.image_layout, null, false); 
     viewHolder = new ViewHolder(); 

     viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView); 
     viewHolder.textView = (TextView) convertView.findViewById(R.id.text); 

     // Set viewHolder attributes 
     viewHolder.position = position; 
     viewHolder.fileName = fileList.get(position);; 

     // set the checkbox 
     viewHolder.checkBox = (CheckBox) convertView.findViewById(R.id.checkBox); 

     // Set the path of the file 
     final String filePath = context.getBasePath(position); 

     if(new File(filePath).isDirectory()) 
     { 
      viewHolder.imageView.setImageResource(R.drawable.folder); 
      viewHolder.resourceId = R.drawable.folder; 
     } 
     else 
     { 
      String mimeType = Utility.getMimeType(filePath); 
      if(mimeType.contains("image")) 
      { 
       loadImage(viewHolder, viewHolder.imageView, filePath); 
      } 
      else 
       viewHolder.resourceId = handleFile(viewHolder.imageView, filePath); 
     } 
     convertView.setTag(viewHolder); 
    } 
    else 
    { 
     viewHolder = (ViewHolder) convertView.getTag(); 

     if(viewHolder.bitmap == null) 
      viewHolder.imageView.setImageResource(viewHolder.resourceId); 
     else 
      viewHolder.imageView.setImageBitmap(viewHolder.bitmap); 
    } 

    viewHolder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton checkBox, boolean checked) { 
      viewHolder.checkBox.setChecked(checked); 
      listener.onFileStateChanged(viewHolder.position, checked); 
     } 
    }); 

    // set the fileName 
    viewHolder.textView.setText(viewHolder.fileName); 

    if(checkBoxVisibility) 
     viewHolder.checkBox.setVisibility(View.VISIBLE); 
    else 
     viewHolder.checkBox.setVisibility(View.INVISIBLE); 

    return convertView; 
} 

И в это время, когда я обновить адаптер с помощью notifydatasetChanged() без изменения данные, ViewHolder, которые я получил по телефону getTag(), возвращали неправильные теги. Он работал как

Если позиция 1, объект держателя имел вид в позиции 0. ie; предыдущий объект был возвращен ..

Atlast Я нашел post

, который не является тем же самым, но с тем же способом, и решение работает для меня .. Я не знаю, как ..

Решение было

установки ширины ListView к MATCH_PARENT в XML, в посте это было height.

Знает ли кто-нибудь, в чем причина такого поведения? Не существует логики, которую я могу найти позади этой проблемы.

+0

Можете ли вы опубликовать свой код, который инициализирует 'ViewHolder'? – Asahi

+0

Я только что обновил весь код –

ответ

1

Кажется, что, когда вы не используете это обходное решение, Android должен несколько раз изменять размер списка в виде списка. Вот почему многие пользователи жалуются на то, что getView() называют больше раз, чем «должно».

В любом случае, будьте уверены, что getView() не называется последовательно, он вызывается в том порядке, который определяет Android, поэтому не ожидайте, что будут показаны теги по порядку.

--- EDIT ---

И here comes the confirmation, страница 48. Надеюсь, что это помогает!

+0

Но его шоу, когда его матч родитель? –

+0

Я не знаю точного объяснения этого, но я предполагаю, что когда ширина установлена ​​на 'MATCH_PARENT' (как это и должно быть), Android уже правильно оформлен, поэтому он называется последовательно, потому что Android видит каждую строку одинаково «трудно». С другой стороны, если для параметра «WRAP_CONTENT» установлено значение «WRAP_CONTENT», каждая строка должна отображаться на определенном макете, а Android обрабатывает 'getView()', как только она отображает каждую строку, а это означает, что каждая из них не обязательно должен быть равен рендерингу, поэтому он не является последовательным. – nKn

+1

Спасибо за попытку помочь мне и объяснить, что вы знаете, может быть, но я ищу какое-то точное решение, потому что это то, что мы обычно работаем над каждой программой. Поэтому я не хочу делать это без знания. –

Смежные вопросы