Listview ArrayAdapter 自定义项 onClickListener 仅第一次工作

Posted

技术标签:

【中文标题】Listview ArrayAdapter 自定义项 onClickListener 仅第一次工作【英文标题】:Listview ArrayAdapter custom item onClickListener working only first time 【发布时间】:2020-09-29 07:36:51 【问题描述】:

我有一个带有 ArrayAdapter 的 ListView,它显示新闻。在新闻之间有一些本地广告,我预先加载并显示在保留位置。但是,此视图中的 OnClickListener 仅在我第一次添加视图时才起作用 - 如果用户向下滚动过去然后返回,单击它时,什么也不会发生。

我该如何解决这个问题?

public class NewsListAdapter extends ArrayAdapter<Article> 

    private List<NativeAdNews> nativeAds;

    public void setData(List<Article> data) 
        dataset.clear();
        dataset.addAll(data);

        loadAdFromNetwork(() -> 
            LayoutInflater inflater = LayoutInflater.from(getContext());
            NativeAdNews nativeAdView = (NativeAdNews) inflater.inflate(R.layout.item_news_nativead, null);
            nativeAdView.setNativeAd(ad.getName(), ad.getWebsite());

            nativeAds.add(nativeAdView);

            Article a = new Article();
            a.setId("nativead" + (nativeAds.size() - 1));
            dataset.add(position, a);
        
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        Article article = dataset.get(position);

        if(article.getId().startsWith("nativead")) 
            int nativeAdPosition = Integer.parseInt(article.getId().replace("nativead", ""));
            NativeAdNews nativeAdView = nativeAds.get(nativeAdPosition);
            //nativeAdView.setClickListeners(); I tried manually re-setting the click listeners with no luck
            return nativeAdView;
         else 
            // reuse views
            View rowView = convertView;
            ...

            return rowView;
        
    


public class NativeAdNews extends FrameLayout 
    private TextView advertiserTextView;

    public void setNativeAd(String advertiserName, String advertiserWebsite) 
        advertiserTextView.setText(advertiserName + " (" + advertiserWebsite + ")");
        setClickListeners();
    

    public void setClickListeners() 
        advertiserTextView.setOnClickListener(v -> 
            Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com"));
            getContext().startActivity(i);
        );
    

    @Override
    public void onFinishInflate() 
        super.onFinishInflate();

        // setup ad
        imageView = findViewById(R.id.image_view);
        advertiserTextView = findViewById(R.id.advertiser);
        ...
    

【问题讨论】:

你在哪里声明了advertiserTextView 它是NativeAdNews 类的成员。以前我将其省略以使代码示例尽可能简短,但为了完整起见,我现在添加了它。 【参考方案1】:

也许你可以试试 ArrayAdapter 中的“ViewHolder”。

@Override
public View getView(int position, View convertView, ViewGroup parent) 

    // viewHolder
    View v = convertView;
    ViewHolder holder;
    if (v == null) 
        LayoutInflater inflater = LayoutInflater.from(getContext());
        v = inflater.inflate(R.layout.item_news_nativead, null);
        holder = new ViewHolder();
        holder.news = (NativeAdNews) v;
        v.setTag(holder)
     else 
        holder = (ViewHolder) v.getTag();
    
    holder.news.setClickListeners();
    return v;


public class ViewHolder 
     NativeAdNews news;

【讨论】:

以上是关于Listview ArrayAdapter 自定义项 onClickListener 仅第一次工作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ArrayAdapter 为 ListView 编写自定义过滤器

Android - ListView 中的 EditTexts 绑定到自定义 ArrayAdapter - 跟踪更改

ListView 中的自定义过滤 ArrayAdapter

TextView 在 ListView 内的自定义 ArrayAdapter 中被切断

在android中使用arrayadapter类自定义listview

使用android中的自定义arrayadapter在listview中使用复选框检查后如何删除多个项目?