I am facing these problem about Recyclerview No adapter attached.
This is my Locat:
E/RecyclerView: No adapter attached; skipping layout
D/OpenGLRenderer: eglDestroySurface = 0x730c9a02d0
D/ViewRootImpl#8aa7e83[AddPostActivity]: Relayout returned: old=[0,0]
[1080,1920] new=[0,0][1080,1920] result=0x5 surface={valid=false 0}
changed=true
W/ClassMapper: No setter/field for YtyKXov13lReyirA8U4iritiUs6220-July-
201910: 39 found on class gurungdinesh.com.sisapen.ModelPost
W/ClassMapper: No setter/field for pdMZtSaxkzd5Uul592qwXKawnaI220-July-
201910: 40 found on class gurungdinesh.com.sisapen.ModelPost
D/FA: Connected to remote service
V/FA: Processing queued up service tasks: 4
I/zygote64: Do partial code cache collection, code=498KB, data=332KB
I/zygote64: After code cache collection, code=498KB, data=332KB
I/zygote64: Increasing code cache capacity to 2MB
D/ViewRootImpl#f8f3e40[MainActivity2]: MSG_RESIZED_REPORT: frame=Rect(0,
0 - 1080, 1920) ci=Rect(0, 72 - 0, 0) vi=Rect(0, 72 - 0, 0) or=1
MSG_WINDOW_FOCUS_CHANGED 1
This is my Adapter:
public class AdapterPost extends
RecyclerView.Adapter<AdapterPost.MyHolder> {
Context context;
List<ModelPost> postList;
public AdapterPost(Context context, List<ModelPost>postList) {
this.context = context;
this.postList = postList;
}
#NonNull
#Override
public MyHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int
viewType) {
//inflate layout
View view =
LayoutInflater.from(context).inflate(R.layout.activity_users_posts,
viewGroup, false);
return new MyHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyHolder myHolder, int i) {
//get data
String fullname = postList.get(i).getFullname();
String date = postList.get(i).getDate();
String time = postList.get(i).getTime();
String Title = postList.get(i).getTitle();
String Writing = postList.get(i).getWriting();
//set data
myHolder.uNameTv.setText(fullname);
myHolder.pTimeTv.setText(time);
myHolder.pDate.setText(date);
myHolder.pTitileTv.setText(Title);
myHolder.pWritingTv.setText(Writing);
}
#Override
public int getItemCount() {
return postList.size();
}
//view holder class
class MyHolder extends RecyclerView.ViewHolder
{
//views from users post
ImageButton moreBtn;
CircularImageView uPictureIv;
TextView uNameTv, pTimeTv, pTitileTv, pWritingTv, pLikesTv, pDate;
Button likebtn, commentBtn, shareBtn;
private MyHolder(#NonNull View itemView) {
super(itemView);
//init views
uPictureIv = itemView.findViewById(R.id.uPictureTv);
uNameTv = itemView.findViewById(R.id.uNameTv);
pTimeTv = itemView.findViewById(R.id.pTimeTv);
moreBtn = itemView.findViewById(R.id.moreBtn);
pDate = itemView.findViewById(R.id.pDateTv);
pTitileTv = itemView.findViewById(R.id.pTitleTv);
pWritingTv = itemView.findViewById(R.id.pWriting);
pLikesTv = itemView.findViewById(R.id.pLikesTv);
likebtn = itemView.findViewById(R.id.likeBtn);
commentBtn = itemView.findViewById(R.id.commentBtn);
shareBtn = itemView.findViewById(R.id.shareBtn);
}
This is my HomeFragment:
public class HomeFragment extends Fragment {
private FirebaseAuth mFirebase;
private DatabaseReference databaseReference;
private RecyclerView recyclerView;
private List<ModelPost> postList;
private AdapterPost adapterPost;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.home_activity, container,
false);
//init
mFirebase = FirebaseAuth.getInstance();
databaseReference =
FirebaseDatabase.getInstance().getReference("posts");
recyclerView = view.findViewById(R.id.all_user_post_list);
LinearLayoutManager layoutManager = new
LinearLayoutManager(getActivity());
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
postList = new ArrayList<>();
loadPosts();
return view;
}
private void loadPosts() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelPost modelPost = ds.getValue(ModelPost.class);
postList.add(modelPost);
//adapter
adapterPost = new AdapterPost(getActivity(), postList);
//set adapter to RecyclerView
recyclerView.setAdapter(adapterPost);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//in case of error
Toast.makeText(getActivity(), "" +
databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
I have tried so many things but nothing happen.
Since Firebase Tasks are Async the setAdapter method is called after your return view; in onCreateView method. That's why it gives the error No adapter attached. What you can do is call setAdapter in the onCreateView method and after you have populated the list, call notifyDataSetChanged(). See the code below
public class HomeFragment extends Fragment {
private FirebaseAuth mFirebase;
private DatabaseReference databaseReference;
private RecyclerView recyclerView;
private List<ModelPost> postList;
private AdapterPost adapterPost;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable
ViewGroup container, #Nullable Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.home_activity, container,
false);
//init
mFirebase = FirebaseAuth.getInstance();
databaseReference =
FirebaseDatabase.getInstance().getReference("posts");
recyclerView = view.findViewById(R.id.all_user_post_list);
LinearLayoutManager layoutManager = new
LinearLayoutManager(getActivity());
layoutManager.setStackFromEnd(true);
layoutManager.setReverseLayout(true);
recyclerView.setLayoutManager(layoutManager);
postList = new ArrayList<>();
// ----------- set the adapter here --------------------
adapterPost = new AdapterPost(getActivity(), postList);
recyclerView.setAdapter(adapterPost);
loadPosts();
return view;
}
private void loadPosts() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
postList.clear();
for (DataSnapshot ds : dataSnapshot.getChildren()) {
ModelPost modelPost = ds.getValue(ModelPost.class);
postList.add(modelPost);
}
// ----------- call notifyDataSetChanged --------------------
adapterPost.notifyDataSetChanged()
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
//in case of error
Toast.makeText(getActivity(), "" +
databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}
You get this message because RecyclerView has no adapter set when the layout is drawn.
What you can do is that you can assign an empty adapter at start, i.e. in onCreateView(), then add the data to your adapter when you have it. This way you will not see this log. However, the first place you set the adapter is in a asynchronous code block. Everything is already drawn and the recyclerview hasn't provided an adapter yet, so it prints this log.
Related
I'm creating app with Firebase implementation. Now I'm stuck with showing list of data using recyclerView. After using my code I have empty activity without any error in Logcat but when turn off my mobile power button and again start then data show on recycleView. Also one thing when I go another activity and open this activity then again show blank page. I need someone's help :(
This is my fragment:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_message, container, false);
// Initialize
recyclerView = view.findViewById(R.id.recycleView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
list = new ArrayList<>();
// For retrieve Chat User ID
databaseReference = FirebaseDatabase.getInstance().getReference().child("Chat");
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for (DataSnapshot ds : snapshot.getChildren()) {
receiveID = ds.getKey();
// Restore Data on model class name UserDataInfo
databaseReference = FirebaseDatabase.getInstance().getReference().child("UsersData").child(receiveID);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
String userName = String.valueOf(snapshot.child("userName").getValue());
String userNumber = String.valueOf(snapshot.child("userPhone").getValue());
String userType = String.valueOf(snapshot.child("userType").getValue());
String userImage = String.valueOf(snapshot.child("userName").getValue());
info = new UserDataInfo(userImage, userType, userNumber, userName, receiveID);
list.add(info);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
// End
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
adapter = new messageListAdapter(list, getContext());
recyclerView.setAdapter(adapter);
}
My Adapter:
public class messageListAdapter extends RecyclerView.Adapter<messageListAdapter.ViewHolder> {
List<UserDataInfo> infoList;
Context context;
public messageListAdapter(List<UserDataInfo> infoList, Context context) {
this.infoList = infoList;
this.context = context;
}
#NonNull
#Override
public messageListAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_list_show_admin, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull messageListAdapter.ViewHolder holder, int position) {
final UserDataInfo userDataInfo = infoList.get(position);
holder.Name.setText(userDataInfo.getUserName());
holder.Number.setText(userDataInfo.getUserPhone());
holder.whichType.setText(userDataInfo.getUserType());
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "ID: " + userDataInfo.getReceiveID(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return infoList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
ImageView Image;
TextView Name, Number, whichType;
LinearLayout linearLayout;
public ViewHolder(#NonNull View itemView) {
super(itemView);
Image = itemView.findViewById(R.id.UserImage);
Name = itemView.findViewById(R.id.Name);
Number = itemView.findViewById(R.id.Number);
whichType = itemView.findViewById(R.id.WhichType);
linearLayout = itemView.findViewById(R.id.Linear_layout);
}
}
}
my Firebase DataBase setup:
Database image
Database image
I am trying to display contacts in a Fragment but the recycler view doesn't show any item. Despite having items in the list recycler view is not showing any item. I am not sure what I have done wrong as the app does not crash when it is running.
Here is The Code
public class UsersFragment extends Fragment {
RecyclerView recyclerView;
UsersAdapter adapter;
List<Users> actualuserList;
List<String> contactsList;
DatabaseReference reference;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_users, container, false);
recyclerView = view.findViewById(R.id.userRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
contactsList = new ArrayList<>();
actualuserList = new ArrayList<>();
return view;
}
private void getContactList() {
Cursor cursor = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC");
while (cursor.moveToNext()) {
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (contactsList.contains(phone)) {
cursor.moveToNext();
} else {
contactsList.add(phone);
}
}
getActualUser();
Log.d("contact: ", String.valueOf(contactsList.size()));
}
private void getActualUser() {
reference = FirebaseDatabase.getInstance().getReference().child("Users");
for (String number : contactsList) {
Query query = reference.orderByChild("phoneNumber").equalTo(number);
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
actualuserList.clear();
if (snapshot.exists()) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users user = dataSnapshot.getValue(Users.class);
actualuserList.add(user);
}
Log.d("actual: ", String.valueOf(actualuserList.size()));
adapter = new UsersAdapter(getContext(), actualuserList);
recyclerView.setAdapter(adapter);
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getContactList();
}
}
In the Log statement, it is showing actual:1 that means there is an item.
Here is Adapter Code
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.ViewHolder> {
Context mContext;
List<Users> mList;
public UsersAdapter(Context mContext, List<Users> mList) {
this.mContext = mContext;
this.mList = mList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.display_contacts, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
final Users users = mList.get(position);
holder.name.setText(users.getUsername());
holder.number.setText(users.getPhoneNumber());
String url = users.getProfilephotoURL();
if (url.equals(""))
holder.circleImageView.setImageResource(R.drawable.ic_user);
else
Glide.with(mContext).load(url).into(holder.circleImageView);
holder.itemView.setOnClickListener(v -> {
Intent intent = new Intent(mContext, ChatActivity.class);
intent.putExtra("name", users.getUsername());
intent.putExtra("firendPhoneNumber", users.getPhoneNumber());
mContext.startActivity(intent);
});
}
#Override
public int getItemCount() {
return mList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView name, number;
CircleImageView circleImageView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.contactName);
number = itemView.findViewById(R.id.contactNumber);
circleImageView = itemView.findViewById(R.id.profilePic);
}
}
}
Logs
2020-07-27 14:52:51.651 25366-25366/com.mycompany.newchatapp D/contact:: 167
2020-07-27 14:52:51.670 25366-25366/com.mycompany.newchatapp E/RecyclerView: No adapter attached; skipping layout
2020-07-27 14:52:51.691 25366-25366/com.mycompany.newchatapp W/ClassMapper: No setter/field for status found on class com.mycompany.newchatapp.Model.Users
2020-07-27 14:52:51.691 25366-25366/com.mycompany.newchatapp D/actual:: 1
2020-07-27 14:52:51.723 25366-25366/com.mycompany.newchatapp W/ClassMapper: No setter/field for status found on class com.mycompany.newchatapp.Model.Users
2020-07-27 14:52:51.723 25366-25366/com.mycompany.newchatapp D/actual:: 1
Any Idea why this is happening?
Seems like you forgot to set adapter.
In onCreateView method put something like:
recyclerView.setAdapter(new UsersAdapter(this.getActivity(), getContactList()));
UPD:
Before that, make getContactList() return relevant dataset. Do not set adapter after initializing recycler view.
Strangely, I've faced this issue very recently and I was using as global List variable as well and the list wasn't empty, even the adpater was not empty but RecyclerView wasn't showing any data until second adpater.notifyDataSetchanged().
I'd found an answer here on this site that said "create a new list variable" and it worked.
Try making the actualUserList a local variable as in your onDataChange(),
public void onDataChange(#NonNull DataSnapshot snapshot) {
List<Users> actualuserList = new ArrayList<>();
if (snapshot.exists()) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
Users user = dataSnapshot.getValue(Users.class);
actualuserList.add(user);
}
Log.d("actual: ", String.valueOf(actualuserList.size()));
adapter = new UsersAdapter(getContext(), actualuserList);
recyclerView.setAdapter(adapter);
}
}
If this doesn't solve your problem, you can also try calling notifyDataSetChanged() after setting up the adapter as adapter.notifyDataSetChanged();.
Also, set the adapter in onCreatedView() and call adapter.notifyDataSetChanged() in this onDataChange().
I am trying to show some items in a RecyclerView and such items are contained in an ArrayList populated with RealtimeDatabase (Firebase) data. This is done every time some changes are detected in the db as follows. The problem is that lstCompany becomes null soon after the addValueEventListener. How can I keep it fulfilled?
public class FragmentCompanies extends Fragment {
View v;
private RecyclerView recyclerView;
private List<Company> lstCompany;
DatabaseReference db;
public FragmentCompanies(){}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
db = FirebaseDatabase.getInstance().getReference();
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
lstCompany = new ArrayList<>();
DataSnapshot ds = dataSnapshot.child("Company");
for (DataSnapshot company: ds.getChildren()){
Map<String, String> currCompany = (Map) company.getValue();
Company c = new Company(currCompany.get("name"), currCompany.get("overview"), currCompany.get("imageURL"));
lstCompany.add(c);
System.out.println(lstCompany);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println(lstCompany);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
v = inflater.inflate(R.layout.fragment_companies,container,false);
System.out.println(lstCompany);
//bind the adapter to the recyclerView
recyclerView = v.findViewById(R.id.companies_recyclerview);
CompaniesRecyAdapter recyAdapter = new CompaniesRecyAdapter(getContext(), lstCompany);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(recyAdapter);
return v;
}
}
The last two println operations return null and it should not happen.
intialize the arraylist in onCreate, and when add data in on onDataChange and notify the adapter that data has been changed
public class FragmentCompanies extends Fragment {
View v;
private RecyclerView recyclerView;
private List<Company> lstCompany;
DatabaseReference db;
public FragmentCompanies(){}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
v = inflater.inflate(R.layout.fragment_companies,container,false);
lstCompany = new ArrayList<>();
System.out.println(lstCompany);
//bind the adapter to the recyclerView
recyclerView = v.findViewById(R.id.companies_recyclerview);
CompaniesRecyAdapter recyAdapter = new CompaniesRecyAdapter(getContext(), lstCompany);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(recyAdapter);
db = FirebaseDatabase.getInstance().getReference();
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
DataSnapshot ds = dataSnapshot.child("Company");
for (DataSnapshot company: ds.getChildren()){
Map<String, String> currCompany = (Map) company.getValue();
Company c = new Company(currCompany.get("name"), currCompany.get("overview"), currCompany.get("imageURL"));
lstCompany.add(c);
System.out.println(lstCompany);
System.out.println(c.getCompanyName);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println(lstCompany);
return v;
}
}
Fragment.java
public class RuteEfectuateFragment extends Fragment {
View v;
RecyclerView mRecyclerView;
FirebaseDatabase mFirebaseDatabase;
DatabaseReference mRef;
private FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter;
final Context context = this.getContext();
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
((ProfileActivity) Objects.requireNonNull(getActivity())).setActionBarTitle("Rute efectuate");
v = inflater.inflate(R.layout.fragment_rute_efectuate, container, false);
mRecyclerView = v.findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mFirebaseDatabase = FirebaseDatabase.getInstance();
mRef = mFirebaseDatabase.getReference("Rute");
return v;
}
#Override
public void onStart() {
super.onStart();
firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(Model.class, R.layout.card_layout, ViewHolder.class, mRef){
#Override
protected void populateViewHolder(ViewHolder viewHolder, Model model, final int position) {
viewHolder.setDetails(getContext(), model.getTaraPlecare(), model.getTaraDestinatie());
viewHolder.itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
// Intent intent = new Intent(Fridge.this, Show.class);
// startActivity(intent);
}
});
}
};
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getActivity(), 1);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}}
Viewholder.java
public class ViewHolder extends RecyclerView.ViewHolder {
private View mView;
public ViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setDetails(Context ctx, String TaraPlecare, String TaraDestinatie){
TextView mTaraPlecare = mView.findViewById(R.id.rTitleTv);
TextView mTaraDestinatie = mView.findViewById(R.id.rDateTv);
mTaraPlecare.setText(TaraPlecare);
mTaraDestinatie.setText(TaraDestinatie);
}}
Can you tell me please why RecyclerView doesn't appear? It appears just when keyboard is opened and I close it and I can't find the reason. If it is necessary I can record how the RecyclerView appears by hiding the keyboard. I tried also tu find a similar question, but I couldn't find.
When using Firebase database and RecyclerView, Firebase database requires to fixed size of RecyclerView be false. I think because Firebase Database is asynchronous and that means RecyclerView will get first an empty adapter and after data is fetched from database, it will be than populated with data.
That affects the size, so if you put fixed size to true it will fail to calculate the size, so that is why it needs false in fixed size. So solution is: mRecyclerView.setHasFixedSize(false);
This is the edited version of my Fragment class inside my main activity. There were some bugs- it was not displaying anything and it was no longer saving the data to the database.
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}
I already got the saving to firebase working perfectly and I'm using the MVC model - I created an adapter, a model and wired it to the main activity but my problem is how to use this model into the onAddValueEventChangedListener();
public class DessertAdapter extendsRecyclerView.Adapter<DessertAdapter.DessertVh> {
private List<Dessert> desserts = new ArrayList<>();
private static final int VIEW_TYPE_EMPTY_LIST_PLACEHOLDER = 0;
private static final int VIEW_TYPE_OBJECT_VIEW = 1;
private Context context;
// TODO: placeholder stuff here
#Override
public int getItemViewType(int position) {
if (desserts.isEmpty()) {
return VIEW_TYPE_EMPTY_LIST_PLACEHOLDER;
} else {
return VIEW_TYPE_OBJECT_VIEW;
}
}
public DessertAdapter(Context context) {
this.context = context;
this.desserts = desserts;
desserts = Dessert.prepareDesserts(
context.getResources().getStringArray(R.array.dessert_names),
context.getResources().getStringArray(R.array.dessert_descriptions),
context.getResources().getStringArray(R.array.dessert_amounts));
}
// TODO: another placeholder stuff here
#Override
public DessertVh onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_dessert, parent, false);
return new DessertAdapter.DessertVh(view);
}
#Override
public void onBindViewHolder(DessertVh holder, int position) {
Dessert dessert = desserts.get(position);
holder.mName.setText(dessert.getName());
holder.mDescription.setText(dessert.getDescription());
holder.mFirstLetter.setText(String.valueOf(dessert.getFirstLetter()));
holder.mPrice.setText(String.valueOf(dessert.getAmount()));
}
#Override
public int getItemCount() {
// if nothing, return null,
// else return the number of items in the list
return desserts == null ? 0 : desserts.size();
}
public static class DessertVh extends RecyclerView.ViewHolder {
private TextView mName;
private TextView mPrice;
private TextView mDescription;
private TextView mFirstLetter;
public DessertVh(View itemView) {
super(itemView);
mName = (TextView) itemView.findViewById(R.id.txt_name);
mPrice = (TextView) itemView.findViewById(R.id.txt_price);
mDescription = (TextView) itemView.findViewById(R.id.txt_desc);
mFirstLetter = (TextView) itemView.findViewById(R.id.txt_firstletter);
}
}
}
main activity where the tabs are displayed
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabs_header);
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this , this )
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
This handles the display of the data
#Override
public void onStart(){
super.onStart();
mFirebaseAuth.addAuthStateListener(firebaseAuthListener);
// load the data from database here
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
}
// maybe this will work?
DummyFragment dummyFragment = new DummyFragment();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
some code missing here but still part of mainactivity
This is the Dummy Fragment Class inside the main activity
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
// possible to put progress dialogue
DessertAdapter adapter = new DessertAdapter(getContext());
recyclerView.setAdapter(adapter);
return view;
}
}
Put the Firebase code inside the Fragment, not the Activity and also pass the dessertList as a param to the DessertAdapter.
Example:
public static class DummyFragment extends Fragment {
int color;
public DummyFragment() {
}
#SuppressLint("ValidFragment")
public DummyFragment(int color) {
this.color = color;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.dummy_fragment, container, false);
final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.dummyfrag_scrollableview);
final FrameLayout frameLayout = (FrameLayout) view.findViewById(R.id.dummyfrag_bg);
frameLayout.setBackgroundColor(color);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getBaseContext());
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
DatabaseReference mDatabaseGig;
final List<Dessert> dessertList;
// get the gig database
mDatabaseGig = FirebaseDatabase.getInstance().getReference("Gig Posts");
dessertList = new ArrayList<>();
DessertAdapter adapter = new DessertAdapter(getContext(), dessertList);
recyclerView.setAdapter(adapter);
mDatabaseGig.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// dessertList.clear();
for(DataSnapshot gigSnapshot: dataSnapshot.getChildren()){
Dessert dessert = gigSnapshot.getValue(Dessert.class);
dessertList.add(dessert);
adapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
// possible to put progress dialogue
return view;
}
}