CymChad / BaseRecyclerViewAdapterHelper

BRVAH:Powerful and flexible RecyclerAdapter
http://www.recyclerview.org/
MIT License
24.33k stars 5.16k forks source link

DataBinding 的时候setOnLoadMoreListener会使Item的DataBindingUtil.inflate报空 #2182

Closed iBotasky closed 6 years ago

iBotasky commented 6 years ago

版本:2.9.38 DataBinding: V2 Adapter:

class MovieHotAdapter : BaseQuickAdapter<Film, MovieHotAdapter.ViewHolder>(R.layout.item_film) {
    override fun convert(helper: ViewHolder, item: Film) {
        val binding = helper.binding
        GlideUtil.loadImage(mContext, binding.ivFilmImg, item.images.small)
        binding.setVariable(BR.title, item.title)
        binding.setVariable(BR.rating, item.rating.average.toString())
        binding.setVariable(BR.stars, (item.rating.average * 5.0f / item.rating.max).toFloat())

        var directors: String = ""
        for (director in item.directors) {
            if (item.directors.indexOf(director) != item.directors.size - 1)
                directors += director.name + "/"
            else
                directors += director.name
        }

        binding.setVariable(BR.director, mContext.getString(R.string.movie_director, directors))
        binding.executePendingBindings()

    }

    override fun getItemView(layoutResId: Int, parent: ViewGroup): View {
        val binding: ItemFilmBinding = DataBindingUtil.inflate(mLayoutInflater, layoutResId, parent, false)//这一句报空
        val view = binding.root
        view.setTag(R.id.BaseQuickAdapter_databinding_support, binding)
        return view
    }

    class ViewHolder(view: View) : BaseViewHolder(view) {
        val binding: ItemFilmBinding
            get() = itemView.getTag(R.id.BaseQuickAdapter_databinding_support) as ItemFilmBinding
    }
}

Fragment中Adapter跟Rv的设置:

mAdapter = getAdapter()
        mRecyclerView.adapter = mAdapter
        mAdapter.setEnableLoadMore(isEnableLoadMore())
        if (isEnableLoadMore()) {
            mAdapter.setLoadMoreView(getDefaultLoadView())
            mAdapter.setOnLoadMoreListener(object : BaseQuickAdapter.RequestLoadMoreListener {
                override fun onLoadMoreRequested() {
                    mAdapter.loadMoreComplete()
                    mAdapter.loadMoreEnd()
                }
            })
        }

拉到最后一个Item报错:

java.lang.IllegalStateException: DataBindingUtil.inflate(…youtResId, parent, false) must not be null
        at com.sirius.cybird.ui.movie.hot.MovieHotAdapter.getItemView(MovieHotAdapter.kt:40)
        at com.chad.library.adapter.base.BaseQuickAdapter.getLoadingView(BaseQuickAdapter.java:778)
        at com.chad.library.adapter.base.BaseQuickAdapter.onCreateViewHolder(BaseQuickAdapter.java:757)
        at com.chad.library.adapter.base.BaseQuickAdapter.onCreateViewHolder(BaseQuickAdapter.java:68)
        at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6519)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5706)
        at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
        at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
        at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
        at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
        at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:185)
        at android.app.ActivityThread.main(ActivityThread.java:6615)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:806)

我配置应该是对的,不懂为什么设置了LoadMore就爆了

iBotasky commented 6 years ago

在官方Demo的DataBindingUseActivity这个类加了setOnLoadMore也会崩溃,但是跟我上面的错误不一样: DataBindingUseActivity:

public class DataBindingUseActivity extends BaseActivity {

    RecyclerView mRecyclerView;
    DataBindingUseAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setBackBtn();
        setTitle("DataBinding Use");
        setContentView(R.layout.activity_data_binding_use);

        mRecyclerView = (RecyclerView) findViewById(R.id.rv);
        mAdapter = new DataBindingUseAdapter(R.layout.item_movie, genData());
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                ToastUtils.showShortToast("onItemClick");
            }
        });
        mAdapter.setOnItemChildLongClickListener(new BaseQuickAdapter.OnItemChildLongClickListener() {
            @Override
            public boolean onItemChildLongClick(BaseQuickAdapter adapter, View view, int position) {
                ToastUtils.showShortToast("onItemChildLongClick");
                return true;
            }
        });
        mAdapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
                ToastUtils.showShortToast("onItemLongClick");
                return true;
            }
        });

       /**
         * 我加的代码
         */
        mAdapter.setEnableLoadMore(true);
        mAdapter.setOnLoadMoreListener(new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                mAdapter.loadMoreFail();
            }
        });
    }

    private List<Movie> genData() {
        ArrayList<Movie> list = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            String name = "Chad";
            int price = random.nextInt(10) + 10;
            int len = random.nextInt(80) + 60;
            Movie movie = new Movie(name, len, price, "He was one of Australia's most distinguished artistes");
            list.add(movie);
        }
        return list;
    }
}

报错:

java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling android.support.v7.widget.RecyclerView{557395f VFED..... .F...... 0,0-1080,1794 #7f080098 app:id/rv}, adapter:com.chad.baserecyclerviewadapterhelper.adapter.DataBindingUseAdapter@8188fac, layout:android.support.v7.widget.LinearLayoutManager@943c475, context:com.chad.baserecyclerviewadapterhelper.DataBindingUseActivity@460a4e4
        at android.support.v7.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:2663)
        at android.support.v7.widget.RecyclerView$RecyclerViewDataObserver.onItemRangeChanged(RecyclerView.java:5066)
        at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:11554)
        at android.support.v7.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:11545)
        at android.support.v7.widget.RecyclerView$Adapter.notifyItemChanged(RecyclerView.java:6778)
        at com.chad.library.adapter.base.BaseQuickAdapter.loadMoreFail(BaseQuickAdapter.java:404)
        at com.chad.baserecyclerviewadapterhelper.DataBindingUseActivity$1.onLoadMoreRequested(DataBindingUseActivity.java:37)
        at com.chad.library.adapter.base.BaseQuickAdapter.autoLoadMore(BaseQuickAdapter.java:1464)
        at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:929)
        at com.chad.library.adapter.base.BaseQuickAdapter.onBindViewHolder(BaseQuickAdapter.java:68)
        at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6482)
        at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
        at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
        at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:285)
        at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:342)
        at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:358)
        at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:365)
        at android.support.v7.widget.GapWorker.run(GapWorker.java:396)
        at android.os.Handler.handleCallback(Handler.java:751)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:185)
        at android.app.ActivityThread.main(ActivityThread.java:6615)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:916)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:806)
iBotasky commented 6 years ago

已解决,在Adapter的getItem的时候如果DataBinding为空要返回一个父类的getItemView返回View:

override fun getItemView(layoutResId: Int, parent: ViewGroup): View {
        //有loadmore的时候需要return super.getItemView(layoutResId, parent)
        val binding: ItemFilmBinding = DataBindingUtil.inflate(mLayoutInflater, layoutResId, parent, false) ?: return super.getItemView(layoutResId, parent)
        val view = binding.root
        view.setTag(R.id.id_tag_movie, binding)
        return view
    }