Get values from json in fragment - java

I am trying to get info from a JSON into a card view, I've made this application in a separate project and it works but now i am trying to integrate it with the actual application. I am using fragments for the actual application.
package com.example.loginfirebase.news;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.example.loginfirebase.R;
import com.google.android.gms.common.api.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class NewsFragment extends Fragment {
RecyclerView recyclerView;
List<Anunturi> anunturiLi;
private static String JSON_URL = "";
Adapter adapter;
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public NewsFragment() {
// Required empty public constructor
}
public static NewsFragment newInstance(String param1, String param2) {
NewsFragment fragment = new NewsFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(container==null){
Log.v("Container",": Containerul este null");
}
// Inflate the layout for this fragment
Context aplicationcontext = getActivity().getApplicationContext();
//Context thiscontext = container.getContext();
RecyclerView recyclerView=container.findViewById(R.id.anunturiList);
if (recyclerView==null){
Log.v("recycler view value","is null");
}
Context fragmentcontext=container.getContext();
anunturiLi = new ArrayList<>();
extractAnunturi(aplicationcontext,fragmentcontext);
Log.v("Aplication context", String.valueOf(aplicationcontext));
return inflater.inflate(R.layout.fragment_news, container, false);
}
// public void onViewCreated(View view, Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// RecyclerView recyclerView=view.findViewById(R.id.anunturiList);
//
//
// }
private void extractAnunturi(Context aplicationcontext,Context fragmentcontext) {
//TODO: FIX
Context mContext;
mContext = fragmentcontext;
Log.v("Activity non null","activity:"+getActivity());
RequestQueue queue = Volley.newRequestQueue(getActivity());
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, JSON_URL, null, new com.android.volley.Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject anunturiObject = response.getJSONObject(i);
Anunturi anunturi = new Anunturi();
anunturi.setTitle(anunturiObject.getString("titlu_anunt"));
Log.v("Tag anunturi title:",anunturi.getTitle());
anunturi.setAutor(anunturiObject.getString("autor_anunt".toString()));
Log.v("Tag anunturi title:",anunturi.getAutor());
anunturi.setCoverImage(anunturiObject.getString("cover_image"));
Log.v("Tag anunturi title:",anunturi.getCoverImage());
anunturi.setAnuntURL(anunturiObject.getString("url"));
Log.v("Tag anunturi title:",anunturi.getAnuntURL());
anunturi.setText_anunt(anunturiObject.getString("text_anunt"));
Log.v("Tag anunturi title:",anunturi.getText_anunt());
anunturiLi.add(anunturi);
} catch (JSONException e) {
e.printStackTrace();
}
}
//TODO FIX
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter = new Adapter(getApplicationContext(), anunturiLi);
recyclerView.setAdapter(adapter);
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//nimic
}
});
queue.add(jsonArrayRequest);
}
}
and i get this error
F:\LoginFirebase\app\src\main\java\com\example\loginfirebase\news\NewsFragment.java:127: error: cannot find symbol
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
^
symbol: method getApplicationContext()
I've tried passing context as parametre and changing to:
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
adapter = new Adapter(getActivity().getApplicationContext(), anunturiLi);
recyclerView.setAdapter(adapter);
But i get this error
2021-04-11 19:37:42.632 26960-26960/com.example.loginfirebase D/AndroidRuntime: Shutting down VM
2021-04-11 19:37:42.633 26960-26960/com.example.loginfirebase E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.loginfirebase, PID: 26960
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
at com.example.loginfirebase.news.NewsFragment$1.onResponse(NewsFragment.java:127)
at com.example.loginfirebase.news.NewsFragment$1.onResponse(NewsFragment.java:103)
at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:90)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
The adapter code:
package com.example.loginfirebase.news;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.loginfirebase.R;
import com.squareup.picasso.Picasso;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder>{
LayoutInflater inflater;
List<Anunturi> anunturi;
public Adapter(Context ctx, List<Anunturi> anunturi){
this.inflater= LayoutInflater.from(ctx);
this.anunturi=anunturi;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view=inflater.inflate(R.layout.custom_list_layout,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//bind the data
holder.titlu_anunt.setText(anunturi.get(position).getTitle());
holder.autor_anunt.setText(anunturi.get(position).getAutor());
Picasso.get().load(anunturi.get(position).getCoverImage()).into(holder.img_anunt);
holder.text_anunt.setText(anunturi.get(position).getText_anunt());
}
#Override
public int getItemCount() {
return anunturi.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView titlu_anunt,autor_anunt,text_anunt;
ImageView img_anunt;
public ViewHolder(#NonNull View itemView) {
super(itemView);
titlu_anunt=itemView.findViewById(R.id.anunt_title);
autor_anunt=itemView.findViewById(R.id.anunt_autor);
text_anunt=itemView.findViewById(R.id.txt_anunt);
img_anunt=itemView.findViewById(R.id.anunt_image);
}
}
}
Solution
Had to put the code in onViewCreated
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
RecyclerView recyclerView=view.findViewById(R.id.anunturiList);
//View view = inflater.inflate(R.layout.fragment_news, container, false);
anunturiLi = new ArrayList<>();
extractAnunturi();
}

