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

时间:2014-10-13 05:43:57

标签: java android android-listview

在我的ImageAdapter(扩展BaseAdapter)中,每个View都是我称为ImageTapView的自定义视图。它是一个单独的类,它使用以RelativeLayout开头的自己的布局文件扩展<merge>。此类包含所有点击侦听器,每个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每次调用ImageTapView时都会创建一个新的getView,而不是仅仅替换已经膨胀的视图中的数据。我认为更难以进入并替换每个字段并重置getView上的动画,更不用说,我希望用户看到他们与{{1}交互的位置他们离开(例如放大图像或动画中间)。

我尝试将每个视图保存到名为ImageTapView的{​​{1}}:

HashMap

但是我得到了一些非常奇怪的行为。例如,在3个交互步骤(开始状态,缩放状态,信息叠加显示状态)的第2步中的views,事情变得非常奇怪。他们似乎没有从他们中断的地方回来,他们不会以新的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函数中是相同的?

提前致谢!

2 个答案:

答案 0 :(得分:1)

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

 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 :(得分:0)

请尝试这种方式,希望这有助于您解决问题。

  1. 适配器的自定义项目布局。
  2. <强> 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
      

      }