ListView适配器的方法getView()在一个setAdapter之后为一个项加载数据多次

时间:2016-07-22 09:47:56

标签: java android listview

我的ListView适配器出了问题。

我使用的是ExpandableHeightListView或基本的Android ListView

ListViewAdapter上课:

public class ListViewNewsAdapter extends BaseAdapter {
    private Activity mActivity;
    private List<NewsModel> mNewsList;
    private String mPhotoUrl;

    public ListViewNewsAdapter(Activity activity, List<NewsModel> famous, String photoUrl) {
        mActivity = activity;
        mNewsList = famous;
        mPhotoUrl = photoUrl;
    }

    @Override
    public int getCount() {
        return mNewsList.size();
    }

    @Override
    public Object getItem(int position) {
        return mNewsList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            // if needed create own layout, `list_view_famous_news_single_item` is identical for now
            convertView = inflater.inflate(R.layout.list_view_famous_news_single_item, parent, false);
        }

        final NewsModel news = mNewsList.get(position);

        ViewHolder holder = new ViewHolder(convertView);

        // not always shows the date, was 'news.getPagemap().getMetatags().get(0).getArticlePublishedTime()', sometimes is 'getArticle()' returns null...
        holder.date.setText(news.getPagemap().getArticle().size() > 0 ? news.getPagemap().getArticle().get(0).getDatepublished() : news.getPagemap().getMetatags().get(0).getArticlePublishedTime());
        holder.title.setText(news.getTitle());
        holder.content.setText(news.getPagemap().getMetatags().get(0).getOgDescription());
        holder.source.setText(news.getDisplayLink());

        String photoUrl = news.getPagemap().getMetatags().get(0).getOgImage();

        loadFamousPicture(mActivity, holder.progressBar, holder.photo, news.getPagemap().getMetatags().get(0).getOgImage(), mPhotoUrl);

        convertView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Intent.ACTION_VIEW);
                i.setData(Uri.parse(news.getLink()));
                mActivity.startActivity(i);
            }
        });

        holder.publicityBanner.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showToast(mActivity, "publicityBanner");
            }
        });

        return convertView;
    }

    public void changeData (List<NewsModel> newsList) {
        mNewsList = newsList;
        notifyDataSetChanged();
    }

    public class ViewHolder {
        @BindView(R.id.dateTextView)
        TextView date;
        @BindView(R.id.titleTextView)
        TextView title;
        @BindView(R.id.contentTextView)
        TextView content;
        @BindView(R.id.sourceTextView)
        TextView source;
        @BindView(R.id.newsPhotoImageView)
        ImageView photo;

        @BindView(R.id.progressBar)
        ProgressBar progressBar;
        @BindView(R.id.publicityBanner)
        LinearLayout publicityBanner;

        public ViewHolder(View view) {
            ButterKnife.bind(this, view);
        }
    }
}

loadFamousProfile(...)方法:

public static void loadFamousPicture(final Activity activity,
                                     @Nullable final ProgressBar progressBar,
                                     final ImageView imageView,
                                     final String... photoUrls) {
    if(progressBar != null)
        progressBar.setVisibility(View.VISIBLE);

    Glide
        .with(activity)
        .load(photoUrls[0])
        .fallback(R.drawable.bg_gradient)
        .error(R.drawable.bg_gradient)
        .centerCrop()
        .crossFade()
        .listener(new RequestListener<String, GlideDrawable>() {
            @Override
            public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
                if (progressBar != null)
                    progressBar.setVisibility(View.GONE);

                // if there is another picture to load
                if (photoUrls.length > 1)
                    loadFamousPicture(activity, progressBar, imageView, Arrays.copyOfRange(photoUrls, 1, photoUrls.length));

                return false;
            }

            @Override
            public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                if (progressBar != null)
                    progressBar.setVisibility(View.GONE);
                return false;
            }
        })
        .diskCacheStrategy(DiskCacheStrategy.SOURCE)
        .into(imageView);
}

我的mNewsList里面有10个元素。我在:

中使用了断点
  • constructor:构造函数只调用一次 - 这当然是件好事

  • 与方法loadFamousPicture(...)一致:此方法应调用10次(因为mNewsList有10个元素),但它被称为13x10次(来自{{1的每个元素13个) }})我不知道为什么......

任何想法为什么会如此?

修改

mNewsList致电:

changeData()

private void listViewInit() { if (favoritesModelList.size() > 0) { noDataTextView.setVisibility(View.GONE); if (mIsListViewInited) { mAdapter.changeData(favoritesModelList); } else { mAdapter = new ListViewMyFavouritesAdapter(getActivity(), favoritesModelList); myFavouritesListView.setAdapter(mAdapter); mIsListViewInited = true; } } else { noDataTextView.setText(getString(R.string.favorites_no_data)); // TODO: which msg noDataTextView.setVisibility(View.VISIBLE); } } 正在调用listViewInit() RetrofitonResponse() ImageView

我在onClick()中设置了断点,它只被调用了一次(就像构造函数一样)......

1 个答案:

答案 0 :(得分:0)

尝试更改您的changeData方法,如下所示:

public void changeData (List<NewsModel> newsList) {
    if(mNewsList.size>0)
      mNewsList.clear();
    this.mNewsList.addAll(newsList);
    notifyDataSetChanged();
}

每次当你在onRespose(Retrofit)中的favoritesModelList中填充数据时,在该行上面只写下linew

if(favoritesModelList!=null && favoritesModelList.size()>0)
   favoritesModelList.clear();

写完上面的行后,在onResponse中填写你的favoritesModelList。