When you're doing this:
RecyclerView recyclerView=container.findViewById(R.id.anunturiList);
You are assigning the Recycler View to a local variable, so your recyclerView field is still null. When you use it below, it causes the NPE.
You have to assign it to the recyclerView field:
recyclerView=container.findViewById(R.id.anunturiList);

Related

Android studio java can't get context in Fragment

I am absolute beginner for this, I'm sorry if this such a dumb mistakes.
so, I created fragment in which i have got recyclerView, but my recycler view is empty, i saw that my context is empty, and i think, that it can be the reason of this, i try to use getActivity
here is code of my fragment
package com.example.pocketcinema;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.List;
public class SearchFragment extends Fragment implements RecyclerViewInterface {
private RecyclerView recyclerView;
RecyclerViewInterface rci;
MyAdapter myAdapter;
public List<String> nameOfFilm, youTubeUrl, photoUrl, descriptionToFilm, category;
FirebaseFirestore db = FirebaseFirestore.getInstance();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
recyclerView = inflater.inflate(R.layout.fragment_search, container,
false).findViewById(R.id.filmsList);
rci = this;
nameOfFilm = new ArrayList<>();
youTubeUrl = new ArrayList<>();
photoUrl = new ArrayList<>();
descriptionToFilm = new ArrayList<>();
category = new ArrayList<>();
loadFilmsFromDB();
return inflater.inflate(R.layout.fragment_search, container, false);
}
private void loadFilmsFromDB() {
Context context = requireContext();
db.collection("films").get().addOnCompleteListener(new
OnCompleteListener<QuerySnapshot>()
{
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
for (QueryDocumentSnapshot document : task.getResult()) {
nameOfFilm.add(document.get("nameOfFilm").toString());
descriptionToFilm.add(document.get("descriptionToFilm").toString());
photoUrl.add(document.get("imageUrl").toString());
youTubeUrl.add(document.get("videoURL").toString());
category.add(document.get("category").toString());
myAdapter = new MyAdapter(context, nameOfFilm, descriptionToFilm,
photoUrl, youTubeUrl,
rci, category);
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(context));
}
}
});
}
here is screenshot with debuger, you can see that context = null
context = null
here you can see that i set layout for recyclerView
with logcat
here is Adapter
package com.example.pocketcinema;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class MyAdapter extends
RecyclerView.Adapter<MyAdapter.MyViewHolder> {
Context ct;
List<String> name, description, image, video, category;
private final RecyclerViewInterface recyclerViewInterface;
public MyAdapter(Context ct, List<String> nameOfFilm, List<String>
descriptionOfFilm, List<String> imageUrl, List<String> videoUrl,
RecyclerViewInterface rci,List<String> category) {
name = nameOfFilm;
description = descriptionOfFilm;
image = imageUrl;
video = videoUrl;
this.ct = ct;
recyclerViewInterface = rci;
this.category = category;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int
viewType) {
LayoutInflater inflater = LayoutInflater.from(ct);
View view = inflater.inflate(R.layout.my_row, parent, false);
return new MyViewHolder(view, recyclerViewInterface);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int
position) {
holder.nameFilm.setText(name.get(position));
holder.cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(ct, PlayerActivity.class);
}
});
Picasso.get().load(image.get(position)).into(holder.image2);
}
#Override
public int getItemCount() {
return image.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView nameFilm;
ImageView image2;
CardView cardView;
public MyViewHolder(#NonNull View itemView, RecyclerViewInterface
recyclerViewInterface) {
super(itemView);
nameFilm = itemView.findViewById(R.id.nameTV);
image2 = itemView.findViewById(R.id.imageView2);
cardView = itemView.findViewById(R.id.cardView);
itemView.findViewById(R.id.sectionOFRecyclerView).setOnClickListener
(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (recyclerViewInterface != null) {
int pos = getAdapterPosition();
if (pos != RecyclerView.NO_POSITION) {
recyclerViewInterface.onItemClick(pos);
}
}
}
});
}
}
}
myAdapter isn't null
You are trying to create an instance of activity as global variable. That means the context has not been generated yet.
Basically you can just use requireContext() method of Fragment class. This will provide you the context.
As I have mentioned in comment, you need to update your onCreateView method as below:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_search, container, false);
}
Then, you need to initialize your view and other stuff on onViewCreated method. You can update that method like this:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
recyclerView = view.findViewById(R.id.filmsList);
textView = view.findViewById(R.id.test);
rci = this;
nameOfFilm = new ArrayList<>();
youTubeUrl = new ArrayList<>();
photoUrl = new ArrayList<>();
descriptionToFilm = new ArrayList<>();
category = new ArrayList<>();
loadFilmsFromDB();
}
Notes
You don't have to send many string parameters to your adapter. It is better to create a Model class for that item, and send the list of that item. So, model classes will have all the data you need, and you can use them from that model. This will give you better coding style and will let you manage your data easier.
To communicate with your XML layout, you can use ViewBinding or DataBinding for that. This will also help you to use your view elements without creating variables for each of them.

