RecyclerView和数据绑定无法正常工作

the*_*itz 22 android android-custom-view android-recyclerview android-databinding

这是我第一次使用RecyclerView进行数据绑定,但不是我第一次使用RecyclerView本身.

由于某些原因,没有调用任何适配器方法 - 甚至不是getItemCount().我的RecyclerView可能是一个愚蠢的问题,与数据绑定无关,但我看不出有什么不妥.

       View rootview = inflater.inflate(R.layout.fragment_profile_first, container, false);
    // Initialize recycler view

    RecyclerView badgesRV = (RecyclerView) rootview.findViewById(R.id.badgesRV);
    LinearLayoutManager llm = new LinearLayoutManager(getActivity());
    llm.setOrientation(LinearLayoutManager.HORIZONTAL);
    badgesRV.setLayoutManager(llm);

    BadgeAdapter badgeAdapter = new BadgeAdapter(profileObject.badgesEntity.badges);
    badgesRV.setAdapter(badgeAdapter);
Run Code Online (Sandbox Code Playgroud)

适配器:

    public class BadgeAdapter extends RecyclerView.Adapter<BadgeAdapter.BadgeBindingHolder>{

    private static final int MAX_BADGES_TO_DISPLAY = 5;
    private BadgeObject[] badges;

    public BadgeAdapter(BadgeObject[] badges){
        this.badges = badges;
    }

    @Override
    public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.profile_badge_row, parent, false);
        BadgeBindingHolder holder = new BadgeBindingHolder(v);
        return holder;
    }

    @Override
    public void onBindViewHolder(BadgeBindingHolder holder, int position) {
        final BadgeObject badgeObject = badges[position];
        holder.getBinding().setVariable(BR.badge, badgeObject);
        holder.getBinding().executePendingBindings();

    }

    @Override
    public int getItemCount() {
        Log.d(TAG, "item count = " + Math.min(MAX_BADGES_TO_DISPLAY, badges.length));
        return Math.min(MAX_BADGES_TO_DISPLAY, badges.length);
    }

    public class BadgeBindingHolder extends RecyclerView.ViewHolder{
        private ViewDataBinding binding;

        public BadgeBindingHolder(View rowView) {
            super(rowView);
            binding = DataBindingUtil.bind(rowView);
        }
        public ViewDataBinding getBinding() {
            return binding;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

profile_badge_row.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
    <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/>
</data>

<LinearLayout
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@{badge.badgeImage}"/>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

我已经检查过,那里肯定有数据.我错过了什么?

=====================

更新:

据我所知,RecyclerView在Data Binding布局中根本不起作用.我创建了一个单独的布局,只有我的RV,它完美地工作.一旦我将它与我的主要布局包括在内,它就不再起作用了.

不确定这是一个错误还是一个功能.

所以,我想如果我把它变成一个自定义视图,也许它会起作用.我的问题是我不知道如何将值传递到我的自定义视图中.

我看了一眼,但无法弄明白他的意思.这是我在自定义视图中的代码.

    LayoutInflater inflater = (LayoutInflater)
            context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.profile_badges_layout, this, true);
    ProfileBadgesLayoutBinding binding = ProfileBadgesLayoutBinding.inflate(inflater);

    RecyclerView badgesRV = (RecyclerView) view.findViewById(R.id.badgesRV);

    LinearLayoutManager llm = new LinearLayoutManager(context);
    llm.setOrientation(LinearLayoutManager.HORIZONTAL);
    badgesRV.setLayoutManager(llm);

    BadgeAdapter badgeAdapter = new BadgeAdapter(null);
    badgesRV.setAdapter(badgeAdapter);
Run Code Online (Sandbox Code Playgroud)

这会给出一条消息,指出找不到ProfileBadgesLayoutBinding.

Exa*_*aqt 20

在你的onCreateViewHolder:

@Override
public BadgeBindingHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ProfileBadgeRowBinding binding = DataBindingUtil.inflate(inflater, R.layout.profile_badge_row, parent, false);
    BadgeBindingHolder holder = new BadgeBindingHolder(binding.getRoot(), binding);
    return holder;
}
Run Code Online (Sandbox Code Playgroud)

并在项目视图中添加绑定

public class BadgeBindingHolder extends RecyclerView.ViewHolder{
    private ProfileBadgeRowBinding binding;

    public BadgeBindingHolder(View rowView, ProfileBadgeRowBinding binding) {
        super(rowView);
        this.binding = binding;
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

并在bindToViewHolder设置变量

@Override
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) {
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding;
    binding.setVariable(BR.badge, badge);
    binding.executePendingBindings(); // This line is important, it will force to load the variable in a custom view
}
Run Code Online (Sandbox Code Playgroud)

如果要访问视图,请在您的视图中添加ID xml.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable name="badge" type="parseJsonEntities.requestObjects.BadgeObject"/>
    </data>

    <LinearLayout
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

然后你可以访问你的id bindToViewHolder

@Override
public void bindToViewHolder(RecyclerView.ViewHolder viewHolder) {
    ProfileBadgeRowBinding binding = ((BadgeBindingHolder) viewHolder).binding;
    binding.setVariable(BR.badge, badge);
    binding.executePendingBindings();

    binding.image.setImage(...);
}
Run Code Online (Sandbox Code Playgroud)

有关自定义视图的更多信息https://developer.android.com/topic/libraries/data-binding/index.html#dynamic_variables

  • 谢谢 !我的问题是我没有使用binding.executePendingBindings(); 对我来说这看起来并不那么明显.非常感谢你 !!!! (2认同)