android – 在getView将其膨胀两次后更新第一个gridview元素

我正在视图持有者/适配器模式之后创建“文档”的网格视图.在活动中,我从网络类中获得回调,因此我需要能够在不同的时间更新每个网格单元.

我这样做的方法是通过从对象元素(文档)到相应的视图持有者的映射映射.我需要这样做,因为适配器正在循环使用单元格,所以有时我可以收到一个回调来更新一个不可见的单元格,在这种情况下,回调信息将被忽略.

我可以看到适配器的getView方法被多次调用为位置0.我一直在读这是正常的.

inflating position 0  ***  progressBar 1
recycling position 0
recycling position 0
inflating position 0  ***  progressBar 2
recycling position 0
recycling position 0
recycling position 0
recycling position 0
recycling position 0
recycling position 0

我需要从回调中更新的一个UI元素是一个进度条,我通过将viewHolder添加到与文档关联的Map来跟踪.

除了第一个方法之外,这整个方法适用于所有位置.我可以识别的唯一区别是这些多次调用getView所以我从那里开始调试.我正在更新的progressBar是“progressBar 2”,这是geView膨胀的最新版本,但实际上它并没有响应setVisible(View.VISIBLE).然后我对代码进行了一些更改以更新“progressBar 1”并且它可以工作.

这意味着getView在同一位置膨胀两次,但第二次没有被使用或显示.

我能做错什么?为什么progressbar1工作而progressbar2没有?我希望getView会给我一个与位置相对应的最新视图.

谢谢.

适配器:

public class DocumentPickerGridViewAdapter extends ArrayAdapter<Document> implements Filterable {
  private final DocumentPickerGridViewController picker;
  private ArrayList values;
  private ArrayList filtered;
  private LayoutInflater inflater;

  public DocumentPickerGridViewAdapter(Context context,ArrayList values) {
    super(context,R.id.documentPickerGridView,values);
    this.picker = (DocumentPickerGridViewController) context;
    this.filtered = values;
    this.values = (ArrayList)values.clone();
    inflater = (LayoutInflater) picker.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  }

  @Override
  public View getView(int position,View convertView,ViewGroup parent) {
    View v = convertView;
    ViewHolder oldHolder;
    ViewHolder holder;
    Document doc = (Document) filtered.get(position);

    if (v == null) {
      v = inflater.inflate(R.layout.documentpickergriditem,parent,false);

      holder = new ViewHolder();
      holder.actionView = (Button) v.findViewById(R.id.document_action_button);
      holder.coverView = (ImageView) v.findViewById(R.id.documentCoverImage);
      holder.archiveButton = (Button) v.findViewById(R.id.document_archive_button);
      holder.progressView = (ProgressView) v.findViewById(R.id.documentProgress);
      holder.progressBar = (ProgressBar) v.findViewById(R.id.documentCoverImageProgressBar);


      picker.allProgressViews.add(holder);
      Log.d("MARIANO","adding to allProgressViews "+holder.progressView);
      Log.d("MARIANO","inflating position "+position);

      v.setTag(holder);
    }
    else{
      // here we are recycling,we should clean old stuff.
      holder = (ViewHolder)v.getTag();



      synchronized (picker){
        oldHolder = picker.documentHoldersMap.get(holder.doc);
      }

      if(oldHolder != null){
        oldHolder.progressView.setVisibility(View.GONE);
        oldHolder.progressBar.setVisibility(View.GONE);
      }

      // Document associated with prevIoUs holder it's Now out of the adapter visible window.
      // we have to remove it from the map so if picker receives any call back we won't update anything.
      if(! holder.doc.uuid().equals(doc)){
        synchronized (picker){
          picker.documentHoldersMap.remove(holder.doc);
        }
      }
    }

    holder.doc = doc;
    holder.position = position;
    synchronized (picker){
      picker.documentHoldersMap.put(doc,holder);
    }

    /*
       Todo: check why view extendedGrid starts to measure the size of the grid after gridpicker view has disapear. This causes a ArrayOutofIndexes
       exception. DocumentGridPicker view does setDocuments(null); which clears all arrays,but the adapter stays setting as many cells as before.
       https://kaldorgroup.jira.com/browse/NEWSWEEK-49
    */
    if(picker.documents() != null && picker.documents().size() > 0 ){
      picker.setCoverView(holder.coverView,doc);
      picker.setActionButton(holder.actionView,doc);
      picker.setArchiveButton(holder.archiveButton,doc);
      picker.refreshButton(doc);
    }

    TextView textView = (TextView) v.findViewById(R.id.documentName);
    textView.setText(doc.name());

    if(position == 0)
      Log.d("MARIANO","progressView: "+holder.progressView);

    return v;
  }

  @Override
  public Filter getFilter() {
    return new Filter() {
      @Override
      protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults result = new FilterResults();

        if (constraint.equals(DocumentPickerGridViewController.FILTER_DOWNLOADED)) {
          ArrayList items = new ArrayList();

          synchronized (this) {
            items.addAll(values);
          }

          for (int i = items.size() - 1; i >= 0; i--) {
            if (((Document) items.get(i)).state() != DocumentStates.Downloaded)
              items.remove(i);
          }

          result.count = items.size();
          result.values = items;
        } else {  // ALL ITEMS
          synchronized (this) {
            result.count = values.size();
            result.values = values;
          }
        }
        return result;
      }

      @SuppressWarnings("unchecked")
      @Override
      protected void publishResults(CharSequence constraint,FilterResults results) {
        filtered = (ArrayList)results.values;
        DocumentPickerGridViewAdapter.this.notifyDataSetChanged();
        clear();
        for(int i = 0,l = filtered.size(); i < l; i++)
          add((Document)filtered.get(i));
        notifyDataSetInvalidated();
      }
    };
  }

  static class ViewHolder{
    ImageView coverView;
    Button actionView;
    Button archiveButton;
    ProgressView progressView;
    ProgressBar progressBar;
    int position;
    Document doc;
  }

}

网格视图 :

<com.kaldorgroup.newsweek.ExpandableGridView
                    android:id="@+id/documentPickerGridView"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:columnWidth="150dp"
                    android:numColumns="auto_fit"
                    android:horizontalSpacing="25dp"
                    android:stretchMode="spacingWidth"
                    android:verticalSpacing="20dp"
                    android:layout_marginTop="10dp"
                    android:layout_marginBottom="5dp"
                    android:layout_marginLeft="15dp"
                    android:layout_marginRight="15dp"
                    android:isScrollContainer="false"
                    android:paddingTop="350dp" />

解决方法

我在GridView中遇到了完全相同的问题.在单击列表的第一项时,它不会刷新.我只是改变了代码
public View getView(int position,ViewGroup parent)
 {
    View v = convertView;
    if (convertView == null) 
    { 
        LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.calendar_item,null);
    }
    .......
 }

     to 

    public View getView(int position,ViewGroup parent)
    {
        View v = convertView;
     //   if (convertView == null) 
     //   { 
            LayoutInflater vi = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.calendar_item,null);
     //   }
        .......
    }

It is working fine to me.. But I don't have idea how it happens...
Any Clarification on this will be more helpful!!

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...