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.
Related
Howdy, I'm working on a project and I'm running into some issues. Namely, I have two fragments, each with their own adapter as both fragments are meant to be able to swipe horizontally. A photo should be attached of the layout I have for further clarity. I would like to be able to tap the bottom fragment, which when I tap a place on the top fragment, the image I tapped or "Structure" will be placed down. However, what I can't figure out is how to smoothly transfer this data and if I were to do it through the activity, how do I do it as the activity has already run through all its code. Could somebody please help, it would be greatly appreciated.
Main Activity
public class MainMap extends AppCompatActivity
{
MapData data = MapData.get();
StructureData structure = StructureData.get();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main_map);
FragmentManager frag = getSupportFragmentManager(); //To manage the map fragment
MapCellFragment rv = (MapCellFragment) frag.findFragmentById(R.id.map);
FragmentManager selectionFrag = getSupportFragmentManager(); //To manage the selection fragment
SelectionCellFragment cf = (SelectionCellFragment) selectionFrag.findFragmentById(R.id.bar);
if (rv == null)
{
rv = new MapCellFragment(data);
frag.beginTransaction().add(R.id.map, rv).commit();
}
if (cf == null)
{
cf = new SelectionCellFragment(structure);
selectionFrag.beginTransaction().add(R.id.bar, cf).commit();
}
}
Map Fragment
public MapData data;
public MapCellFragment() {
// Required empty public constructor
}
public MapCellFragment(MapData data)
{
this.data = data;
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment gridCellFragment.
*/
// TODO: Rename and change types and number of parameters
public static MapCellFragment newInstance(String param1, String param2) {
MapCellFragment fragment = new MapCellFragment();
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);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.map_fragment, container, false);
RecyclerView rv = (RecyclerView) view.findViewById(R.id.recyclerview);
rv.setLayoutManager(new GridLayoutManager(getActivity(), MapData.HEIGHT, GridLayoutManager.HORIZONTAL,false));
MapAdapter myAdapter = new MapAdapter(data);
rv.setAdapter(myAdapter);
return view;
}
Bottom Bar Fragment
This was essentially a copy and paste of the other fragment, just changing the data which goes in and the XML it's attached to.
Map Adapter
package com.example.map;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MapAdapter extends RecyclerView.Adapter<MapViewHolder>
{
MapData data;
public MapAdapter(MapData data)
{
this.data = data;
}
#NonNull
#Override
public MapViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.grid_cells,parent,false);
//Resizes the images within the grid cells xml file
int size = parent.getMeasuredHeight() / MapData.HEIGHT + 1;
ViewGroup.LayoutParams lp = view.getLayoutParams();
lp.width = size;
lp.height = size;
MapViewHolder myViewHolder = new MapViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull MapViewHolder holder, int position)
{
int row = position % MapData.HEIGHT;
int col = position / MapData.HEIGHT;
MapElement ele = data.get(row, col);
holder.ne.setImageResource(ele.getNorthEast());
holder.nw.setImageResource(ele.getNorthWest());
holder.se.setImageResource(ele.getSouthEast());
holder.sw.setImageResource(ele.getSouthWest());
if(ele.getStructure() != null)
{
holder.mapStruct.setImageResource(ele.getStructure().getDrawableId());
}
}
#Override
public int getItemCount()
{
return 300;
}
}
Map View Holder
package com.example.map;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Objects;
public class MapViewHolder extends RecyclerView.ViewHolder {
ImageView nw;
ImageView ne;
ImageView sw;
ImageView se;
ImageView mapStruct;
public MapViewHolder(#NonNull View itemView)
{
super(itemView);
nw = itemView.findViewById(R.id.northWest);
ne = itemView.findViewById(R.id.northEast);
sw = itemView.findViewById(R.id.southWest);
se = itemView.findViewById(R.id.southEast);
mapStruct = itemView.findViewById(R.id.structure);
}
}
Bar Adapter
package com.example.map;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SelectionAdapter extends RecyclerView.Adapter<SelectionViewHolder>
{
StructureData data;
public SelectionAdapter(StructureData data)
{
this.data = data;
}
#NonNull
#Override
public SelectionViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType)
{
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.list_selection,parent,false);
SelectionViewHolder myViewHolder = new SelectionViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(#NonNull SelectionViewHolder holder, int position)
{
Structure s = data.get(position);
holder.structure.setImageResource(s.getDrawableId());
holder.label.setText(s.getLabel());
holder.bind(s);
}
#Override
public int getItemCount()
{
return data.size();
}
}
Bar ViewHolder
package com.example.map;
import android.annotation.SuppressLint;
import android.util.Log;
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 java.util.Objects;
public class SelectionViewHolder extends RecyclerView.ViewHolder
{
Structure selectObject;
ImageView structure;
TextView label;
public SelectionViewHolder(#NonNull View itemView)
{
super(itemView);
structure = itemView.findViewById(R.id.image);
label = itemView.findViewById(R.id.label);
structure.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
SelectionCellFragment.selectedData = selectObject;
}
});
}
public void bind(Structure s)
{
selectObject = s;
}
//Maybe, I need to place this bind function in MapViewHolder as well
//When I press on the button, I must share the information over to the Map fragment
//Then the new information will form a ImageView on the big one
}
You could use ViewModel to solve your use-case. You could have something like SelectedStructureViewModel that will be set in the SelectionCellFragment when the user taps to select the structure. While the MapCellFragment can observe this SelectedStructureViewModel to be notified whenever the user selects the structure. You can then query it when user taps a place on the Map.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 1 year ago.
I have utilized mContext through "recyclerAdapter = new RecyclerAdapter(mContext, placeList);" but at the variable declaration, android studio mentioned that it was never assigned. What is the error here?
The main purpose of this is so that I can retrieve both text and images from firebase to android studio.
package com.example.myapplication;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
//firebase
//FirebaseDatabase firebaseDatabase;
private DatabaseReference myRef;
//Widgets
RecyclerView recyclerView;
//variables
private ArrayList<Place> placeList;
private RecyclerAdapter recyclerAdapter;
private Context mContext;//Private field 'mContext' is never assigned
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//set recyclerView
recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager LayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(LayoutManager);
recyclerView.setHasFixedSize(true);
//set Firebase
myRef = FirebaseDatabase.getInstance().getReference();
//set arraylist
placeList = new ArrayList<>();
//get a data method
GetDataFromFirebase();
//Clear Arraylist
ClearAll();
}
//this is data method
private void GetDataFromFirebase() {
Query query = myRef.child("places1");
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
ClearAll();
for (DataSnapshot ds: snapshot.getChildren()){
Place place = new Place();
place.setImage(ds.child("image").getValue().toString()); //place image to "image:"
place.setName(ds.child("name").getValue().toString());
place.setLocation(ds.child("location").getValue().toString());
placeList.add(place);
}
recyclerAdapter = new RecyclerAdapter(mContext, placeList);//mContext is being used here
recyclerView.setAdapter(recyclerAdapter);
recyclerAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
private void ClearAll(){
if (placeList != null){
placeList.clear();
if(recyclerAdapter!=null){
recyclerAdapter.notifyDataSetChanged();
}
}
placeList = new ArrayList<>();
}
}
mContext was also used in my another class file called RecyclerAdapter.java
package com.example.myapplication;
import android.content.Context;
import android.icu.text.Transliterator;
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.bumptech.glide.Glide;
import java.util.ArrayList;
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
private static final String Tag = "RecyclerView";
private Context mContext;
private ArrayList<Place> placeList;
public RecyclerAdapter(Context mContext, ArrayList<Place> placeList) {
this.mContext = mContext;
this.placeList = placeList;
}
#NonNull
#Override
public RecyclerAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//call viewholder to place the data in this template
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.place_info, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//get textview
holder.textView1.setText(placeList.get(position).getName());
holder.textView2.setText(placeList.get(position).getName());
//image view using glide lib
Glide.with(mContext)
.load(placeList.get(position).getImage())
.into(holder.imageView); //diaply into image view
}
#Override
public int getItemCount() {
return placeList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
//widgets
ImageView imageView;
TextView textView1;
TextView textView2;
public ViewHolder(#NonNull View itemView) {
super(itemView);
imageView =itemView.findViewById(R.id.imageView);
textView1=itemView.findViewById(R.id.textViewName);
textView2=itemView.findViewById(R.id.textViewLocation);
}
}
}
Replace this:
Glide.with(mContext)
.load(placeList.get(position).getImage())
.into(holder.imageView);
with this:
Glide.with(holder.itemView.getContext())
.load(placeList.get(position).getImage())
.into(holder.imageView);
After doing this, you no longer need the "mContext" :)
(Neither in the constructor nor in the class)
Please let me know if this works.
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.
I want to build an app by which I can generate bussiness card. So I use navigaion drawer. For navigating menus I use fragment class for each of the menus and corresponding XML layout. In one of the layout I want to show my card view inside recyclerview.
MycardFragment.java
(This is the fragment class where I want show recyclerview)
package com.example.look.np.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
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.ListAdapter;
import android.widget.TextView;
import com.example.look.np.R;
import com.example.look.np.models.Template;
import com.example.look.np.utils.FirebaseMethod;
import com.example.look.np.utils.RecyclerviewAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class MyCardFragment extends Fragment {
private static final String TAG = "MyCardFragment";
private Context mContext;
private RecyclerView recyclerView;
FirebaseDatabase database;
DatabaseReference myRef ;
List<Template> listdata;
public MyCardFragment() {
// Required empty public constructor
}
//i tried this section but it gimes me error
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mycards,container,false);
database = FirebaseDatabase.getInstance();
myRef = database.getReference("template");
// Initialize Template Model Class
Template template = new Template();
// ...
// Lookup the Recycler view in fragment layout
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
// Attach the adapter to the recyclerview to populate items
RecyclerviewAdapter adapter = new RecyclerviewAdapter(template,inflater.getContext());//>>>This is the error i'm facig
// Set layout manager to position the items
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
listdata = new ArrayList<Template>();
for(DataSnapshot dataSnapshot1 :dataSnapshot.child("template").getChildren()){
Template value = dataSnapshot1.getValue(Template.class);
Template fire = new Template();
String name = value.getP_name();
String desig = value.getP_designation();
String email = value.getP_email();
String phone = value.getP_phone();
String address = value.getC_address();
String c_name = value.getC_name();
fire.setP_name(name);
fire.setP_designation(desig);
fire.setP_email(email);
fire.setP_phone(phone);
fire.setC_name(c_name);
fire.setC_address(address);
listdata.add(fire);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Failed to read value
Log.w("Hello", "Failed to read value.", databaseError.toException());
}
});
return view;
}
#Override
public void onStart() {
super.onStart();
}
}
I aslo created an adapter for recycler view, when I want to set the adapter to the fragment class it shows error. It takes context and List. For context I add getActivity() bMycardFragment.java
(This is the fragment class where I want show recyclerview)
package com.example.look.np.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
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.ListAdapter;
import android.widget.TextView;
import com.example.look.np.R;
import com.example.look.np.models.Template;
import com.example.look.np.utils.FirebaseMethod;
import com.example.look.np.utils.RecyclerviewAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class MyCardFragment extends Fragment {
private static final String TAG = "MyCardFragment";
private Context mContext;
private RecyclerView recyclerView;
FirebaseDatabase database;
DatabaseReference myRef ;
List<Template> listdata;
public MyCardFragment() {
// Required empty public constructor
}
//i tried this section but it gimes me error
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mycards,container,false);
database = FirebaseDatabase.getInstance();
myRef = database.getReference("template");
// Initialize Template Model Class
Template template = new Template();
// ...
// Lookup the Recycler view in fragment layout
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
// Attach the adapter to the recyclerview to populate items
RecyclerviewAdapter adapter = new RecyclerviewAdapter(template,inflater.getContext());//>>>This is the error i'm facig
// Set layout manager to position the items
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
listdata = new ArrayList<Template>();
for(DataSnapshot dataSnapshot1 :dataSnapshot.child("template").getChildren()){
Template value = dataSnapshot1.getValue(Template.class);
Template fire = new Template();
String name = value.getP_name();
String desig = value.getP_designation();
String email = value.getP_email();
String phone = value.getP_phone();
String address = value.getC_address();
String c_name = value.getC_name();
fire.setP_name(name);
fire.setP_designation(desig);
fire.setP_email(email);
fire.setP_phone(phone);
fire.setC_name(c_name);
fire.setC_address(address);
listdata.add(fire);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Failed to read value
Log.w("Hello", "Failed to read value.", databaseError.toException());
}
});
return view;
}
#Override
public void onStart() {
super.onStart();
}
}
MycardFragment.java
(This is the fragment class where I want show recyclerview)
package com.example.look.np.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
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.ListAdapter;
import android.widget.TextView;
import com.example.look.np.R;
import com.example.look.np.models.Template;
import com.example.look.np.utils.FirebaseMethod;
import com.example.look.np.utils.RecyclerviewAdapter;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class MyCardFragment extends Fragment {
private static final String TAG = "MyCardFragment";
private Context mContext;
private RecyclerView recyclerView;
FirebaseDatabase database;
DatabaseReference myRef ;
List<Template> listdata;
public MyCardFragment() {
// Required empty public constructor
}
//i tried this section but it gimes me error
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_mycards,container,false);
database = FirebaseDatabase.getInstance();
myRef = database.getReference("template");
// Initialize Template Model Class
Template template = new Template();
// ...
// Lookup the Recycler view in fragment layout
recyclerView = view.findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
// Attach the adapter to the recyclerview to populate items
RecyclerviewAdapter adapter = new RecyclerviewAdapter(template,inflater.getContext());//>>>This is the error i'm facig
// Set layout manager to position the items
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
listdata = new ArrayList<Template>();
for(DataSnapshot dataSnapshot1 :dataSnapshot.child("template").getChildren()){
Template value = dataSnapshot1.getValue(Template.class);
Template fire = new Template();
String name = value.getP_name();
String desig = value.getP_designation();
String email = value.getP_email();
String phone = value.getP_phone();
String address = value.getC_address();
String c_name = value.getC_name();
fire.setP_name(name);
fire.setP_designation(desig);
fire.setP_email(email);
fire.setP_phone(phone);
fire.setC_name(c_name);
fire.setC_address(address);
listdata.add(fire);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Failed to read value
Log.w("Hello", "Failed to read value.", databaseError.toException());
}
});
return view;
}
#Override
public void onStart() {
super.onStart();
}
}
I have an adapter class which takes context and List of items. Now I want to set my adapter in a fragment by passing context (getActivity() and List but it shows me error
I tried getActivity() but it show me error
i also tried this
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
//This is adapter class for my Recyclerview
RecyclerAdater.java
package com.example.look.np.utils;
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.TextView;
import com.example.look.np.R;
import com.example.look.np.models.Template;
import java.util.List;
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.MyHolder>{
// ... constructor and member variables
// Usually involves inflating a layout from XML and returning the holder
List<Template> listdata;
Context context;
public RecyclerviewAdapter(List<Template> listdata, Context context) {
this.listdata = listdata;
this.context = context;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Inflate the custom layout
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardview,parent,false);
// Return a new holder instance
MyHolder myHolder = new MyHolder(view);
return myHolder;
}
public void onBindViewHolder(MyHolder holder, int position) {
Template data = listdata.get(position);
holder.pname.setText(data.getP_name());
holder.pdesignation.setText(data.getP_designation());
holder.pemail.setText(data.getP_email());
holder.pphone.setText(data.getP_phone());
holder.cname.setText(data.getC_name());
holder.caddress.setText(data.getC_address());
}
#Override
public int getItemCount() {
//return listdata.size();
int arr = 0;
try{
if(listdata.size()==0){
arr = 0;
}
else{
arr=listdata.size();
}
}catch (Exception e){
e.printStackTrace();
}
return arr;
}
class MyHolder extends RecyclerView.ViewHolder{
// Your holder should contain a member variable
// for any view that will be set as you render a row
TextView pname,caddress,pemail,pdesignation,pphone,cname;
// We also create a constructor that accepts the entire item row
// and does the view lookups to find each subview
public MyHolder(View itemView) {
// Stores the itemView in a public final member variable that can be used
// to access the context from any ViewHolder instance.
super(itemView);
pname = (TextView) itemView.findViewById(R.id.txt_personName);
caddress = (TextView) itemView.findViewById(R.id.txt_address);
pemail = (TextView) itemView.findViewById(R.id.txt_email);
pdesignation = (TextView) itemView.findViewById(R.id.txt_designation);
pphone = (TextView) itemView.findViewById(R.id.txt_phone);
cname = (TextView) itemView.findViewById(R.id.txt_companyName);
}
}
}
Point to be noted, don't forget to set layoutManager to recyclerview and to set adapter.
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL
recyclerview.setLayoutManager(layoutManager);
recyclerview.setHasFixedSize(true);
recyclerviewAdapter adapter = new recyclerviewAdapterAdapter(listdata,getActivity());
recyclerview.setAdapter(adapter);
Another thing to notice in your code is:
There is network call (Which run in background) in oncreateView(). Before it gives result, the return view; is getting called.
This means the view is not updated while on background job is going.
This can be resolved by calling separate method like setRecyclerView() from onCreateView() method. After getting result from background operation you can set your recyclerview as mentioned above.
Don't forget to call the adapter.notifydatasetchanged() method.
I have a recyclerView that must show a list of cards, but it doesn't!
There is an arrayList of recipes get passed to the adapter to display them as cardviews, everything in the debugging seems to be alright, but it doesnt display anything on the screen.
ViewHolder:
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.nd.ameer.bake.R;
public class RecipeViewHolder extends RecyclerView.ViewHolder {
public TextView titleTextView;
public ImageView coverImageView;
public RecipeViewHolder(View v) {
super(v);
titleTextView = (TextView) v.findViewById(R.id.titleTextView);
coverImageView = (ImageView) v.findViewById(R.id.recipeImageView);
}
}
Adapter:
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.bumptech.glide.Glide;
import com.example.nd.ameer.bake.R;
import com.example.nd.ameer.bake.models.Recipe;
import com.example.nd.ameer.bake.views.holders.RecipeViewHolder;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class RecipeAdapter extends
RecyclerView.Adapter<RecipeViewHolder> {
ArrayList<Recipe> recipes = new ArrayList<>();
Context context;
public RecipeAdapter(ArrayList<Recipe> recipes, Context context) {
this.recipes = recipes;
this.context = context;
}
#Override
public RecipeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recipe_item, parent, false);
return new RecipeViewHolder(view);
}
#Override
public void onBindViewHolder(RecipeViewHolder holder, int position) {
holder.coverImageView.setImageResource(R.color.colorPrimaryLight);
holder.titleTextView.setText(recipes.get(position).getName());
}
#Override
public int getItemCount() {
return recipes.size();
}
}
Fragment onCreateView:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_recipe, container, false);
createRecipes();
recyclerView = (RecyclerView) rootView.findViewById(R.id.rv_recipe);
recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
if (recipes.size() > 0 & recyclerView != null) {
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new RecipeAdapter(recipes, getContext()));
}
return rootView;
}
The method createRecipes(); creates a list of recipes and then it get passed to the adapter.
as you can see, the recipes size is 4, so it's not the problem
I didn't know the cause of the problem till now, but I moved both the adapter and the view holder to the Recipes Fragment as inner classes, and this has fixed the problem.