How to inflate another layout inside of another fragment

Hi i tried to inflate my home_items.xml in my application however it doesnt work it just gives me the fragment_home.xml ONLY im wondering how can i fix this? (I can send any part of my code.)
HomeAdapter.java:
package com.example.soulforge.adapter;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.example.soulforge.R;
import com.example.soulforge.model.HomeModel;
import java.util.List;
import java.util.Random;
import de.hdodenhof.circleimageview.CircleImageView;
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.HomeHolder>{
private List<HomeModel> list;
Context context;
public HomeAdapter(List<HomeModel> list, Context context) {
this.list = list;
this.context = context;
}
#NonNull
#Override
public HomeHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_items, parent, false);
return new HomeHolder(view);
}
#Override
public void onBindViewHolder(#NonNull HomeHolder holder, int position) {
holder.userNameTv.setText(list.get(position).getUserName());
holder.timeTv.setText(""+list.get(position).getTimestamp());
int count = list.get(position).getLikeCount();
if(count ==0){
holder.likeCountTv.setVisibility(View.INVISIBLE);
}else if (count == 1){
holder.likeCountTv.setText(count + " like");
}else{
holder.likeCountTv.setText(count + " likes");
}
holder.descriptionTv.setText(list.get(position).getDescription());
Random random = new Random();
int color = Color.argb(255, random.nextInt(256), random.nextInt(256), random.nextInt(256));
Glide.with(context.getApplicationContext())
.load(list.get(position).getProfileImage())
.placeholder(R.drawable.ic_person)
.timeout(6500)
.into(holder.profileImage);
Glide.with(context.getApplicationContext())
.load(list.get(position).getImageUrl())
.placeholder(new ColorDrawable(color))
.timeout(7000)
.into(holder.imageView);
}
#Override
public int getItemCount() {
return list.size();
}
static class HomeHolder extends RecyclerView.ViewHolder{
private CircleImageView profileImage;
private TextView userNameTv, timeTv, likeCountTv, descriptionTv;
private ImageView imageView;
private ImageButton likeBtn, commentBtn, shareBtn;
public HomeHolder(#NonNull View itemView) {
super(itemView);
profileImage = itemView.findViewById(R.id.profileImage);
imageView = itemView.findViewById(R.id.imageView);
userNameTv = itemView.findViewById(R.id.nameTv);
timeTv = itemView.findViewById(R.id.timeTv);
likeCountTv = itemView.findViewById(R.id.likeCountTv);
likeBtn = itemView.findViewById(R.id.likeBtn);
commentBtn = itemView.findViewById(R.id.commentBtn);
shareBtn = itemView.findViewById(R.id.shareBtn);
descriptionTv = itemView.findViewById(R.id.descTv);
}
}
}
Home.java:
package com.example.soulforge.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.soulforge.R;
import com.example.soulforge.adapter.HomeAdapter;
import com.example.soulforge.model.HomeModel;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.EventListener;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.FirebaseFirestoreException;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class Home extends Fragment {
private RecyclerView recyclerView;
HomeAdapter adapter;
private List<HomeModel> list;
private FirebaseUser user;
public Home() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
init(view);
list = new ArrayList<>();
adapter = new HomeAdapter(list, getContext());
recyclerView.setAdapter(adapter);
loadDataFromFirestore();
}
private void init(View view) {
Toolbar toolbar = view.findViewById(R.id.toolbar);
if (getActivity() != null)
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
recyclerView = view.findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
FirebaseAuth auth = FirebaseAuth.getInstance();
user = auth.getCurrentUser();
}
public void loadDataFromFirestore() {
CollectionReference reference = FirebaseFirestore.getInstance().collection("Users")
.document(user.getUid())
.collection("Post Images");
reference.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
if (error != null) {
Log.e("Error: ", error.getMessage());
return;
}
if (value == null)
return;
for (QueryDocumentSnapshot snapshot : value) {
if (!snapshot.exists())
return;
HomeModel model = snapshot.toObject(HomeModel.class);
list.add(new HomeModel(
model.getUserName(),
model.getProfileImage(),
model.getImageUrl(),
model.getUid(),
model.getComments(),
model.getDescription(),
model.getId(),
model.getTimestamp(),
model.getLikeCount()
));
}
adapter.notifyDataSetChanged();
}
});
}
}
Any idea how to fix this? I tried to use inflate however it failed to work as shown it is missing the home items xml enter image description here.
Before you say i have cleared and rebuild and all the FAQ ways to fix this
You're updating wrong list instance
Create one method inside adapter
public updateList(List<HomeModel> list) {
this.list = list;
notifyDataSetChanged()
}
And call it like :
reference.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value, #Nullable FirebaseFirestoreException error) {
...
adapter.updateList(new HomeModel(
model.getUserName(),
model.getProfileImage(),
model.getImageUrl(),
model.getUid(),
model.getComments(),
model.getDescription(),
model.getId(),
model.getTimestamp(),
model.getLikeCount()
));
}
}
});

