Invoking transition animations from a RecyclerView adapter instead of an Activity

I have a RecyclerView application filled with some maps using the special RecyclerView (RV) adapter I made. Then I tried to follow this tutorial to add a transition between actions. However, as shown in the tutorial, the animation is called when the Intent is created inside the Activity, and my OnClick code is inside the RVAdapter. This does not give me access to the Activity required for the method

Intent intent = new Intent(HomeActivity.this, TargetActivity.class);
intent.putExtra(TargetActivity.ID, Contact.CONTACTS[position].getId());
ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
        // the context of the activity
        MainActivity.this,

        // For each shared element, add to this method a new Pair item,
        // which contains the reference of the view we are transitioning *from*,
        // and the value of the transitionName attribute
        new Pair<View, String>(view.findViewById(R.id.CONTACT_circle),
                getString(R.string.transition_name_circle)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_name),
                getString(R.string.transition_name_name)),
        new Pair<View, String>(view.findViewById(R.id.CONTACT_phone),
                getString(R.string.transition_name_phone))
);
ActivityCompat.startActivity(HomeActivity.this, intent, options.toBundle());

I tried passing the Activity object in the RVAdapter to my constructor, but it only led to NullPointerExceptions.

Here is my RVAdapter code:

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.AppVH>{


ArrayList<App> apps;

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

@Override
public void onBindViewHolder(AppVH holder, int position) {
    holder.name.setText(apps.get(position).getName());
    holder.artist.setText(apps.get(position).getArtist());
    String p = "";
    if(apps.get(position).getPrice()==0.0) p="Free";
    else p= "$"+apps.get(position).getPrice()+" "+apps.get(position).getCurrency();
    holder.price.setText(p);
    Picasso.with(AppListActivity.context).load(apps.get(position).getUrlImLarge()).into(holder.icon);
}

@Override
public int getItemCount() {
    return apps.size();
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}

RecyclerViewAdapter(ArrayList<App> applications){
    this.apps = applications;
}

// Clean all elements of the recycler
public void clear() {
    apps.clear();
    notifyDataSetChanged();
}

// Add a list of items
public void addAll(ArrayList<App> list) {
    apps.addAll(list);
    notifyDataSetChanged();
}

public class AppVH extends RecyclerView.ViewHolder implements View.OnClickListener{

    CardView cv;
    TextView name;
    TextView artist;
    TextView price;
    ImageView icon;
    private final Context c;

    public AppVH(View itemView) {
        super(itemView);
        cv = (CardView) itemView.findViewById(R.id.cardview);
        name = (TextView) itemView.findViewById(R.id.app_name);
        artist = (TextView) itemView.findViewById(R.id.app_artist);
        price = (TextView) itemView.findViewById(R.id.app_price);
        icon = (ImageView) itemView.findViewById(R.id.app_icon);
        itemView.setOnClickListener(this);
        c = itemView.getContext();
    }

    @Override
    public void onClick(View v) {
        final Intent intent;
        Log.d("Debugtext","Card with position " + getAdapterPosition() + " was touched.");
        intent = new Intent(c, AppDetailActivity.class);
        intent.putExtra("app",apps.get(getAdapterPosition()));
        c.startActivity(intent);
    }
}
}

This is how I add an adapter to RecyclerView in my "HomeActivity".

RecyclerView rv = (RecyclerView) findViewById(R.id.recycler_view);

    rv.setHasFixedSize(true);
    GridLayoutManager gridlm = new GridLayoutManager(getApplicationContext(),columns);
    rv.setLayoutManager(gridlm);
    rvadapter = new RecyclerViewAdapter(apps);
    rv.setAdapter(rvadapter);

Is there an easy way to call the ActivityCompat.startActivity (...) method from the adapter?

+4
1

, : . .

        @Override
        public void onClick(View v) {
            final Intent intent;
            //Opens the AppDetailActivity showing the selected App Card
            //Log.d("Debugtext","Card with position " + getAdapterPosition() + " was touched.");
            intent = new Intent(c, AppDetailActivity.class);
            intent.putExtra("app",apps.get(getAdapterPosition()));

            ActivityOptionsCompat options = ActivityOptionsCompat.
                    makeSceneTransitionAnimation((Activity)c, (View)cv, "appcard");
            c.startActivity(intent, options.toBundle());
        }
+5

Source: https://habr.com/ru/post/1627685/


All Articles