【问题标题】:Android Listview Caching work unexpectedly on initializationAndroid Listview缓存在初始化时意外工作
【发布时间】:2012-10-17 14:01:47
【问题描述】:

我在 listview (a.k.a convertView) 中的视图缓存有点麻烦 这是我的代码,

private class CurrencyAdapter extends ArrayAdapter<CurrencyModel> {
    Context ctx;
    int layoutResourceId;
    List<CurrencyModel> adapter_models = null;

    public CurrencyAdapter(Context ctx, int layoutResourceId,
            List<CurrencyModel> model) {
        super(ctx, layoutResourceId, model);
        this.ctx = ctx;
        this.layoutResourceId = layoutResourceId;
        adapter_models = model;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        Log.d(Constants.APP_TAG, "position: " + position);
        View row = convertView;
        CurrencyAdapterContainer holder = null;
        if (row == null) {
            Log.d(Constants.APP_TAG, "APP NULL");
            row = ((Activity) ctx).getLayoutInflater().inflate(
                    layoutResourceId, parent, false);
            holder = new CurrencyAdapterContainer();
            holder.textView = (TextView) row
                    .findViewById(R.id.currencies_txt);
            holder.imgView = (ImageView) row
                    .findViewById(R.id.currencies_flag_icon);
            row.setTag(holder);

        } else {
            Log.d(Constants.APP_TAG, "APP NOT NULL");
            holder = (CurrencyAdapterContainer) row.getTag();
        }

        CurrencyModel curr = getItem(position);

        if (curr.currency_value == null) {
            if (counter < MAX_COUNTER) {
                ++counter;
                CurrencyJsonDownloader cDownloader = new CurrencyJsonDownloader(
                        curr, holder.textView);  //download currency value in background, and set textview text if currency_value has been loaded in onpostExcecute (i'm using AsyncTask)
                String url = CURRENCY_URL.replace("<symbol>", curr.symbol);
                Log.d(Constants.APP_TAG, "Url currency: " + url);
                cDownloader.execute(url);
            }
            holder.textView.setText("");
        } else {
            holder.textView.setText(curr.currency_value);
        }
        holder.imgView.setImageResource(curr.drawableId);

        return row;
    }

    @Override
    public CurrencyModel getItem(int position) {
        // TODO Auto-generated method stub
        return adapter_models.get(position);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return adapter_models.size();
    }
}

static class CurrencyAdapterContainer {
    ImageView imgView;
    TextView textView;
}

这是我的 logcat 中的输出

位置:0 APP为空

位置:1 APP 不为空

位置:2 APP 不为空

位置:3 APP 不为空

。 . .

位置:10 APP 不为空

这会造成灾难,因为这意味着在后台作业中传递的 textview 是相同的 textview 并且更改后的视图是相同的 textview 并且另一个 textview 将具有空白视图,除非我滚动它当然会再次调用getView() 一切都很好。但是在启动应用程序时会出现问题,因为只有一个 textview 总是在改变它的值。

那么为什么会这样呢?有什么我可以做的吗? 谢谢之前...

【问题讨论】:

    标签: java android listview caching


    【解决方案1】:

    ListView 项目视图被回收,因此永远不要持有对特定项目视图的引用并期望它在 ListView 滚动后表示相同的数据。

    将数据项传递给您的工作任务,并让它更新数据。

    更新:

    • 如果您当前的项目不在屏幕上,它将从适配器请求( 当 ListView 滚动到它时),并将显示更新的数据。
    • 如果当前正在显示该项目,请在适配器上调用notifyDataSetChanged(),这将使 ListView 刷新其显示的项目。

    【讨论】:

      【解决方案2】:

      我认为问题出在您的列表适配器上。在这里,我发布了一个适配器类,我认为它会对您有所帮助。

      public class UploadListAdaptor extends BaseAdapter {
      private Context context;
      private List<UploadDetailsObj> uploadList;
      
      public UploadListAdaptor(Context context, List<UploadDetailsObj> list) {
          this.context = context;
          uploadList = list;
      
      }
      
      public int getCount() {
          return uploadList.size();
      }
      
      public Object getItem(int position) {
          return uploadList.get(position);
      }
      
      public long getItemId(int position) {
          return position;
      }
      
      /** LIST CATEGORY */
      
      public View getView(int position, View convertView, ViewGroup viewGroup) {
      
          final UploadDetailsObj chlListObj = uploadList.get(position);
      
          if (convertView == null) {
      
              LayoutInflater inflater = (LayoutInflater) context
                      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
              convertView = inflater
                      .inflate(R.layout.inflator_progress_bar, null);
      
              TextView photoName = (TextView) convertView
                  .findViewById(R.id.tv_photoname);
      
              Button btnProgress=(Button)convertView.findViewById(R.id.btn_progress);
          photoName.setText(chlListObj.getPhotoName());
      
      
      
      
          }
      
      
          return convertView;
      
      }
      
         }
      

      您可以使用此代码调用此适配器。

       List<UploadDetailsObj> listofUploads= new ArrayList<UploadDetailsObj>();
       UploadListAdaptor uploadListAdptr = new UploadListAdaptor(yourclass.this,
                  listofUploads);
      
          uploadListView.setAdapter(uploadListAdptr);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-28
        • 2015-07-18
        • 1970-01-01
        • 1970-01-01
        • 2017-03-24
        相关资源
        最近更新 更多