Context for RecyclerView.Adapter
Solution 1
I've seen a lot of code where people keep reference to the Context in an Adapter. But in a RecyclerView.Adapter, the itemView (the view you already inflated from onCreateViewHolder) is accessible from your ViewHolder. For the most part, you should be dealing with the viewHolder anyways. So, use viewholder.itemView.getContext();. You can even expose a method in your viewholder getContext().
public Context getContext() {return itemView.getContext();}
Solution 2
Firstly, there are some differences between type of Contexts. Reference: https://possiblemobile.com/2013/06/context/
Example:
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Context context = viewHolder.anyView.getContext();
}
Solution 3
Create a custom Adapter
and add a Constructor
so that the Context
can be passed.
public class CustomAdapter extends ArrayAdapter<String> {
private Context context;
private List<String> stringList = null;
public CustomAdapter(Context context, int resource, List<String> objects) {
super(context, resource, objects);
this.context = context;
this.stringList = objects;
}
}
Use this 'context' variable to show the ProgressDialog
as per your requirement.
Solution 4
1.Pass activity context in constructor for adapter. if your calling from fragment pass it as getActivity().
2.You can also try itemView.getContext() in onBindViewHolder.
I am not sure about pros and cons of using #2 method because I always use #1.
Solution 5
In fragment add:
Context context;
#in onCreateView method:
context=getActivity();
allGroupsView = (RecyclerView) rootView.findViewById(R.id.allGroupsView);
adapterGroup = new AdapterGroup(context,results);
allGroupsView.setAdapter(adapterGroup);
allGroupsView.setLayoutManager(new LinearLayoutManager(getActivity()));
dont use getActivity.getApplicationContext() or context.getApplicationContext()
loading = ProgressDialog.show(mContext, null, "Please wait", true, true);
August
Updated on June 09, 2022Comments
-
August about 2 years
I want to add
ProgressDialog
in an adapter. AFAIK,.this
for activity, andgetActivity.getApplicationContext()
for fragment. What about adapter? Is it possible?I got error
Unable to add window -- token null is not valid; is your activity running?
when I usemContext.getApplicationContext()
.EDIT:
In a fragment, I show cards by
allGroupsView = (RecyclerView) rootView.findViewById(R.id.allGroupsView); adapterGroup = new AdapterGroup(getActivity().getApplicationContext(), results); allGroupsView.setAdapter(adapterGroup); allGroupsView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
In class
AdapterGroup
public class AdapterGroup extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private Context mContext; private LayoutInflater inflater; List<DataGroup> data= Collections.emptyList(); DataGroup current; public AdapterGroup(Context context, List<DataGroup> results) { this.mContext = context; inflater = LayoutInflater.from(mContext); this.data = results; } // Inflate the layout when viewholder created @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = inflater.inflate(R.layout.card_view_row, parent, false); final MyHolder holder = new MyHolder(view); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Log.d("debug", String.valueOf(holder.getAdapterPosition())); getDetails(Config.GET_GROUP_DETAILS_URL, data.get(holder.getAdapterPosition()).groupName, data.get(holder.getAdapterPosition()).description); } }); return holder; } private void getDetails(String url, String groupName, String description) { groupName = groupName.replace(" ", "%20"); description = description.replace(" ", "%20"); final String finalGroupName = groupName; final String finalDescription = description; class GetDetails extends AsyncTask<String, Void, String> { ProgressDialog loading; @Override protected void onPreExecute() { super.onPreExecute(); loading = ProgressDialog.show(mContext.getApplicationContext(), null, "Please wait", true, true); loading.setCancelable(false); } // more code down from here
-
OneCricketeer over 7 yearsQuestion asked about RecyclerView.Adapter. Besides, storing the
context
member variable in aArrayAdapter
is redundant. -
vidulaJ over 7 yearsYou can use this for a RecyclerView Adapter as well.
-
OneCricketeer over 7 yearsSure. I think the question already is doing this, though, as
mContext
appears to be the variable in the adapter andmContext.getApplicationContext
is throwing an exception -
vidulaJ over 7 yearsDid not have the code previously and the edit had been done after this answer. So using only mContext, a ProgressDialog could be started.
-
August over 7 yearsif I use
mContext
only withoutgetApplicationContext
it also throw the same exception -
OneCricketeer over 7 years@August That may be because you also assigned
mContext
with a call togetApplicationContext
when you initialized the adapter. -
vidulaJ over 7 yearsYou initialize Adapter variable inside a Fragment?
-
August over 7 yearscan you please take a look at my newly added codes?
-
August over 7 years
Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
-
WritingForAnroid over 7 yearsBy seeing updated code I feel its better to pass context in constructor.