How to parse only specific data with parseSnapshot?

To put this simple, I have a table called Wishlist in Firebase Database which contains 2 different types of objects: attractions and sights.
Then, in my app I want to show in a fragment only those objects from Wishlist table which are sights. How could I achieve this? Right now, the code is as it follows: (obviously, it will crash if I put return null, but how else could I address this issue?)
package com.example.mytravelapp.Fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.mytravelapp.Adapters.WishlistViewHolder;
import com.example.mytravelapp.Models.Sight;
import com.example.mytravelapp.Models.Wishlist;
import com.example.mytravelapp.R;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.firebase.ui.database.SnapshotParser;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import java.util.ArrayList;
import java.util.List;
/**
* A simple {#link Fragment} subclass.
*/
public class WishlistSightsFragment extends Fragment {
private RecyclerView wishlist;
private DatabaseReference query;
private FirebaseRecyclerAdapter adapter;
private FirebaseUser user;
public WishlistSightsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_wishlist_sights, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
wishlist = view.findViewById(R.id.rvWishlistSights);
wishlist.setHasFixedSize(true);
user = FirebaseAuth.getInstance().getCurrentUser();
GridLayoutManager grid = new GridLayoutManager(getContext().getApplicationContext(), 1);
wishlist.setLayoutManager(grid);
fetch();
}
private void fetch(){
query = FirebaseDatabase.getInstance().getReference("wishlist").child(user.getUid());
FirebaseRecyclerOptions<Wishlist> options =
new FirebaseRecyclerOptions.Builder<Wishlist>()
.setQuery(query, new SnapshotParser<Wishlist>() {
#NonNull
#Override
public Wishlist parseSnapshot(#NonNull DataSnapshot snapshot) {
Wishlist attraction = new Wishlist(snapshot.child("idWishlist").getValue().toString(),
snapshot.child("idAttraction").getValue().toString(),
snapshot.child("name").getValue().toString(),
snapshot.child("description").getValue().toString(),
snapshot.child("image").getValue().toString(),
snapshot.child("type").getValue().toString());
if(attraction.getType().equals("sight")){
return attraction;
}
return null;
}
})
.build();
adapter = new FirebaseRecyclerAdapter<Wishlist, WishlistViewHolder>(options) {
#Override
public WishlistViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.wishlist_design, parent, false);
return new WishlistViewHolder(view);
}
#Override
protected void onBindViewHolder(final WishlistViewHolder holder, final int position, final Wishlist model) {
holder.setDetails(getActivity(), model.getName(), model.getDescription(), model.getIdAttraction(), model.getImage());
}
};
wishlist.setAdapter(adapter);
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onStop() {
super.onStop();
adapter.stopListening();
}
}
I think this query is more useful for you.
query = FirebaseDatabase.getInstance().getReference("wishlist").child(user.getUid()).orderByChild("type").equalTo("sight");
FirebaseRecyclerOptions<Wishlist> options =
new FirebaseRecyclerOptions.Builder<Wishlist>()
.setQuery(query, Wishlist.class)
.build();
You can get the list of wish who have type sight.

