I have a recycleview which fetches data from api with a custom adapter containing a textview and imageview and I implemented this in Activity and it works fine, but now I tried to use fragment instead of activity and every thing works fine except for the images that are not displayed after moving the code to fragment so this is my fragment:
public class TVFragment extends Fragment implements TVAdapter.TVAdapterOnClickHandler {
TVAdapter mAdapter;
RecyclerView mSportsList;
String sortsports="sports.php";
Context mContext ;
public static TVFragment newInstance() {
TVFragment fragment = new TVFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tv, container, false);
mSportsList = (RecyclerView) view.findViewById(R.id.rv_sports);
mContext = getActivity();
GridLayoutManager LayoutManagerSports = new GridLayoutManager(getActivity(), 3);
mSportsList.setLayoutManager(LayoutManagerSports);
mSportsList.setHasFixedSize(true);
mAdapter = new TVAdapter(this, mContext);
mSportsList.setAdapter(mAdapter);
loadTVData(sortsports);
return view;
}
private void loadTVData(String sortChannels) {
showTVDataView();
new FetchTVTask().execute(sortChannels);
}
@Override
public void onClick(TVItem channel) {
Context context = getActivity().getApplicationContext();
Class destinationClass = TVChannel.class;
Intent intentToStartDetailActivity = new Intent(context, destinationClass);
intentToStartDetailActivity.putExtra("TVChannel", channel);
startActivity(intentToStartDetailActivity);
}
private void showTVDataView() {
mSportsList.setVisibility(View.VISIBLE);
}
public class FetchTVTask extends AsyncTask<String, Void, ArrayList<TVItem>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected ArrayList<TVItem> doInBackground(String... params) {
if (params.length == 0) {
return null;
}
String sortChannels = params[0];
URL channelRequestUrl = NetworkTV.buildUrl(sortChannels);
try {
String jsonTVResponse = NetworkTV.getResponseFromHttpUrl(channelRequestUrl);
ArrayList<TVItem> simpleJsonTVData = JsonTV.getSimpleTVStringsFromJson(getContext(), jsonTVResponse);
return simpleJsonTVData;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(ArrayList<TVItem> TVData) {
if (TVData != null) {
showTVDataView();
mAdapter.setTVData(TVData);
} else {
}
}
}
}
then this is my adapter:
public class TVAdapter extends RecyclerView.Adapter<TVAdapter.RecyclerViewHolder> {
ArrayList<TVItem> mChannelItems;
private Context mContext;
private final TVAdapter.TVAdapterOnClickHandler mClickHandler;
public interface TVAdapterOnClickHandler {
void onClick(TVItem channel);
}
public TVAdapter(TVAdapterOnClickHandler clickHandler, Context context) {
this.mContext = context;
mClickHandler = clickHandler;
}
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public final TextView Cat;
public final ImageView Image;
public RecyclerViewHolder(View view) {
super(view);
Cat = (TextView)itemView.findViewById(R.id.channel_cat);
Image = (ImageView) itemView.findViewById(R.id.channel_image);
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
TVItem channel = mChannelItems.get(adapterPosition);
mClickHandler.onClick(channel);
}
}
@Override
public TVAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
mContext = viewGroup.getContext();
int layoutIdForListItem = R.layout.tv_list_item;
LayoutInflater inflater = LayoutInflater.from(mContext);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new TVAdapter.RecyclerViewHolder(view);
}
@Override
public void onBindViewHolder(TVAdapter.RecyclerViewHolder holder, int position) {
Picasso.with(mContext).load(mChannelItems.get(position).getFullImagePath()).resize(500,500).placeholder(R.drawable.placeholder).error(R.drawable.placeholder).into(holder.Image);
holder.Cat.setText(String.valueOf(mChannelItems.get(position).getTitle()));
}
@Override
public int getItemCount() {
if (null == mChannelItems)
return 0;
else {
return mChannelItems.size();
}
}
public void setTVData(ArrayList<TVItem> TVData) {
mChannelItems = TVData;
notifyDataSetChanged();
}
}
you can see these lines:
Picasso.with(mContext).load(mChannelItems.get(position).getFullImagePath()).resize(500,500).placeholder(R.drawable.placeholder).error(R.drawable.placeholder).into(holder.Image);
and:
holder.Cat.setText(String.valueOf(mChannelItems.get(position).getTitle()));
the cat still displayed well in textview but the images with picasso library not displayed anymore and I read a lot of solutions like pass the context from fragment to adapter but nothing work!
this is the debugging images:
viewgroup.getContext() Isn't the context needed, but the context from the fragment or an activity.
@Override
public TVAdapter.RecyclerViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
//mContext = viewGroup.getContext(); This should fix it. You already init mContext in the constructor.
int layoutIdForListItem = R.layout.tv_list_item;
LayoutInflater inflater = LayoutInflater.from(mContext);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
return new TVAdapter.RecyclerViewHolder(view);
}
Why are you assigning value to mContext
twice? Try removing mContext = viewGroup.getContext();
from code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With