其他分享
首页 > 其他分享> > android – 在RecyclerView适配器中使用自定义视图?

android – 在RecyclerView适配器中使用自定义视图?

作者:互联网

我有一个基本的自定义视图,如下所示:

public class CustomView extends RelativeLayout {

    private User user;

    private ImageView profilePicture;

    public CustomView(Context context) {
        super(context);
        init();
    }

    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        inflate(getContext(), R.layout.custom_layout, this);

        profilePicture = (ImageView) findViewById(R.id.profilePicture);

        // ACCESS USER MODEL HERE
        // e.g. user.getUsername()
    }

}

如您所见,我想在View中访问用户数据(即:user.getUsername()).

我还需要能够在RecyclerView适配器中使用自定义视图.

这是我的适配器目前的​​样子:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {

    private Context context;

    private List<User> userData;

    public MyAdapter(Context context, List<User> userData) {
        this.context = context;
        this.userData = userData;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(View v) {
            super(v);
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);

        // HOW TO INFLATE THE CUSTOM VIEW?

        // ViewHolder viewHolder = new ViewHolder(customView);

        return viewHolder;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        // ANYTHING HERE?
    }

    @Override
    public int getItemCount() {
        return userData.size();
    }

}

如何在适配器中充气自定义视图?
另外,我应该在onBindViewHolder()中添加任何内容吗?

注意:我必须使用自定义视图,因为我在不同的适配器下使用此视图(即:不仅仅是这个RecyclerView适配器).

解决方法:

假设一个CustomView类看起来像这样:

public class CustomView extends RelativeLayout {
    private User user;
    private ImageView profilePicture;

    // override all constructors to ensure custom logic runs in all cases
    public CustomView(Context context) {
        this(context, null);
    }
    public CustomView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public CustomView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }
    public CustomView(
            Context context,
            AttributeSet attrs,
            int defStyleAttr,
            int defStyleRes
    ) {
        super(context, attrs, defStyleAttr, defStyleRes);

        // put all custom logic in this constructor, which always runs
        inflate(getContext(), R.layout.custom_layout, this);
        profilePicture = (ImageView) findViewById(R.id.profilePicture);
    }

    public void setUser(User newUser) {
        user = newUser;
        // ACCESS USER MODEL HERE
        // e.g. user.getUsername()
    }
}

您的RecyclerView.Adapter和RecyclerView.ViewHolder看起来像这样:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    // no Context reference needed—can get it from a ViewGroup parameter
    private List<User> userData;

    public MyAdapter(List<User> userData) {
        // make own copy of the list so it can't be edited externally
        this.userData = new ArrayList<User>(userData);
    }

    @Override
    public int getItemCount() {
        return userData.size();
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // no need for a LayoutInflater instance—
        // the custom view inflates itself
        CustomView itemView = new CustomView(parent.getContext());
        // manually set the CustomView's size
        itemView.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
        ));
        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        holder.getCustomView().setUser(userData.get(position));
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private CustomView customView;

        public ViewHolder(View v) {
            super(v);
            customView = (CustomView) v;
        }

        public CustomView getCustomView() {
            return customView;
        }
    }
}

> CustomView管理自己的设置,它在自己的构造函数中发生,在这种情况下使用XML文件的膨胀. (或者,它可以以编程方式设置其子视图.)
>因此,RecyclerView.Adapter不需要执行任何通胀 – 它只是创建一个新的CustomView实例,并让CustomView担心自己的设置.
>在调用setUser方法之前,CustomView无法获取User实例,因此在构造函数中不能进行用户访问.在任何情况下,在一个CustomView生命周期内,RecyclerView可以要求它在不同时间显示许多不同用户的信息. CustomView需要能够执行此操作.因此,引入了setUser方法.
>因为CustomView是通过代码而不是XML实例化的,所以无法在XML中定义大小的属性.因此,在定时之后以编程方式完成大小调整.
> onBindViewHolder只需在CustomView上调用setUser即可将CustomView与正确的User实例链接起来.
> ViewHolder类现在只是RecyclerView项和CustomView之间的链接.

在RecyclerViews中使用来自另一个类的预构建的自定义视图(即不在RecyclerView.Adapter中膨胀XML)似乎从未被讨论过.我认为这是一个很好的想法,即使自定义视图专门用于RecyclerView,因为它是promotes separation of concernsadherence to the Single Responsibility Principle.

标签:android-adapter,android,android-recyclerview,android-view
来源: https://codeday.me/bug/20191001/1840286.html