【问题标题】:ListViewAdapter - when listeners, attached to view are collected?ListViewAdapter - 何时收集附加到视图的侦听器?
【发布时间】:2013-04-26 18:44:54
【问题描述】:

我正在使用自定义 ListViewAdapter 来显示一个列表。 列表中的每一行都有 3 个按钮,即附加的侦听器。 但我发现它非常令人不安,在每次滚动期间,都会创建新的 OnClickListeners,即使对于存在 convertView 的那些行,也是非空值。

//据我了解,最常用的视图转换方法:

public View getView(int position, View convertView, ViewGroup parent) {
    View view = null;   
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.listview_item, parent, false);
    } else {
        view = convertView;
    }
    final TextView textView = (TextView) view.findViewById(R.id.txtProduct);
    textView.setText(name);
    textView.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            ...
        }
});
... two more listeners, with the same approach
return view;

根据我使用 Java 的经验,Spider-sense “ting-a-lings” - 似乎创建和丢弃相同的侦听器方法是垃圾收集器滥用。 我不确定老听众是什么时候被收集的,如果它有......

有没有办法使用旧的监听器,而不是创建一个新的监听器? (某种缓存数据结构)

【问题讨论】:

    标签: android performance android-listview garbage-collection


    【解决方案1】:

    您可以将您的列表适配器类设置为从View.OnClickListener 接口继承。然后,只需设置

    textView.setOnClickListener(this);
    

    并在您的适配器类的onClick 方法中处理点击。例如,要知道点击了哪一行,请在上面一行之前添加这一行:

    textView.setTag(position);
    

    然后,在onClick,你可以通过获取这个标签来知道你正在处理的列表中的哪个位置:

    public void onClick(View v) {
        Object item = myList.get((Integer) v.getTag());
        //handle click event
    }
    

    【讨论】:

    • 这样,一行就会变成一个可点击的监听器,convertView 也会复用监听器。美丽而优雅的解决方案 :) 但是,我正在寻找的是一行,有 3 个侦听器,每个侦听器的行为不同,因此 onClick 实现无法解决问题。
    猜你喜欢
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多