Unable to retrieve context in Fragment [duplicate]

This question already has answers here:
Why is my context in my Fragment null?
(4 answers)
Closed 5 years ago.
I tried to find the solution with several resources:
Retrieve Context from a fragment
Using context in a fragment
But I still got the following error:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
Any help will be appreciated. Thanks!
My current codes:
AnalysisActivity.java:
package com.app.component.fragment;
import android.os.Bundle;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import com.material.components.R;
import com.material.components.fragment.FragmentTabsEvents;
import com.material.components.fragment.FragmentTabsPerformance;
import com.material.components.fragment.FragmentTabsRecommendation;
import com.material.components.utils.Tools;
import java.util.ArrayList;
import java.util.List;
public class AnalysisActivity extends AppCompatActivity {
private ViewPager view_pager;
private TabLayout tab_layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_analysis);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Tools.setSystemBarColor(this,R.color.black);
view_pager = findViewById(R.id.view_pager);
setupViewPager(view_pager);
tab_layout = findViewById(R.id.tab_layout);
tab_layout.setupWithViewPager(view_pager);
}
private void setupViewPager(ViewPager viewPager) {
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getSupportFragmentManager());
adapter.addFragment(FragmentTabsPerformance.newInstance(), "PERFORMANCE");
adapter.addFragment(FragmentTabsRecommendation.newInstance(), "RECOMMENDATION");
adapter.addFragment(FragmentTabsEvents.newInstance(), "EVENTS RELATED TO YOU");
viewPager.setAdapter(adapter);
}
private class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public SectionsPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
FragmentTabsPerformance.java:
package com.app.component.fragment;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.material.components.R;
import com.material.components.utils.Tools;
import java.util.ArrayList;
import java.util.List;
import lecho.lib.hellocharts.model.Line;
import lecho.lib.hellocharts.model.LineChartData;
import lecho.lib.hellocharts.model.PointValue;
import lecho.lib.hellocharts.view.LineChartView;
public class FragmentTabsPerformance extends Fragment {
private Context context;
public FragmentTabsPerformance() {
this.context = getActivity().getApplicationContext();
List<PointValue> values = new ArrayList<>();
values.add(new PointValue(0, 2));
values.add(new PointValue(1, 4));
values.add(new PointValue(2, 3));
values.add(new PointValue(3, 4));
//In most cased you can call data model methods in builder-pattern-like manner.
Line line = new Line(values).setColor(Color.BLUE).setCubic(true);
List<Line> lines = new ArrayList<>();
lines.add(line);
LineChartData data = new LineChartData();
data.setLines(lines);
LineChartView chart = new LineChartView(this.getContext());
chart.setLineChartData(data);
}
public static FragmentTabsPerformance newInstance() {
FragmentTabsPerformance fragment = new FragmentTabsPerformance();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_tabs_performance, container, false);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_1), R.drawable.image_8);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_2), R.drawable.image_9);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_3), R.drawable.image_15);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_4), R.drawable.image_14);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_5), R.drawable.image_12);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_6), R.drawable.image_2);
Tools.displayImageOriginal(getActivity(), (ImageView) root.findViewById(R.id.image_7), R.drawable.image_5);
return root;
}
}
This exception occurred since you called the getActivity() in the construction method when the fragment is not attached to an activity. You may refer to the API guides about the lifecycle methods about fragment with activity. In your case, you may use getContext() instead of getActivity() method to get the context of fragment.
getActivity() only available after Fragment is attached to activity. So, getActivity() in Fragment constructor will return null. Check fragment life cycle for more detail

