如何在ListView适配器中缓存自定义视图



在我的ImageAdapter(扩展BaseAdapter)中,每个View都是一个自定义视图,我称之为ImageTapView。它是一个单独的类,用自己的以<merge>开头的布局文件扩展RelativeLayout。这个类包含所有的点击监听器,每个ImageTapView从互联网下载和显示的图像的加载器,以及点击时发生的动画。

这是我的ImageAdapter构造函数:

public class ImageAdapter extends BaseAdapter {
    private Context context;
    private JSONArray posts;
    private String baseUrl;
    private HashMap views = new HashMap();
    public ImageAdapter(Context _context, JSONArray _posts, String _baseUrl){
        context = _context;
        posts = _posts;
        baseUrl = _baseUrl;            
    }
    ...etc
}

在我的ImageAdapter.getView中,如果我执行以下操作,一切都会正常工作:

public View getView(int position, View convertView, ViewGroup parent){
    // create new imageTapView
    JSONObject thisPost = posts.getJSONObject(position);
    convertView = new ImageTapView(context, thisPost);
    return convertView;
}

但这意味着Android每次调用getView时都会创建一个新的ImageTapView,而不仅仅是替换已经膨胀的视图中的数据。我认为进入并替换getView上的每个字段和重置动画会更加困难,更不用说,我希望用户看到他们在与ImageTapView的交互中停止的地方(例如,放大图像或动画中间)。

我尝试将每个视图保存到一个名为views:的HashMap

public View getView(int position, View convertView, ViewGroup parent){
    if(views.containsKey(position)) return (ImageTapView) views.get(position);
    // create new imageTapView
    JSONObject thisPost = posts.getJSONObject(position);
    convertView = new ImageTapView(context, thisPost);
    views.put(position, convertView);
    return convertView;
}

但我有一些非常奇怪的行为。ImageTapViews在交互的三个步骤中的第二步(开始状态、缩放状态、信息叠加显示状态),事情变得非常奇怪。它们似乎没有从停止的地方恢复,也没有像新的ImageTapView那样对点击做出正确的反应。

那么,在ListView中是否有缓存对象或自定义对象的标准方法?我应该改为扩展ArrayAdapter,还是我的问题在getView函数中相同?

提前感谢!

试试这个,你需要创建额外的方法setPost()来设置post

 public View getView(int position, View convertView, ViewGroup parent){
      // create new imageTapView
      JSONObject thisPost = posts.getJSONObject(position);
      if(convertView==null)
            convertView = new ImageTapView(context, thisPost);
      else{
      ((ImageTapView)convertView).setPost(thisPost); 
      }
     return convertView;
 }

试试这种方法,希望这能帮助你解决问题

  1. 适配器的自定义项布局

row.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <packageName.ImageTapView>
        android:id="@+id/imageTapView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    </packageName.ImageTapView>
</LinearLayout>
  1. 在适配器中展开自定义行布局。

    公共类ImageAdapter扩展BaseAdapter{

    private Context context;
    private JSONArray posts;
    private String baseUrl;
    private HashMap views = new HashMap();
    public ImageAdapter(Context _context, JSONArray _posts, String _baseUrl){
        context = _context;
        posts = _posts;
        baseUrl = _baseUrl;
    }
    static class ViewHolder
    {
        ImageTapView imageTapView;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(_context).inflate(R.layout.row, null);
            viewHolder.imageTapView = (ImageTapView) convertView.findViewById(R.id.imageTapView);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.imageTapView.setPost(posts.getJSONObject(position));
        return convertView;
    }
    ...etc
    

    }

最新更新