我创建了一个自定义列表视图布局,其中包含从Web加载的图像,如下所示:
http://i.stack.imgur.com/l8ZOc.png
向下滚动时工作正常.但是,当您向下滚动时,之前的项目将从屏幕中移出然后销毁.当你再次尝试向上滚动时,它会再次被加载(从缓存,更快但不是即时),这会导致延迟并且它不应该流畅.
1.有一个如何正确做到这一点的例子吗?
2.有没有办法防止列表视图项目在屏幕外被销毁?
3.如果是这样,是否会因为保留太多物品而导致问题?
贝娄是我的代码:
MenuAdapter:
public class MenuAdapter extends BaseAdapter{ Context context; List<MyMenuItem> menuItems; MenuAdapter(Context context, List<MyMenuItem> menuItems) { this.context = context; this.menuItems = menuItems; } @OverrIDe public int getCount() { return menuItems.size(); } @OverrIDe public Object getItem(int position) { return menuItems.get(position); } @OverrIDe public long getItemID(int position) { return menuItems.indexOf(getItem(position)); } private class VIEwHolder { ImageVIEw ivMenu; TextVIEw tvMenuheader; } @OverrIDe public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) { VIEwHolder holder = null; LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); if (convertVIEw == null) { convertVIEw = mInflater.inflate(R.layout.menu_item, null); holder = new VIEwHolder(); holder.tvMenuheader = (TextVIEw) convertVIEw.findVIEwByID(R.ID.tvMenuheader); holder.ivMenu = (ImageVIEw) convertVIEw.findVIEwByID(R.ID.ivMenuItem); convertVIEw.setTag(holder); } else { holder = (VIEwHolder) convertVIEw.getTag(); } MyMenuItem row_pos = menuItems.get(position); Picasso.with(context) .load(row_pos.getItem_image_url()) .into(holder.ivMenu); holder.tvMenuheader.setText(row_pos.getItem_header()); Log.e("Test", "headers:" + row_pos.getItem_header()); return convertVIEw; }}
MyMenuItem:
public class MyMenuItem { private String item_header; private String item_image_url; public MyMenuItem(String item_header, String item_image_url){ this.item_header=item_header; this.item_image_url=item_image_url; } public String getItem_header(){ return item_header; } public voID setItem_header(String item_header){ this.item_header=item_header; } public String getItem_image_url(){ return item_image_url; } public voID setItem_image_url(String item_image_url){ this.item_image_url=item_image_url; }}
主要活动:
public class MyActivity extends Activity implements AdapterVIEw.OnItemClickListener { List<MyMenuItem> menuItems; ListVIEw myListVIEw; JsONArray JsonArray; @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_my); Bundle extras = getIntent().getExtras(); if(extras!=null){ try{ JsonArray = new JsONArray(extras.getString("Data")); }catch (Exception e){ e.printstacktrace(); } } menuItems = new ArrayList<MyMenuItem>(); for (int i = 0; i < JsonArray.length(); i++) { try { MyMenuItem item = new MyMenuItem(JsonArray.getJsONObject(i).getString("Title"), JsonArray.getJsONObject(i).getString("imageURL")); menuItems.add(item); }catch (Exception e){ e.printstacktrace(); } } myListVIEw = (ListVIEw) findVIEwByID(R.ID.List); MenuAdapter adapter = new MenuAdapter(this, menuItems); myListVIEw.setAdapter(adapter); myListVIEw.setonItemClickListener(this); }}
MenuItem.xml:
<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <ImageVIEw androID:ID="@+ID/ivMenuItem" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:scaleType="center" androID:src="@drawable/em" /> <TextVIEw androID:ID="@+ID/tvMenuheader" androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:background="#55000000" androID:paddingBottom="15dp" androID:paddingleft="10dp" androID:paddingRight="10dp" androID:paddingtop="15dp" androID:textcolor="@androID:color/white" androID:layout_gravity="left|top" androID:layout_alignBottom="@+ID/ivMenuItem" androID:layout_alignParentleft="true" androID:layout_alignParentStart="true" androID:layout_alignParentRight="true" androID:layout_alignParentEnd="true" /></relativeLayout>
解决方法:
1.有没有一个如何正确做到这一点的例子?
您的代码看起来非常接近完美. Adapter的getVIEw方法通常是优化的关键途径.比较毕加索自己的例子SampleListDetailAdapter.java.重要的一点(以及你的代码)
>检查&重新使用已经膨胀的观点,通货膨胀是昂贵的.
>使用VIEwHolder,这样您就不必每次都调用findVIEwByID.在简单的视图上并不是非常昂贵.也缓存了afaik.
> Picasso.with(context).load(url)…每次需要显示图像时.这应该立即完成,但仍然使用缓存和其他魔法.
您可以添加一些小的优化,但我怀疑有明显的甚至可衡量的变化:
纯样式更改:使用BaseAdapter#getItem(position).这种方法
只为你而存在.框架不使用它.
@OverrIDe public MyMenuItem getItem(int position) { // << subclasses can use subtypes in overrIDden methods! return menuItems.get(position); } @OverrIDe public VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) { ... MyMenuItem row_pos = getItem(position);
使用理智的ID方法
@OverrIDepublic long getItemID(int position) { return menuItems.indexOf(getItem(position));}
相当于
@OverrIDepublic long getItemID(int position) { return position;}
但现在无限快. indexOf(Object)与对象数量的关系非常严重.
缓存不更改的对象:
MenuAdapter(Context context, List<MyMenuItem> menuItems) { this.mLayoutInflater = LayoutInflater.from(content); this.mPicasso = Picasso.with(context);}..@OverrIDepublic VIEw getVIEw(int position, VIEw convertVIEw, VIEwGroup parent) { if (convertVIEw == null) { convertVIEw = mInflater.inflate(R.layout.menu_item, null); ... mPicasso .load(row_pos.getItem_image_url()) .into(holder.ivMenu);
2.有没有办法阻止列表视图项目在屏幕外被销毁?
没有(*).
..(*)你可以基本上缓存getVIEw的结果,例如在LruCache(位置,视图)或LruCache(MyMenuItem,VIEw)中,然后不要触摸convertVIEw – 它们需要保持未转换状态,否则您将在缓存中终止这些视图.也
@OverrIDepublic int getItemVIEwType(int position) { return Adapter.IGnorE_ITEM_VIEW_TYPE;}
似乎是必需的,因为使用代码的标准适配器假定它从可见性中删除的视图消失了.他们不是和他们搞乱你的缓存混乱,并为我造成了奇怪的显示问题.
3.如果是这样,是否会因为保留太多物品而导致问题?
是.此行为不是意图/预期.你或多或少都没有获得.您可以保存对holder.tvMenuheader.setText()的调用.同样是毕加索的一个,但他们两个都应该立即完成.毕加索应该已经缓存了你的图像.通过缓存所有视图,您实际上添加了另一个包含所有图像的缓存.我宁愿检查毕加索缓存是否按预期工作并保存大部分项目.您可能希望使用视图缓存执行此 *** 作的唯一原因是需要复杂设置视图的情况,因此值得缓存完全构造的视图而不仅仅是某些内容部分.
轮廓
分析实际上可以告诉您可以/需要/应该改进的地方.第一个看IMO的是tracevIEw.您将看到代码是否阻止主线程导致乱序列表滚动.如果您正在执行复杂的视图,并且您发现绘制方法大多数时间都在执行,那么也要对它们进行概要分析.
> http://www.curious-creature.org/docs/android-performance-case-study-1.html
> http://blog.venmo.com/hf2t3h4x98p5e13z82pl8j66ngcmry/performance-tuning-on-android
> http://www.vogella.com/tutorials/AndroidTools/article.html
以上是内存溢出为你收集整理的如何使用Picasso库正确实现带图像的自定义列表视图?全部内容,希望文章能够帮你解决如何使用Picasso库正确实现带图像的自定义列表视图?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)