Retrofit RecyclerView not working in tab layout

I've been trying to implement a recycler view inside a fragment which displays parsed data using the retrofit library. Whenever I run the project the lists don't show and the monitor says "E/RecyclerView: No adapter attached; skipping layout". Here is my code:
MainActivity:
package com.example.ahmed.newsapp
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.design.widget.TabLayout;
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int ACTIVITY_NUM = 0;
// TODO - insert your themoviedb.org API KEY here
private final static String API_KEY = "<API KEY CENSORED>";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Find the view pager that will allow the user to swipe between fragments
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
// Create an adapter that knows which fragment should be shown
FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager
());
// Set the adapter onto the view pager
viewPager.setAdapter(adapter);
TabLayout ob=(TabLayout) findViewById(R.id.sliding_tabs);
ob.setupWithViewPager(viewPager);
}
}
FragmentAdapter:
package com.example.ahmed.newsapp;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* Created by ahmed on 3/22/2017.
*/
public class FragmentAdapter extends FragmentPagerAdapter {
private String tabs[]=new String[]{"Home","Family Members","Colors"};
public FragmentAdapter(FragmentManager fm){
super(fm);
}
#Override
public Fragment getItem(int position) {
switch(position){
case 0:
return new HomeActivity();
case 1:
return new HomeActivity();
/* case 2:
return new ColorFragment();*/
}
return null;
}
#Override
public CharSequence getPageTitle(int position) {
return tabs[position];
}
#Override
public int getCount() {
return 2;
}
}
NewsAdapter:
package com.example.ahmed.newsapp;
/**
* Created by ahmed on 27-08-17.
*/
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.List;
public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {
private List<News> news;
private int rowLayout;
private Context context;
public static class NewsViewHolder extends RecyclerView.ViewHolder {
LinearLayout moviesLayout;
TextView movieTitle;
TextView data;
TextView movieDescription;
TextView rating;
public NewsViewHolder(View v) {
super(v);
moviesLayout = (LinearLayout) v.findViewById(R.id.movies_layout);
movieTitle = (TextView) v.findViewById(R.id.title);
data = (TextView) v.findViewById(R.id.subtitle);
movieDescription = (TextView) v.findViewById(R.id.description);
rating = (TextView) v.findViewById(R.id.rating);
}
}
public NewsAdapter(List<News> news, Context context) {
this.news = news;
// this.rowLayout = rowLayout;
this.context = context;
}
#Override
public NewsViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item_news, parent, false);
return new NewsViewHolder(view);
}
#Override
public void onBindViewHolder(NewsViewHolder holder, final int position) {
holder.movieTitle.setText(news.get(position).getTitle());
holder.data.setText(news.get(position).getReleaseDate());
holder.movieDescription.setText(news.get(position).getOverview());
holder.rating.setText(news.get(position).getVoteAverage().toString());
}
#Override
public int getItemCount() {
return news.size();
}
}
HomeActivity:
package com.example.ahmed.newsapp;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static android.content.ContentValues.TAG;
public class HomeActivity extends Fragment {
RecyclerView recyclerView;
private final static String API_KEY = "<API KEY CENSORED>";
NewsAdapter adapter;
List<News> news,dummy;
View rootview;
public HomeActivity() {
// Required empty public constructor
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootview = inflater.inflate(R.layout.activity_home, container, false);
if (API_KEY.isEmpty()) {
Toast.makeText(getContext(), "Please obtain your API KEY first from themoviedb.org", Toast.LENGTH_LONG).show();
return rootview;
}
ApiInterface apiService =
ApiClient.getClient().create(ApiInterface.class);
recyclerView = (RecyclerView) rootview.findViewById(R.id.home_page_recycler_view);
adapter= new NewsAdapter(dummy,getContext());
Call<NewsResponse> call = apiService.getTopRatedMovies(API_KEY);
call.enqueue(new Callback<NewsResponse>() {
#Override
public void onResponse(Call<NewsResponse> call, Response<NewsResponse> response) {
news = response.body().getResults();
adapter.notifyDataSetChanged();
adapter=new NewsAdapter(news,getContext());
recyclerView.setAdapter(adapter);
// adapter.setData(news);
Log.d(TAG, "Number of movies received: " + news.size());
}
#Override
public void onFailure(Call<NewsResponse> call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
return rootview;
}
}
i think the problem is in your FragmentAdapter class
just remove return null; statement from your FragmentAdapter like below code
#Override
public Fragment getItem(int position) {
Fragment fragment=null;
switch(position){
case 0:
fragment= new HomeActivity();
case 1:
fragment= new HomeActivity();
/* case 2:
return new ColorFragment();*/
}
return fragment;
}
change this
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
recyclerView = (RecyclerView) rootview.findViewById(R.id.home_page_recycler_view);
adapter= new NewsAdapter(dummy,getContext());
You don't need to recreate your adapter when you receive response.
It may looks like:
recyclerView = (RecyclerView) rootview.findViewById(R.id.home_page_recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new NewsAdapter(null, getActivity());
recyclerView.setAdapter(adapter);
Call<NewsResponse> call = apiService.getTopRatedMovies(API_KEY);
call.enqueue(new Callback<NewsResponse>() {
#Override
public void onResponse(Call<NewsResponse> call, Response<NewsResponse> response) {
news = response.body().getResults();
adapter.setData(news);
Log.d(TAG, "Number of movies received: " + news.size());
}
...
And in NewsAdapter:
...
public void setData(Collection<News> newData) {
news.clear();
news.addAll(newData);
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return news == null ? 0 : news.size();
}
...

Categories