Groupie: Passing in 'Context' and 'Objects created inside Activity' to Item

Created on 18 Oct 2016  路  3Comments  路  Source: lisawray/groupie

First of all thanks a lot for such a brilliant lib for RecyclerViews!

I will break my question into two parts.

  1. Passing Context
  2. Passing Objects created inside Activity

1. Context
When using the RecyclerView Adapter as provided by Android Support library, we generally pass the 'Context' objects from Activities to the RVAdapter via RVAdapter constructor like below:

RVAdapter.java:

public class RVAdapter extends RecyclerView.Adapter{

     private Context context;
     private ImageHelper.CircleTransform
     public RVAdapter(Context context,CircleTransform circleTransform){
            this.context = context;
            this.circleTransform = circleTransform;
     }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new RowHolder(inflater.inflate(R.layout.item_row,parent,false)) ;
    }

   //Here we use the context object passed via activity
  @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {

        RowHolder holder = (RowHolder) viewHolder;

        Glide.with(context)
                .load(TextHelper.formatUrl(<profie_url>))
                .bitmapTransform(circleTransform)
                .placeholder(R.drawable.ic_user_default)
                .error(R.drawable.ic_user_default)
                .into(holder.img);

    }
}

Now, when using Groupie this is how we create Row Item for that particular row:

RowItem.java

public class RowItem extends Item<RowItemBinding> {

    String profile_url;
    ImageHelper.CircleTransform circleTransform;
    public SGroupsRowItem(String profile_url,ImageHelper.CircleTransform circleTransform){
        this.profile_url = profile_url;
        this.circleTransform = circleTransform;
    }

    @Override
    public int getLayout() {
        return R.layout.row_item;
    }

    @Override
    public void bind(GroupieSgroupsItemRowItemBinding viewBinding, int position) {
        Glide.with(viewBinding.getRoot().getContext())
                .load(TextHelper.formatUrl(<profile_url>))
                .bitmapTransform(circleTransform)
                .placeholder(R.drawable.ic_user_default)
                .error(R.drawable.ic_user_default)
                .into(viewBinding.img);
    }
}

As can be seen we need to call viewBinding.getRoot().getContext() for every row item to get Context object.Isn't that expensive operation for every row item?
OR
In another way what we could do is pass the Context object in RowItem's constructor.
BUT again, we need to pass Context every time we create that RowItem object like:

Section section = new Section();
section.add(new RowItem(profile_url,this));
section.add(new RowItem(profile_url,this));

What is the ideal way to do when dealing with Context object inside Item class?

2. Objects created inside Activity
As can be seen in the above example ImageHelper.CircleTransform object created inside Activity needs to be used inside RowItem to apply bitmapTransform to the image.

In case of RvAdapter we can pass it one time using RVAdapter constructor.

But when using Groupie I need to pass ImageHelper.CircleTransform object every time i create
rowitem.

How do you deal with above scenarios of passing in objects one time from Activity ?
Thanks again! 馃憤

question

Most helpful comment

Hey. No, calling ViewHolder.getRoot.getContext() isn't expensive. Holding quick, cheap, and easy references to a view is the whole point of a ViewHolder! Similarly, it's not expensive to ask a View for its Context.

Your other two issues aren't really related to the library. If you want to have all instances of RowItem use the same CircleTransform, passing it in the constructor sounds like the most correct way to me. If it's just the typing that's tedious, maybe use a factory or a helper method or even dependency injection. There are other ways to handle it, like singletons or a static instance shared for the whole RowItem class.

I also try to avoid holding context in my model objects, or in my adapter, which I consider part of the model. This way it can be reused across configuration changes. If I require a Context to bind the Item I use the View's context. Of course, nothing is stopping you from extending GroupAdapter in the same way you were before.

All 3 comments

Hey. No, calling ViewHolder.getRoot.getContext() isn't expensive. Holding quick, cheap, and easy references to a view is the whole point of a ViewHolder! Similarly, it's not expensive to ask a View for its Context.

Your other two issues aren't really related to the library. If you want to have all instances of RowItem use the same CircleTransform, passing it in the constructor sounds like the most correct way to me. If it's just the typing that's tedious, maybe use a factory or a helper method or even dependency injection. There are other ways to handle it, like singletons or a static instance shared for the whole RowItem class.

I also try to avoid holding context in my model objects, or in my adapter, which I consider part of the model. This way it can be reused across configuration changes. If I require a Context to bind the Item I use the View's context. Of course, nothing is stopping you from extending GroupAdapter in the same way you were before.

@lisawray cool! Makes complete sense.
Thanks again for the supercool lib!

Glad you like it! I'll close this issue, feel free to open a new one if you have other questions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amervelic picture amervelic  路  3Comments

hardysim picture hardysim  路  3Comments

kawaiiDango picture kawaiiDango  路  5Comments

vahids28 picture vahids28  路  4Comments

alvin-nt picture alvin-nt  路  3Comments