[CymChad/BaseRecyclerViewAdapterHelper]优化建议

2024-08-08 181 views
1

BaseViewHolder类中的: public BaseViewHolder addOnClickListener(final int viewId) { childClickViewIds.add(viewId); final View view = getView(viewId); if (view != null) { if (!view.isClickable()) { view.setClickable(true); } // view.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // if (adapter.getOnItemChildClickListener() != null) { // adapter.getOnItemChildClickListener().onItemChildClick(adapter, v, getClickPosition()); // } // } // }); view.setOnClickListener(childViewsOnClickListener); }

    return this;
}

凡是这些new 出监听者的地方,都可以只写一个监听者对象,这样减少构建对象

回答

1

position 会有错乱问题,你可以尝试一下,如果没有问题,提个pr来看看

1

@tysheng position通过BaseViewHolder里的方法getClickPosition()获取,如果有错乱问题的话,在方法内new 监听者也会出现Posion错乱问题,想了一番,应该不会出现错乱问题

6

在内部可以,你可以把代码在这贴一下

5
public BaseViewHolder setChildViewOnClickListener(int... childViewIds) {
    if (childViewIds != null && childViewIds.length > 0) {
        for (int oneViewId : childViewIds) {
            if (oneViewId <= 0) {
                continue;
            }
            childClickViewIds.add(oneViewId);
            View view = getView(oneViewId);
            if (view != null) {
                view.setOnClickListener(forItemChildViewClickListener);
            }
        }
    }
    return this;
}
private View.OnClickListener forItemChildViewClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if (adapter != null) {
            if (adapter.getOnItemChildClickListener() != null) {
                adapter.getOnItemChildClickListener().onItemChildClick(adapter, v, getClickPosition());
            }
        }
    }
};
public BaseViewHolder setChildViewOnLongClickListener(int... childViewIds) {
    if (childViewIds != null && childViewIds.length > 0) {
        for (int oneViewId : childViewIds) {
            if (oneViewId <= 0) {
                continue;
            }
            itemChildLongClickViewIds.add(oneViewId);
            View view = getView(oneViewId);
            if (view != null) {
                view.setOnLongClickListener(forItemChildViewLongClickListener);
            }
        }
    }
    return this;
}
private View.OnLongClickListener forItemChildViewLongClickListener = new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        if (adapter != null && adapter.getOnItemChildLongClickListener() != null) {
            return adapter.getOnItemChildLongClickListener().onItemChildLongClick(adapter,v,getClickPosition());
        }
        return false;
    }
};
1

getClickPosition() 这个函数呢?

9

@tysheng 在这呢:return adapter.getOnItemChildLongClickListener().onItemChildLongClick(adapter,v,getClickPosition());

1

if (!view.isClickable()) { view.setClickable(true); } 这段应该也不需要, 系统有相关判断

5

@feer921 你holder怎么传?能不能运行起来

9

在这关于点击监听器 顺便问一下 在普通的recyclerview里面 为item的view或者item内部的控件设置点击监听器, 标准的添加监听器应该是在 viewholder的构造方法里面吧, 也就是创建viewholder的view的时候, 因为viewholde的view是复用的,例如一共创建了6个viewholder的对象,如果为view添加点击监听器,也应该是创建6个监听器对象, 具体区分点击哪条item是通过viewholder实例调用getlayoutposition方法获取到position 而由于onBindViewHolder方法是每一次填装数据的时候都会调用,不应该在此方法中设置监听器,否则就会导致每一次循环填装数据,都会无限制创建监听器对象 看了BaseQuickAdapter的应用案例,案例中为控件和item视图添加点击监听器是在adapter的convert方法里面进行的,而convert方法对应着onBindViewHolder方法,从案例中ItemClickAdapter代码来看,每一次循环填装数据都会创建新的监听器对象 应该在哪里为item的view设置监听器呢?

8

@NastasyaObertas 你说的没错,onBindViewHolder中会多创建监听,所以我们在设置item的点击事件就是在onCreateViewHolder里面设置的,而item的子view的话,无法做到在onCreateViewHolder里面添加,因为你还不知道它有哪些view需要添加点击事件,而item的话肯定是itemview添加,这个是提前知道的。