I want to show information that call from API to recycler view in fragment, but the recycler view doesnt show the information. The Api show GET method and need to display the list in Recycler View.
This is my Model
public class PhoneModel {
public PhoneModel() {
}
private int amount;
private String amount_display;
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public String getAmount_display() {
return amount_display;
}
public void setAmount_display(String amount_display) {
this.amount_display = amount_display;
}
}
This is my Adapter. i just want to show one information only in Recycler View.
public class PhoneAdapter extends RecyclerView.Adapter<PhoneAdapter.PhoneViewHolder> {
private ArrayList<PhoneModel> listItems;
private Context context;
LayoutInflater inflater;
public PhoneAdapter(Context context) {
this.listItems = new ArrayList<>();
this.context = context;
inflater = LayoutInflater.from(context);
}
#Override
public PhoneViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = inflater.from(parent.getContext())
.inflate(R.layout.view_holder_phone,parent,false);
return new PhoneViewHolder(v);
}
#Override
public void onBindViewHolder(PhoneViewHolder holder, int position) {
holder.test.setText(listItems.get(position).getAmount_display());
}
#Override
public int getItemCount() {
return listItems.size();
}
public void add(PhoneModel model) {
listItems.add(model);
notifyDataSetChanged();
}
public void clear() {
listItems.clear();
notifyDataSetChanged();
}
public class PhoneViewHolder extends RecyclerView.ViewHolder {
private TextView test;
private TextView currentBal;
public PhoneViewHolder(View itemView) {
super(itemView);
test = itemView.findViewById(R.id.tv_deposit);
currentBal = itemView.findViewById(R.id.tv_current_bal);
}
}
}
This is my Activity which i connect with Phone Model and Phone Adapter.
public class HistoryFragment extends Fragment {
private final static String TAG = HistoryFragment.class.getSimpleName();
private PhoneAdapter phoneAdapter;
private RecyclerView recyclerView;
public HistoryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
recyclerView = view.findViewById(R.id.recycler_history);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLinearLayoutManager);
phoneAdapter = new PhoneAdapter(getContext());
recyclerView.setAdapter(phoneAdapter);
phoneHistory();
return view;
}
private void phoneHistory(){
StringRequest request = new StringRequest(
Request.Method.GET,
ServerApi.URL_PHONE,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Gson gson = new GsonBuilder().create();
JSONObject jsonObject = null;
if(response != null) {
try {
jsonObject = new JSONObject(response);
PhoneModel phoneModel = gson.fromJson(jsonObject.getJSONObject("value").toString(), PhoneModel.class);
phoneAdapter.add(phoneModel);
} catch (JSONException e) {
Log.d(TAG, e.getLocalizedMessage());
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
};
Volley.newRequestQueue(getContext()).add(request);
}
}
Try this
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_history, container, false);
recyclerView = view.findViewById(R.id.recycler_history);
LinearLayoutManager mLinearLayoutManager = new
LinearLayoutManager(getActivity(),
LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(mLinearLayoutManager);
phoneHistory();
phoneAdapter = new PhoneAdapter(getContext());
recyclerView.setAdapter(phoneAdapter);
return view;
}
You getting empty data because in adapter constructor you creating new arraylist().
Change this:
public PhoneAdapter(Context context) {
this.listItems = new ArrayList<>();
this.context = context;
inflater = LayoutInflater.from(context);
}
To
public PhoneAdapter(Context context,Arraylist list) {
this.listItems = list;
this.context = context;
inflater = LayoutInflater.from(context);
}
also change in fragment:
phoneAdapter = new PhoneAdapter(getContext());
recyclerView.setAdapter(phoneAdapter,list);
and in phoneHistory() method
if(response != null) {
try {
jsonObject = new JSONObject(response);
PhoneModel phoneModel = gson.fromJson(jsonObject.getJSONObject("value").toString(), PhoneModel.class);
phoneModel .add(phoneModel);
list.add(phoneModel )
phoneAdapter.notifyDataSetChanged()
} catch (JSONException e) {
Log.d(TAG, e.getLocalizedMessage());
}
}
Hope it will help you!!
Related
I am using a Fragment to view a RecyclerView. But I always get this error
E/RecyclerView: No adapter attached; skipping layout
I have created an adapter for my recyclerview but the layout does not display. The php backend is working fine. Can somebody please help. Here are my codes for the fragment and adapter
Tips.java
public class Tips extends Fragment {
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
List<TipModel> tipList;
RecyclerView recyclerView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
loadTips();
return view;
}
private void loadTips() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
}
TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
recyclerView.setAdapter(tipAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
TipAdapter.java
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder> {
private Context context;
private List<TipModel> tipList;
public TipAdapter(Context context, List<TipModel> tipList) {
this.context = context;
this.tipList = tipList;
}
#Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
}
#Override
public void onBindViewHolder(TipViewHolder holder, int position) {
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
}
#Override
public int getItemCount() {
return tipList.size();
}
class TipViewHolder extends RecyclerView.ViewHolder {
TextView textViewTip;
public TipViewHolder(View view) {
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
}
}
It happens because RecyclerView is expecting an adapter when dispatching layout on view created, so it is fine if there is no adapter when the view is created, it will just skip the layout part.
If you are worried about the error, then you could set an empty adapter when the view is created:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_tips, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
tipList = new ArrayList<>();
recyclerView.setAdapter(new TipAdapter(getActivity(), tipList));
}
Then adjust your code in the response callback:
#Override
public void onResponse(String response) {
// Instead of setting adapter here...
// TipAdapter tipAdapter = new TipAdapter(getActivity(), tipList);
// recyclerView.setAdapter(tipAdapter);
// Just notify the adapter that tipList has changed.
recyclerView.getAdapter().notifyDataSetChanged();
// ...
}
TipList is the Adapter's datastore, it belongs to the Adapter and not to the Fragment
I have edited your code ( don't have access to Android Studio, doing it in Text Editor, please check for syntax errors )
Fragment
public class Tips extends Fragment {
Configuration config = new Configuration();
String HttpUrl = config.viewtips_url;
RecyclerView recyclerView;
TipAdapter tipAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Initialize the Tip Adapter
tipAdapter = new TipAdapter(getActivity());
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_tips, container, false);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
// Assign the Adapter to recyclerView
recyclerView.setAdapter(tipAdapter);
return view;
}
private void loadTips() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, HttpUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
// Create a new TipList
List<TipModel> tipList = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
tipList.add(new TipModel(
jsonObject.getInt("id"),
jsonObject.getString("tip")
));
}
tipAdapter.updateWith(tipList)
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
TipAdapter
public class TipAdapter extends RecyclerView.Adapter<TipAdapter.TipViewHolder> {
private Context context;
private List<TipModel> tipList = new ArrayList<>();
public TipAdapter(Context context) {
this.context = context;
}
#Override
public TipViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.itemlayout, null);
return new TipViewHolder(view);
}
#Override
public void onBindViewHolder(TipViewHolder holder, int position) {
TipModel tipModel = tipList.get(position);
holder.textViewTip.setText(tipModel.getTip());
}
#Override
public int getItemCount() {
return tipList.size();
}
class TipViewHolder extends RecyclerView.ViewHolder {
TextView textViewTip;
public TipViewHolder(View view) {
super(view);
textViewTip = view.findViewById(R.id.textViewTip);
}
}
public updateWith(List<TipModel> tipList) {
this.tipList = tipList;
notifyDataSetChanged();
}
This is how I did it, when I had a similar problem while inflating recycler view in fragment. This code worked perfectly for me:
P.S. - This is the patch of code what I used in my application. I am sorry for any inconvenience.
First of all, in the onCreateView() of your Display Fragment:
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
Firebase.setAndroidContext(getActivity());
((Home_Drawer) getActivity())
.setActionBarTitle("Home");
recyclerView = (RecyclerView) root.findViewById(R.id.recycler_view_home_frag);
progressBar = (ProgressBar) root.findViewById(R.id.mainPageProgressBar);
// Log.i("inside", "rv initiated" +mLayoutManager.toString());
// Assign activity this to progress dialog.
progressDialog = new ProgressDialog(getActivity());
// Setting up message in Progress dialog.
progressDialog.setMessage("Loading Images From Firebase.");
// Showing progress dialog.
progressDialog.show();
// The path is already defined in MainActivity.
databaseReference = FirebaseDatabase.getInstance().getReference().child("productDisplay");
Log.i("inside", databaseReference.toString());
return root;
}
Then, we call onStart(). This is because recycler view generally does not inflate, ehile setting the adapter in onCreateView().
#Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<DisplayItemsModel> item_info =
new FirebaseRecyclerOptions.Builder<DisplayItemsModel>()
.setQuery(databaseReference, DisplayItemsModel.class)
.build();
final FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder> info_adapter =
new FirebaseRecyclerAdapter<DisplayItemsModel, ViewHolder>(item_info) {
#Override
protected void onBindViewHolder(final ViewHolder holder, final int position, final DisplayItemsModel model) {
mContext = getContext();
final DatabaseReference dref = getRef(position).getRef();
Log.i("dref", dref.toString());
// Adding Add Value Event Listener to databaseReference.
dref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(final DataSnapshot snapshot) {
holder.item_name_single_card.setText(snapshot.child("name").getValue().toString());
holder.price_single_card.setText(snapshot.child("price").getValue().toString());
String image_url = snapshot.child("image").getValue().toString();
Picasso.get().load(image_url).into(holder.thumbnail);
// Continue with your code.
This worked perfectly for me. Hope it solves your problem.
homepageThis is my fragment class
public class Premiums extends Fragment {
private RecyclerView recyclerPremium;
private RecyclerView.LayoutManager mLayoutManager;
private List<FeaturedAddDetails> featuredAddDetailsList = new ArrayList<>();
private List<PremiumDetails> premiumDetailslist = new ArrayList<>();
private NewestAdapter newestAdapter;
private PremiumAdapter premiumAdapter;
private String jsonResponse;
private PremiumDetails premiumDetails;
private JSONObject jsonobject;
public Premiums() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.premium_fragment, container, false);
recyclerPremium = (RecyclerView) mainView.findViewById(R.id.recycler_premium);
premiumAdd();
premiumAdapter = new PremiumAdapter(getActivity().getApplicationContext(), premiumDetailslist);
recyclerPremium.setAdapter(premiumAdapter);
return mainView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerPremium.setLayoutManager(mLayoutManager);
recyclerPremium.setHasFixedSize(true);
}
private void premiumAdd() {
PremiumRequestHandler premiumHandler = new PremiumRequestHandler("premiumADD");
premiumHandler.executeAsStringRequest(new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("response", response);
JSONArray jsonarray = null;
try {
jsonarray = new JSONArray(response);
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonarray.length(); i++) {
try {
jsonobject = jsonarray.getJSONObject(i);
Log.e("id", String.valueOf(jsonobject.getInt("id")));
premiumDetails = new PremiumDetails(jsonobject.getInt("id"),
jsonobject.getInt("userid"),
jsonobject.getInt("mobile"),
jsonobject.getInt("cityid"),
jsonobject.getInt("price"),
jsonobject.getInt("comments"),
jsonobject.getInt("created"),
jsonobject.getInt("categoryid"),
jsonobject.getInt("MainCategoryID"),
jsonobject.getInt("views"),
jsonobject.getInt("ImageCount"),
jsonobject.getInt("storeid"),
jsonobject.getString("title"),
jsonobject.getString("default_photo"),
jsonobject.getString("CityName"),
jsonobject.getString("CategoryName"),
jsonobject.getString("currency"),
jsonobject.getString("description"));
premiumDetailslist.add(premiumDetails);
premiumAdapter.setPremiumDetails(premiumDetailslist);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new BaseRequest.ErrorResponseCallback() {
#Override
public void onError(Exception exception) {
}
});
}
This is my adapter class
public class PremiumAdapter extends RecyclerView.Adapter<PremiumAdapter.MyViewHolderPremium> {
private List<PremiumDetails> premiumDetailsList;
private ImageLoader imageLoader;
private Context context;
public PremiumAdapter(Context context, List<PremiumDetails> premiumDetailsList) {
this.premiumDetailsList = premiumDetailsList;
this.context = context;
notifyDataSetChanged();
}
public void setPremiumDetails(List<PremiumDetails> premiumDetailsList) {
this.premiumDetailsList = premiumDetailsList;
notifyDataSetChanged();
}
public class MyViewHolderPremium extends RecyclerView.ViewHolder {
private TextView txtTitle,txtDescription,txtCityName,txtPrice,txtCategory,txtHour,txtPhotoNo;
private NetworkImageView imgPhoto;
public MyViewHolderPremium(View itemView) {
super(itemView);
txtTitle = (TextView)itemView.findViewById(R.id.txt_title_fad);
txtDescription = (TextView)itemView.findViewById(R.id.description_fad);
txtCityName = (TextView)itemView.findViewById(R.id.city_name_fad);
txtPrice = (TextView)itemView.findViewById(R.id.price_fad);
txtCategory = (TextView)itemView.findViewById(R.id.category_fad);
txtHour = (TextView)itemView.findViewById(R.id.hours_fad);
txtPhotoNo = (TextView)itemView.findViewById(R.id.txt_photo_no_fad);
imgPhoto=(NetworkImageView)itemView.findViewById(R.id.img_photo_lod_fad);
}
}
#Override
public MyViewHolderPremium onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.featured_ad_adapter_layout,parent,false);
final MyViewHolderPremium myViewHolderPremium = new MyViewHolderPremium(itemView);
return myViewHolderPremium;
}
#Override
public void onBindViewHolder(MyViewHolderPremium holder, int position) {
PremiumDetails premiumDetails = premiumDetailsList.get(position);
holder.txtTitle.setText(premiumDetails.getTitle());
holder.txtDescription.setText(premiumDetails.getDescription());
holder.txtCityName.setText(premiumDetails.getCityName());
holder.txtPrice.setText(Integer.toString(premiumDetails.getPrice()));
holder.txtCategory.setText(premiumDetails.getCategoryName());
holder.txtHour.setText(Integer.toString(premiumDetails.getCreated()));
holder.txtPhotoNo.setText(Integer.toString(premiumDetails.getImageCount())+" photos " );
try {
imageLoader= VolleyHandler.getImageLoader();
} catch (Exception e) {
e.printStackTrace();
}
//imageLoader = CustomVolleyRequest.getInstance(context).getImageLoader();
//imageLoader.get(featuredAddDetails.getDefault_photo(), ImageLoader.getImageListener(holder.imgPhoto, R.mipmap.ic_launcher, android.R.drawable.ic_dialog_alert));
holder.imgPhoto.setImageUrl(premiumDetails.getDefault_photo(),imageLoader);
}
#Override
public int getItemCount() {
Log.e("size", String.valueOf(premiumDetailsList.size()));
return premiumDetailsList.size();
}}
I am getting error on showing values but I got values from json and I can't add it to adapter and model class, plz help me I look stackoverflow whole day but I can't find my issue
my getItemCount() is showing as 0"
You are setting the adapter and then you are calling premiumAdd() method.First call that method and then set the adapter.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.premium_fragment, container, false);
recyclerPremium = (RecyclerView) mainView.findViewById(R.id.recycler_premium);
premiumAdd();
premiumAdapter = new PremiumAdapter(getActivity().getApplicationContext(), premiumDetailslist);
recyclerPremium.setAdapter(premiumAdapter);
return mainView;
Try notifyDataSetChanged() after setting data in the Constructor of your Adapter
[EDIT] Whenever your data changes, you need to inform your Adapter about it also, then call notifyDataSetChanged() on it.
You are probably setting empty data into the Adapter, your List changes, but the Adapter does not know about it.
[Update]
In addition to your Adapter constructor, add a setData(List) to your adapter to change your dataset at runtime.
public void setPremiumDetails(List<PremiumDetails> premiumDetailsList) {
this.premiumDetailsList = premiumDetailsList;
notifyDataSetChanged();
}
When your request in premiumAdd() returns, and you receive a new set of data, you call setPremiumDetails on your Adapter with the new data and the List will update.
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View mainView = inflater.inflate(R.layout.premium_fragment, container, false);
recyclerPremium = (RecyclerView) mainView.findViewById(R.id.recycler_premium);
mLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
recyclerPremium.setLayoutManager(mLayoutManager);
recyclerPremium.setHasFixedSize(true);
premiumAdd();
premiumAdapter = new PremiumAdapter(getActivity().getApplicationContext(), premiumDetailslist);
recyclerPremium.setAdapter(premiumAdapter);
return mainView;
}
and remove premiumAdapter.notifyDataSetChanged();
added adapter code:
public class RVAdapter extends RecyclerView.Adapter<RVAdapter.ViewHolder> {
ArrayList<Model> dataset;
public RVAdapter(ArrayList<Model> dataset) {
this.dataset = dataset;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_item,parent,false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Model model = dataset.get(position);
holder.name.setText(model.name) ;
holder.status.setText(model.status);
if (model.status.equalsIgnoreCase("good"))
holder.ivStatus.setImageResource(R.drawable.ic_tick_48);
else
holder.ivStatus.setImageResource(R.drawable.ic_delete_48);
}
#Override
public int getItemCount() {
Log.e("TAG","SIZE: "+dataset.size());
return dataset.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView name;
TextView status;
ImageView ivStatus;
RelativeLayout parent;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.rv_item_name);
status = (TextView) itemView.findViewById(R.id.rv_item_status);
ivStatus = (ImageView) itemView.findViewById(R.id.rv_item_iv);
parent = (RelativeLayout) itemView.findViewById(R.id.rv_item_parent);
}
}
}
your notifiy adapter on every single add
for (...){
....
premiumDetailslist.add(premiumDetails);
premiumAdapter.notifyDataSetChanged();// called every time wrong
}
also provide what exact error log says
and move the notifyDataSetChanged() after the for not in the loop
if no data is showing try recyclerview.invalidate , but i wont particularly do that way, would try debugging, log every step, inspect with method in the expected sequence isnt working
i responsed json object from api and i tried to send the response to the module using setter then to the Recyclerview adapter but its not working
This is my fragment
public class ListViewActivityFragment extends Fragment {
List<AppShowModule> appShowModule;
RecyclerView AppRecyclerView;
RecyclerView.LayoutManager AppRecyclerViewlayoutManager;
RecyclerView.Adapter AppRecyclerViewadapter;
String jsonUrl = "https://itunes.apple.com/jo/rss/topfreeapplications/limit=50/json";
TextView text;
Context context;
RequestQueue requestQueue;
public ListViewActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_list_view, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
appShowModule = new ArrayList<>();
AppRecyclerView = (RecyclerView) getView().findViewById( R.id.AppRecyclerView );
AppRecyclerView.setHasFixedSize( true );
AppRecyclerView.setLayoutManager( AppRecyclerViewlayoutManager );
JsonAppShowData();}
public void JsonAppShowData() {
final JsonObjectRequest jsonObjectRequest = new JsonObjectRequest( jsonUrl, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONObject("feed").getJSONArray( "entry" );
AppShowModule appShowModule111 = new AppShowModule();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json1 = jsonArray.getJSONObject( i ).getJSONObject("im:name");
String name = response.getJSONObject("feed").getJSONArray("entry").getJSONObject(i).getJSONObject("im:name").getString("label").toString();
appShowModule111.setAppName(name);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e( "LOG", error.toString() );
}
} );
requestQueue = Volley.newRequestQueue( getContext() );
requestQueue.add(jsonObjectRequest);
AppRecyclerView.setLayoutManager(new LinearLayoutManager(context));
AppRecyclerViewadapter = new ListViewAdapter(appShowModule,getContext() );
AppRecyclerView.setAdapter(AppRecyclerViewadapter);
}
}
And this is my adapter
public class ListViewAdapter extends RecyclerView.Adapter<ListViewAdapter.ViewHolder> {
Context context;
List<AppShowModule> getDataAdapter;
public ListViewAdapter(List<AppShowModule> getDataAdapter, Context context){
super();
this.getDataAdapter = getDataAdapter;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.appitem, parent, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position)
{
final AppShowModule getDataAdapter1 = getDataAdapter.get( position );
holder.NameTextView.setText( getDataAdapter1.getAppName() );
Picasso.with( context ).load( getDataAdapter1.getAppImageUrl() ).into( holder.imgPost );
}
#Override
public int getItemCount() {
return getDataAdapter.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView NameTextView;
public ImageView imgPost;
LinearLayout lnrLayout;
public ViewHolder(View itemView) {
super(itemView);
NameTextView = (TextView) itemView.findViewById(R.id.appName);
imgPost = (ImageView) itemView.findViewById(R.id.appImage);
lnrLayout = (LinearLayout)itemView.findViewById(R.id.lnrLayout);
}
}
}
And this is my module
public class AppShowModule
{
private String appName;
private String appImageUrl;
public String getAppName() {
return appName;}
public void setAppName(String appName) {
this.appName = appName;}
public String getAppImageUrl() {
return appImageUrl;}
public void setAppImageUrl(String appImageUrl) {
this.appImageUrl = appImageUrl;}
}
I think you should not initialize your adapter when you get a response from the web service. Do it on activity create and when you get your data, update the adapter.
I am using RecyclerView to display my products, problem is when if I select the first products and scroll down to the end of list I see different products selected and when i scroll back to top of list the first item is not selected.
My Adapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.MyViewHolder> {
String u = "http://192.185.52.231/~sabby070/hyype/";
Context context1;
private java.util.List<ProductDetails> List;
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_list, parent, false);
return new MyViewHolder(itemView);
}
public RecyclerAdapter(List<ProductDetails> DataList, FragmentActivity activity) {
this.List = DataList;
context1 = activity;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView Likecount;
public ImageView Image;
public ImageView Imagelike, ImageUnlike;
public MyViewHolder(View view) {
super(view);
Likecount = (TextView) view.findViewById(R.id.textView_itemPrice);
Image = (ImageView) view.findViewById(R.id.imageView_imgtosold);
Imagelike = (ImageView)view.findViewById(R.id.Like_Button);
ImageUnlike = (ImageView)view.findViewById(R.id.UnLike_Button);
}
}
#Override
public void onBindViewHolder(final RecyclerAdapter.MyViewHolder holder, final int position) {
final ProductDetails detail = List.get(position);
holder.Likecount.setText(detail.getLikeCount());
Glide.with(context1).load(u+detail.getImage()).override(600, 200).diskCacheStrategy(DiskCacheStrategy.ALL).into(holder.Image);
holder.Image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(context1, ""+position, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(context1, Buy_Product.class);
intent.putExtra("Product Name",detail.getLikeCount());
intent.putExtra("Product Image",detail.getImage());
context1.startActivity(intent);
}
});
holder.Imagelike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.Imagelike.getVisibility()==View.VISIBLE)
{
holder.Imagelike.setVisibility(View.GONE);
holder.ImageUnlike.setVisibility(View.VISIBLE);
}
}
});
holder.ImageUnlike.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.ImageUnlike.getVisibility()==View.VISIBLE)
{
holder.Imagelike.setVisibility(View.VISIBLE);
holder.ImageUnlike.setVisibility(View.GONE);
}
}
});
}
#Override
public int getItemCount() {
return List.size();
}
}
My class
public class Men_Fragment extends Fragment {
static String URL = "http://192.185.52.231/~sabby070/hyype/index.php?action=timeline&user_id=53&post_category=timeline";
private List<ProductDetails> DataList = new ArrayList<>();
private RecyclerView recyclerView;
private RecyclerAdapter rAdapter;
String img;
String a;
Boolean list[];
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_men_, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.men_recycler_view);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
for (int i = 0; i < response.length(); i++) {
JSONObject obj = jsonObject.getJSONObject(String.valueOf(i));
a = obj.getString("like_count");
img = obj.getString("video_thumb");
final ProductDetails details = new ProductDetails(a, img);
DataList.add(details);
rAdapter = new RecyclerAdapter(DataList, getActivity());
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(rAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "" + error, Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
return view;
}
}
You have to take List(with boolean) and store selected values in that list and then use those values in onBindView()
In your ProductDetails class add a field boolean selected;
In your onClick() add List.get(position).setSelected(!List.get(position).isSelected()); to check/uncheck as needed.
Finaly in your onBindViewHolder(...) add
if(List.get(position).isSelected()){
holder.Imagelike.setVisibility(View.VISIBLE);
}else{
holder.ImageUnlike.setVisibility(View.GONE);
}
I have an adapter which won't get notified after fetching new data by Retrofit however, I'm using notifyDataSetChanged and get success in the logs but nothing works either :(
Also I tried to use local array with this adapter and it works great.
public class alberrClassNews extends Fragment {
private RecyclerView recyclerView;
private List<alberrNewsListContent> alberrNews = new ArrayList<alberrNewsListContent>();
private final String TAG = "Get JSONArray";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.alberrnewsclass, container, false);
getActivity().setTitle("nnnn");
recyclerView = (RecyclerView) view.findViewById(R.id.alberrNewsList);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(layoutManager);
layoutManager.setReverseLayout(true);
layoutManager.setStackFromEnd(true);
final alberrNewsAdapter aNA = new alberrNewsAdapter(getActivity(), alberrNews);
recyclerView.setAdapter(aNA);
final ProgressDialog progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("loading");
progressDialog.show();
final Retrofit alberrRetrofit = new Retrofit.Builder()
.baseUrl("http://nn.com/abbn/")
.addConverterFactory(GsonConverterFactory.create()).build();
alberrService service = alberrRetrofit.create(alberrService.class);
Call<JSONArray> call = service.alberrNews();
call.enqueue(new Callback<JSONArray>() {
#Override
public void onResponse(Call<JSONArray> call, Response<JSONArray> response) {
progressDialog.dismiss();
Log.i(TAG, "success");
try{
JSONArray jsonArray = response.body().getJSONArray(0);
for (int i = 0 ; i < jsonArray.length() ; i++){
JSONObject jsonObject = jsonArray.getJSONObject(i);
alberrNewsListContent newsContent = new alberrNewsListContent();
newsContent.setAlberrNewsTitle(jsonObject.getString("title"));
newsContent.setAlberrNewsSubject(jsonObject.getString("subject"));
newsContent.setAlberrNewsImage(jsonObject.getString("image"));
alberrNews.add(newsContent);
}
} catch (JSONException e){
e.printStackTrace();
}
aNA.notifyDataSetChanged();
}
#Override
public void onFailure(Call<JSONArray> call, Throwable t) {
Log.i(TAG, "Failed");
progressDialog.dismiss();
Toast.makeText(getActivity().getApplicationContext(),
"no connection", Toast.LENGTH_SHORT).show();
}
});
return view;
}
Adapter Class
public class alberrNewsAdapter extends RecyclerView.Adapter<alberrNewsAdapter.ViewHolder> {
private List<alberrNewsListContent> newsListContent;
private Context context;
public alberrNewsAdapter(Context ncontext , List<alberrNewsListContent> nnewsListContent ){
this.context = ncontext;
this.newsListContent = nnewsListContent;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater
.from(parent.getContext())
.inflate(R.layout.alberrnewscontent, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(alberrNewsAdapter.ViewHolder holder, int position) {
final alberrNewsListContent newsContent = newsListContent.get(position);
holder.alberrNewsTitle.setText(newsContent.getAlberrNewsTitle());
holder.alberrNewsSubject.setText(newsContent.getAlberrNewsSubject());
Glide.with(context)
.load(newsContent.getAlberrNewsImage())
.override(300, 260)
.into(holder.alberrNewsImage);
}
#Override
public int getItemCount() {
return newsListContent.size();
}
public void replaceDataSet(List<alberrNewsListContent> alberrNews){
this.newsListContent = alberrNews;
notifyDataSetChanged();
}
public static class ViewHolder extends RecyclerView.ViewHolder{
TextView alberrNewsTitle;
TextView alberrNewsSubject;
ImageView alberrNewsImage;
CardView alberrNewsCardView;
public ViewHolder(View itemView) {
super(itemView);
alberrNewsTitle = (TextView)itemView.findViewById(R.id.alberrNewsTitle);
alberrNewsSubject = (TextView)itemView.findViewById(R.id.alberrNewsSubject);
alberrNewsImage = (ImageView)itemView.findViewById(R.id.alberrNewsImage);
alberrNewsCardView = (CardView)itemView.findViewById(R.id.alberrNewsCardView);
}
}
}
In your alberrNewsAdapter, you can create a new method called replaceDataSet() which will replace your dataset in the adapter and call notifyDataSetChanged().
private List<alberrNewsListContent> alberrNews alberrNews;
public void replaceDataSet(List<alberrNewsListContent> alberrNews){
this.alberrNews = alberrNews;
notifyDataSetChanged();
}
And in onResponse() instead of calling aNA.notifyDataSetChanged(); call aNA.replaceDataSet();
Pass new list content to the adapter via public method and call notifyDataSetChanged(); inside that method. Currently, you're not updating the list inside the adapter.