【问题标题】:How to implement a view holder?如何实现视图持有者?
【发布时间】:2011-05-07 22:22:58
【问题描述】:

我正在使用查看器从动态数组适配器显示。它可以工作,但是当我滚动列表时显示的数据会不规则地变化。我希望我的列表视图只填充一次,而不是一直当我滚动我的列表时。有什么建议吗? 这是我的代码

public View getView(int position, View convertView, ViewGroup parent) {            

   // A ViewHolder keeps references to children views to avoid unneccessary calls            
   // to findViewById() on each row.            
   ViewHolder holder;            
   // When convertView is not null, we can reuse it directly, there is no need            
   // to reinflate it. We only inflate a new View when the convertView supplied            
   // by ListView is null.            

   if (convertView == null) {                

    convertView = mInflater.inflate(R.layout.sample, null);   
    // Creates a ViewHolder and store references to the two children views                
    // we want to bind data to.               
    holder = new ViewHolder();                
    holder.name = (TextView) convertView.findViewById(R.id.text);               
    holder.icon = (ImageView) convertView.findViewById(R.id.icon);                
    convertView.setTag(holder);            
   } else {                
    // Get the ViewHolder back to get fast access to the TextView                
    // and the ImageView.


    holder = (ViewHolder) convertView.getTag();

   }            


   // Bind the data efficiently with the holder. 
   if(_first==true)
   {
   if(id<myElements.size())
   {
      holder.name.setText(myElements.get(id)); 
   holder.icon.setImageBitmap( mIcon1 );
   id++;
   }
   else
   {
    _first=false;
   }
   }
    //holder.icon.setImageBitmap(mIcon2);
   /*try{
    if(id<myElements.size())
     id++;
     else
     {
      id--;
     } 
   }
   catch(Exception e)
   {
    android.util.Log.i("callRestService",e.getMessage());
   }*/



   return convertView;

  }        
static class ViewHolder {            
 TextView name;            
 ImageView icon;        
}  

加载列表时,它看起来像这样:http://i.stack.imgur.com/NrGhR.png 在滚动一些数据后http://i.stack.imgur.com/sMbAD.png 它看起来像这样,如果我滚动到开头,它看起来又是http://i.stack.imgur.com/0KjMa.png

P.S : 我的列表必须按字母顺序排列

【问题讨论】:

  • 你能把你的输出截图贴出来吗?
  • @Tilsan The Fighter:已经发布了快照。

标签: android listview view


【解决方案1】:

你试过了吗?

public View getView(int position, View convertView, ViewGroup parent) {            

   // A ViewHolder keeps references to children views to avoid unneccessary calls            
   // to findViewById() on each row.            
   ViewHolder holder;            
   // When convertView is not null, we can reuse it directly, there is no need            
   // to reinflate it. We only inflate a new View when the convertView supplied            
   // by ListView is null.            

   if (convertView == null) {                

    convertView = mInflater.inflate(R.layout.sample, null);   
    // Creates a ViewHolder and store references to the two children views                
    // we want to bind data to.               
    holder = new ViewHolder();                
    holder.name = (TextView) convertView.findViewById(R.id.text);               
    holder.icon = (ImageView) convertView.findViewById(R.id.icon);                
    convertView.setTag(holder);            
   } else {                
    // Get the ViewHolder back to get fast access to the TextView                
    // and the ImageView.


    holder = (ViewHolder) convertView.getTag();

   }            


   // Bind the data efficiently with the holder. 
   holder.name.setText(myElements.get(id)); 
   holder.icon.setImageBitmap( mIcon1 );

   return convertView;
  }  

static class ViewHolder {            
    TextView name;            
    ImageView icon;        
} 

如果是,有什么问题?

我认为一次加载所有行并不是一个好主意。您最终将在内存中拥有大量无用的视图,这些视图将毫无意义地减慢应用程序的速度。 视图和视图上的操作(如 inflate、findViewById、getChild..)很昂贵,您应该尽可能地重用它们。这就是我们使用 ViewHolders 的原因。

【讨论】:

  • 是的!我试过了。当我滚动到最后一个元素(> 92)时,它无法在列表视图中加载元素! myElement 是在 id 的帮助下的 arrayList,我让每个元素都显示在文本视图中。是的,我似乎只加载了一次所有数据,但我不知道如何重用它,你能帮忙吗
【解决方案2】:

您需要编写自己的ListView 版本才能做到这一点(这很糟糕)。如果ListView 不能正常工作,这可能意味着你做错了什么。

id 元素从何而来?您将在 getView() 方法中获得该位置,因此您无需担心超出列表范围。该位置链接到列表中的元素位置,因此您可以像这样获得正确的元素:

myElements.get(position);

当列表中的数据发生变化时,可以这样调用:

yourAdapter.notifyDataSetChanged()

这将使用新数据重建您的列表(同时保持滚动和其他内容)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多