FirebaseUI populate ListView text not displayed - java

I am populating a ListView of songs using Firebase database and Firebase-UI, all the dependencies are initialized correctly and the app is connected with the database but when it displays the list it doesn't display the text, just empty boxes like that:
When an item is added to the database then a box is added but it doesn't show the text. Here is the code:
Song class:
package com.example.gloriadesideri.animas;
public class Song
{
private String myName;
private String myURL;
private String myAuthor;
public Song(){
/*myName="";
myURL="";
myAuthor="";*/
}
public Song(String Author, String Song, String URL) {
this.myName=Song;
this.myURL=URL;
this.myAuthor=Author;
}
public String getName()
{
return myName;
}
public String getURL()
{
return myURL;
}
public String getAuthor()
{
return myAuthor;
}
public void setName(String name)
{
this.myName=name;
}
public void setURL ( String URL)
{
this.myURL=URL;
}
public void setAuthor(String author)
{
this.myAuthor=author;
}
}
Song Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="20dp"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/songName"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/author"/>
</LinearLayout>
Activity that should have the list view:
package com.example.gloriadesideri.animas;
import android.content.Intent;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseListAdapter;
import com.firebase.ui.database.FirebaseListOptions;
import com.google.firebase.database.ChildEventListener;
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;
import java.util.List;
public class Canzoni extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
{
//nav view parameters
private DrawerLayout cDrawerLayout;
private ActionBarDrawerToggle cToggle;
//list view parameters
private ListView mListView;
//firebase parameters
private FirebaseListAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canzoni);
//nav view code
cDrawerLayout= (DrawerLayout) findViewById(R.id.draw_viewC);
cToggle= new ActionBarDrawerToggle(this, cDrawerLayout,R.string.Open, R.string.Close);
cDrawerLayout.addDrawerListener(cToggle);
cToggle.syncState();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
actionBar.setDisplayHomeAsUpEnabled(true);
NavigationView cNavigationView = (NavigationView) findViewById(R.id.nav_viewC);
if (cNavigationView != null)
{
cNavigationView.setNavigationItemSelectedListener(this);
}
Query mQuery= FirebaseDatabase.getInstance().getReference().child("songs");
mListView= (ListView) findViewById(R.id.canzoni_list);
FirebaseListOptions<Song> mOptions= new FirebaseListOptions.Builder<Song>()
.setLayout(R.layout.song_layout)
.setQuery(mQuery, Song.class)
.setLifecycleOwner(this)
.build();
mAdapter= new FirebaseListAdapter <Song>(mOptions){
#Override
protected void populateView(View v, Song model, int position) {
TextView songName= v.findViewById(R.id.songName);
TextView songAuthor=v.findViewById(R.id.author);
songName.setText(model.getName());
songAuthor.setText(model.getAuthor());
}
};
mListView.setAdapter(mAdapter);
}
#Override
protected void onStart() {
super.onStart();
mAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
mAdapter.stopListening();
}
#Override
public boolean onOptionsItemSelected(MenuItem Item)
{
if(cToggle.onOptionsItemSelected(Item))
{
return true;
}
return super.onOptionsItemSelected(Item);
}
#Override
public boolean onNavigationItemSelected(MenuItem Item)
{
int id = Item.getItemId();
Intent intent;
if (id == R.id.preghiere)
{
intent= new Intent(this, Preghiere.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if ( id== R.id.bans)
{
intent= new Intent(this, Bans.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id== R.id.canzoni)
{
intent= new Intent(this, this.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id==R.id.calendario)
{
intent= new Intent(this, Calendario.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id== R.id.per_riflettere)
{
intent= new Intent(this, perRiflettere.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if( id== R.id.home)
{
intent= new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.draw_viewC);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
layout of the above activity
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Canzoni"
android:id="#+id/draw_viewC">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/canzoni_list">
</ListView>
<android.support.design.widget.NavigationView
android:layout_width="239dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/white"
android:fitsSystemWindows="true"
app:headerLayout="#layout/header"
app:itemIconTint="#color/black"
app:itemTextColor="#color/black"
app:menu="#menu/drawem_menu"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp"
tools:ignore="MissingConstraints"
android:id="#+id/nav_viewC"/>
</android.support.v4.widget.DrawerLayout>
Any suggestion on how to fix this?
Edit:
the database looks like this:
both writing and reading rules are true
Edit
I have changed the private names in the Song class so they are the same as the database.
private String Author;
private String Song;
private String Url;
it starts working the problem is that now it displays just the author
Update 2

I this code fetch the user data from firebase and show data into recycled view.
In layout i used constaraint layout you can change it..
display_data.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvData"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="#+id/dlTvEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Found"
android:textSize="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
then after row_layout bind into recycler view..
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<TextView
android:id="#+id/rlTvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="20dp" />
<TextView
android:id="#+id/rlTvEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="20dp"
app:layout_constraintTop_toBottomOf="#+id/rlTvName" />
<TextView
android:id="#+id/rlTvPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textSize="20dp"
app:layout_constraintTop_toBottomOf="#+id/rlTvEmail" />
</android.support.constraint.ConstraintLayout>
then after make pojo class for user that insert into firebase..
User.java
public class User {
public String name;
public String email;
public String pwd;
// Default constructor required for calls to
// DataSnapshot.getValue(User.class)
public User() {
}
public User(String name, String email,String pwd) {
this.name = name;
this.email = email;
this.pwd=pwd;
}
}
then after make adapter class.
DisplayAllData.java
public class DisplayAllData extends RecyclerView.Adapter<DisplayAllData.ItemViewHolder> {
private List<User> mUserLsit = new ArrayList<>();
private Context mContext;
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new ItemViewHolder(view);
}
public DisplayAllData(Context mContext, List<User> mUserLsit) {
this.mContext = mContext;
this.mUserLsit = mUserLsit;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
User user = mUserLsit.get(position);
holder.mTvName.setText(user.name);
holder.mTvEmail.setText(user.email);
holder.mTvPwd.setText(user.pwd);
}
#Override
public int getItemCount() {
return mUserLsit.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
TextView mTvName, mTvEmail, mTvPwd;
public ItemViewHolder(View itemView) {
super(itemView);
mTvEmail = itemView.findViewById(R.id.rlTvEmail);
mTvName = itemView.findViewById(R.id.rlTvName);
mTvPwd = itemView.findViewById(R.id.rlTvPwd);
}
}
}
then after finally make display class to fetch user record from firebase and bind into recyclerview.
DisplayActivity.java
public class DisplayActivity extends AppCompatActivity {
private RecyclerView mRvData;
private DisplayAllData allDataAdapter;
private DatabaseReference mDatabase;
private TextView mTvEmpty;
private FirebaseDatabase mFirebaseInstance;
private List<User> mUserList = new ArrayList<>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_data);
initView();
}
private void initView() {
mFirebaseInstance = FirebaseDatabase.getInstance();
mDatabase = mFirebaseInstance.getReference("usersDb/UserTable");
mRvData = findViewById(R.id.rvData);
mTvEmpty = findViewById(R.id.dlTvEmpty);
mRvData.setLayoutManager(new LinearLayoutManager(this));
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUserList.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
User user = dataSnapshot1.getValue(User.class);
mUserList.add(user);
}
allDataAdapter = new DisplayAllData(DisplayActivity.this, mUserList);
mRvData.setAdapter(allDataAdapter);
allDataAdapter.notifyDataSetChanged();
if (mUserList.isEmpty())
mTvEmpty.setVisibility(View.VISIBLE);
else
mTvEmpty.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}

After few experiments with code like change this
songName.setText(model.getName());
songAuthor.setText(model.getAuthor());
to this
songName.setText(model.getURL());
songAuthor.setText(model.getAuthor());
I have learned that the problem was really the names I gave to the privates and the names I gave to the get-methods in the Song class. The names of the privates should be the same as the database fields and the names of the methods should be getYourPrivateName().

In your database, you have a property under the name of the song called myAuthor but in the model class, you have the field named Author, both should be the same.
To solve this, you have two solutions. First one would be to delete all the record from your database and add fresh data according to your model class. Make sure that the properties in your database are added using the name od your field that exist in your model class: myName, myURL, myAuthor and NOT Author, Song, Url.
If you are not in testing mode, then just use annotation in your model class like this:
#PropertyName("Song")
private String myName;
#PropertyName("Url")
private String myURL;
#PropertyName("Author")
private String myAuthor;
According to your edited question, you fileds are incorrect. Please how you Song class should look like:
public class Song {
private String author, song, url;
public Song() {}
public Song(String author, String song, String url) {
this.author = author;
this.song = song;
this.url = url;
}
public String getAuthor() { return author; }
public String getSong() { return song; }
public String getUrl() { return url; }
}
See the fields? Are named with the first letter lower case.

Related

My cardview is going off screen even in wrapcontent

MY PROBLEM -
my cardview is going over the screen(can be seen in the image) even if the says matchparent.
my database node
Please help....... is this a bug or smth?
What am i doing = i m trying to retrieve the data from firebase in a recycler view, the data is being retrieved but the item of the recyclerview is giving problem, as the cardview is half outside the screen even if the cardview is set to matchparent and wrapcontent please help if possible
My recycler Item
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/Cdate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hi"
android:textSize="50dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</androidx.cardview.widget.CardView>
my Adapterclass
package com.sjsbhints.pdfmanager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
public class CAdapter extends FirebaseRecyclerAdapter<Cmodel,CAdapter.myViewHolder> {
/**
* Initialize a {#link RecyclerView.Adapter} that listens to a Firebase query. See
* {#link FirebaseRecyclerOptions} for configuration options.
*
* #param options
*/
public CAdapter(#NonNull FirebaseRecyclerOptions<Cmodel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull myViewHolder holder, int position, #NonNull Cmodel model) {
// if(model.Cdate.isEmpty()){
// holder.Cdate.setText("Null");
// }
holder.Cdate.setText(model.getCdate());
// holder.Cheading.setText(model.getCheading());
// holder.Cbody.setText(model.getCbody());
}
#NonNull
#Override
public myViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.circular_item,parent,false);
return new myViewHolder(view);
}
class myViewHolder extends RecyclerView.ViewHolder{
TextView Cdate,Cheading,Cbody,Ndate,Nheading,Nsheading,Nbody,Tdate,Tsubject,Ttopic,Ttdate;
public myViewHolder(#NonNull View itemView) {
super(itemView);
Cdate = itemView.findViewById(R.id.Cdate);
// Cheading = itemView.findViewById(R.id.cheading);
// Cbody = itemView.findViewById(R.id.cbody);
}
}
}
my model class
package com.sjsbhints.pdfmanager;
public class Cmodel {
String Cdate,Cheading,Cbody,Ndate,Nheading,Nsheading,Nbody,Tdate,Tsubject,Ttopic,Ttdate;
Cmodel(){
}
public Cmodel(String cdate, String cheading, String cbody, String ndate, String nheading, String nsheading, String nbody, String tdate, String tsubject, String ttopic, String ttdate) {
Cdate = cdate;
Cheading = cheading;
Cbody = cbody;
Ndate = ndate;
Nheading = nheading;
Nsheading = nsheading;
Nbody = nbody;
Tdate = tdate;
Tsubject = tsubject;
Ttopic = ttopic;
Ttdate = ttdate;
}
public String getCdate() {
return Cdate;
}
public void setCdate(String cdate) {
Cdate = cdate;
}
public String getCheading() {
return Cheading;
}
public void setCheading(String cheading) {
Cheading = cheading;
}
public String getCbody() {
return Cbody;
}
public void setCbody(String cbody) {
Cbody = cbody;
}
public String getNdate() {
return Ndate;
}
public void setNdate(String ndate) {
Ndate = ndate;
}
public String getNheading() {
return Nheading;
}
public void setNheading(String nheading) {
Nheading = nheading;
}
public String getNsheading() {
return Nsheading;
}
public void setNsheading(String nsheading) {
Nsheading = nsheading;
}
public String getNbody() {
return Nbody;
}
public void setNbody(String nbody) {
Nbody = nbody;
}
public String getTdate() {
return Tdate;
}
public void setTdate(String tdate) {
Tdate = tdate;
}
public String getTsubject() {
return Tsubject;
}
public void setTsubject(String tsubject) {
Tsubject = tsubject;
}
public String getTtopic() {
return Ttopic;
}
public void setTtopic(String ttopic) {
Ttopic = ttopic;
}
public String getTtdate() {
return Ttdate;
}
public void setTtdate(String ttdate) {
Ttdate = ttdate;
}
}
my MainActivity
package com.sjsbhints.pdfmanager;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.FirebaseDatabase;
public class CircularAct extends AppCompatActivity {
RecyclerView recyclerView;
CAdapter cAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circular2);
recyclerView = findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
FirebaseRecyclerOptions<Cmodel> options =
new FirebaseRecyclerOptions.Builder<Cmodel>()
.setQuery(FirebaseDatabase.getInstance().getReference().child("CircularData"), Cmodel.class)
.build();
cAdapter = new CAdapter(options);
recyclerView.setAdapter(cAdapter);
}
#Override
protected void onStart() {
super.onStart();
cAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
cAdapter.stopListening();
}
}
my mainactivity Xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".CircularAct">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="599dp"
android:layout_height="960dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Your CardView definitely matched the parent's width because it inherited the width of the RecyclerView since that's its parent.
Your RecyclerView, on the other hand, has a width of 599dp. The fixed size means that it will ignore the device's width. To match the device's width and height, set it to match_parent or use 0dp since you're using a constraint layout in your case.
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

Why is only one file getting deleted when I click to delete multiple?

I am trying to make a program where I list the file names in a recyclerview. Using a button inside the row, the application should delete the item via a path which is stored in an array that includes the file path. The application should also display the file path if the card itself is clicked in a toast message.
So far I am able to do this, however I can only delete one file at a time when the application is active. The problem arises when I try to delete multiple files. The items are deleted from the recyclerview and everything looks normal, but if the application is closed then the files that I attempted to delete after the first one show up again, indicating that they were not deleted.
My code:
JAVA CLASSES
FileView.java (this is the main activity)
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
File[] fileList;
String filePath = "";
String fileData = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = file.listFiles();
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList[i].getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
fileData = fileList[position].toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
#Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList[position];
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
}
});
}
}
RowAdapter.java (this is the adapter class)
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 java.util.ArrayList;
public class RowAdapter extends RecyclerView.Adapter<RowAdapter.RowViewHolder> {
private ArrayList<RowItem> mRowList;
private OnItemClickListener mListener;
public interface OnItemClickListener{
void onItemClick(int position);
void onDeleteClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class RowViewHolder extends RecyclerView.ViewHolder{
public ImageView rowImageView;
public TextView rowTextView;
public ImageView rowDeleteImage;
public RowViewHolder(#NonNull View itemView, OnItemClickListener listener) {
super(itemView);
rowImageView = itemView.findViewById(R.id.fileImage);
rowTextView = itemView.findViewById(R.id.fileName);
rowDeleteImage = itemView.findViewById(R.id.deleteFile);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
rowDeleteImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(listener != null){
int position = getAdapterPosition();
if(position != RecyclerView.NO_POSITION){
listener.onDeleteClick(position);
}
}
}
});
}
}
public RowAdapter(ArrayList<RowItem> rowList){
mRowList = rowList;
}
#NonNull
#Override
public RowViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row, parent, false);
RowViewHolder rvh = new RowViewHolder(v, mListener);
return rvh;
}
#Override
public void onBindViewHolder(#NonNull RowViewHolder holder, int position) {
RowItem currentItem = mRowList.get(position);
holder.rowImageView.setImageResource(currentItem.getImageResource());
holder.rowTextView.setText(currentItem.getFileName());
}
#Override
public int getItemCount() {
return mRowList.size();
}
}
RowItem.java (getters for image and filename)
public class RowItem {
private int imageResource;
private String fileName;
public RowItem(int img, String stringInput) {
this.imageResource = img;
this.fileName = stringInput;
}
public int getImageResource() {
return imageResource;
}
public String getFileName() {
return fileName;
}
}
XML FILES
activity_file_view.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.loopbreakr.firstpdf.FileView">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp"
android:scrollbars="vertical"
android:background="#color/cardview_shadow_start_color"
/>
</RelativeLayout>
row.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_marginBottom="4dp"
app:cardCornerRadius="4dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="4dp">
<ImageView
android:id="#+id/fileImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:padding="2dp"/>
<TextView
android:id="#+id/fileName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="55dp"
android:layout_marginTop="5dp"
android:text="File Name"
android:textColor="#color/black"
android:textSize="20sp" />
<ImageView
android:id="#+id/deleteFile"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_margin="5dp"
android:padding="2dp"
android:src="#drawable/ic_delete" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
EDIT
I tried to change the array to an arraylist as suggested, however I think I must have done so incorrectly as this results in a crash.
FileView.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FileView extends AppCompatActivity {
private RecyclerView fileRecyclerView;
private RowAdapter fileAdapter;
private RecyclerView.LayoutManager fileLayoutManager;
private ArrayList<RowItem> rowItem;
List<File> fileList;
String filePath = "";
String fileData = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_file_view);
filePath = "PDF_files";
File file = new File(getExternalFilesDir(filePath).toString());
fileList = Arrays.asList(file.listFiles());
createRows();
buildRecyclerView();
}
public void createRows(){
rowItem = new ArrayList<>();
for (int i = 0; i < fileList.size(); i++) {
rowItem.add(new RowItem(R.drawable.ic_book,(fileList.get(i).getName().replace("__", " ").replace('_','\n').replace('-','/').replace(".pdf",""))));
}
}
public void removeItem(int position) {
rowItem.remove(position);
fileAdapter.notifyItemRemoved(position);
}
#Override
public void recreate() {
super.recreate();
}
public void buildRecyclerView() {
fileRecyclerView = findViewById(R.id.recyclerView);
fileRecyclerView.setHasFixedSize(true);
fileLayoutManager = new LinearLayoutManager(this);
fileAdapter = new RowAdapter(rowItem);
fileRecyclerView.setLayoutManager(fileLayoutManager);
fileRecyclerView.setAdapter(fileAdapter);
fileAdapter.setOnItemClickListener(new RowAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
fileData = fileList.get(position).toString();
Toast.makeText(FileView.this,"Clicked: " + fileData , Toast.LENGTH_SHORT).show();
}
#Override
public void onDeleteClick(int position) {
removeItem(position);
File deletePath = fileList.get(position);
deletePath.delete();
if(deletePath.exists()){
getApplicationContext().deleteFile(deletePath.getName());
}
fileList.remove(position);
}
});
}
}
When you delete a record, the table widget (the stuff you see on your device) is updated and the row is removed. However, your fileList array is not updated; it still has the Path representing that deleted file (you deleted the file, sure, but any objects that capture the notion of the path of that file are still around, of course).
When you delete a file, you need to also fix the fileList array. Given that arrays cannot grow or shrink, this is probably a lot simpler if you use a List<File> instead of a File[].
You make it yourself difficult as you keep two lists.
rowItems and fileList.
In RowItems you have only a String variable fileName.
Add a variable String filePath and use it instead of the file list array.

RecyclerView.setAdapter not being resolved

Everything works as in other projects but for some reason I'm unable to set the projectListItems ( a recycler view ) adapter because it won't resolve setAdapter()...
binding.projectListItems.setAdapter(adapter); in the ProjectsActivity.java
Cleaned and Rebuilt project... also Invalidated cache and restarted.
ProjectsActivity.java
package com.example.poleprofilingapp.ui;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import com.example.poleprofilingapp.R;
import com.example.poleprofilingapp.databinding.ActivityProjectsBinding;
import com.example.poleprofilingapp.project.Project;
import com.example.poleprofilingapp.project.ProjectAdapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ProjectsAcitivty extends AppCompatActivity {
private ProjectAdapter adapter;
private ActivityProjectsBinding binding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_projects);
Intent intent = getIntent();
List <Project> projectsList = new ArrayList<>();
Project project = new Project();
project.setName("Project 1");
project.setAddress("Address 1");
project.setDescription("Test Project 1");
project.setType("NOVEC");
project.setCompanyKey("333555");
projectsList.add(project);
binding = DataBindingUtil.setContentView(this,
R.layout.activity_projects);
adapter = new ProjectAdapter(projectsList, this);
binding.projectListItems.setAdapter(adapter); // setAdapter not resoleved
}
}
ProjectAdaptor.java
package com.example.poleprofilingapp.project;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
import androidx.recyclerview.widget.RecyclerView;
import com.example.poleprofilingapp.R;
import com.example.poleprofilingapp.databinding.ProjectListItemBinding;
import java.util.List;
public class ProjectAdapter extends RecyclerView.Adapter<ProjectAdapter.ViewHolder> {
private List<Project> projects;
private Context context;
public ProjectAdapter(List<Project> projects, Context context) {
this.projects = projects;
this.context = context;
}
#NonNull
#Override
public ProjectAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
ProjectListItemBinding binding = DataBindingUtil
.inflate(LayoutInflater.from(parent.getContext()),
R.layout.project_list_item,
parent,
false);
return new ViewHolder(binding);
}
#Override
public void onBindViewHolder(#NonNull ProjectAdapter.ViewHolder holder, int position) {
Project project = projects.get(position);
holder.projectListItemBinding.setProject(project);
}
#Override
public int getItemCount() {
return projects.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
// Binding Vars
public ProjectListItemBinding projectListItemBinding;
// Constructor to do view lookups for each subview
public ViewHolder(ProjectListItemBinding projectLayoutBinding){
super(projectLayoutBinding.getRoot());
projectListItemBinding = projectLayoutBinding;
}
}
}
Project.java ( data model )
package com.example.poleprofilingapp.project;
public class Project {
private String id;
private String name;
private String address;
private String description;
private String type;
private String companyKey;
public Project() {
}
public Project(String name, String address, String description, String type, String companyKey) {
this.name = name;
this.address = address;
this.description = description;
this.type = type;
this.companyKey = companyKey;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getCompanyKey() {
return companyKey;
}
public void setCompanyKey(String companyKey) {
this.companyKey = companyKey;
}
}
XML - activity_projects.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="project"
type="com.example.poleprofilingapp.project.Project"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.ProjectsAcitivty">
<android.support.v7.widget.RecyclerView
android:id="#+id/projectListItems"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</android.support.v7.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
projects_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="project"
type="com.example.poleprofilingapp.project.Project"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/projectListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="8dp"
android:paddingBottom="8dp"
tools:background="#color/colorPrimaryDark">
<TextView
android:id="#+id/name"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:text="#{project.name}"
android:textColor="#android:color/white"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Test Project"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Inside the onCreate intialize your bindiing variable
ActivityMainBinding mBinding;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
mBinding = DataBindingUtil.setContentView(this,R.layout.activity_main);
}
In onStart method set you layoutManager and adapter
#Override
protected void onStart() {
super.onStart();
mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
UserAdapter adapter = new UserAdapter(getApplicationContext(),usersList());
mBinding.recyclerView.setAdapter(adapter);
}
and this is list
private List<Animals> usersList(){
List<Animals> animalsList = new ArrayList<>();
String[] animals = {"Tiger","Monkey","Dog","Lion","Zebra","Horse","Cat"};
String[] types = {"Carnivore","Herbivore","Omnivore","Carnivore","Herbivore","Herbivore","Omnivore"};
int[] image = {R.drawable.all_call,R.drawable.done,R.drawable.hide,R.drawable.all_call};
for (int i=0;i<animals.length;i++){
Animals users = new Animals(
animals[i],
types[i],
image[i]
);
animalsList.add(users);
}
return animalsList;
}
So the issue was that I migrated the project over to androix but never changed the RecyclerView to support androix method. So in the build folder my generated binding class was trying to us android.support.v7..... in place of androidx.recyclerview.....
So what fixed this was updating the XML then running Invalidating the Chache / Restart...
Whala all fixed up.

Change collapsing toolbar title after Retrofit call

I'm trying to modify the toolbar title based on the Retrofit2 response, however there is no change.
getSupportActionBar().setTitle("here work");
final Call<Process> getProcess = WiimApi.getService(serverAddress).getProcess(id);
getProcess.enqueue(new Callback<Process>() {
#Override
public void onResponse(Call<Process> call, Response<Process> response) {
mProcess = response.body();
getSupportActionBar().setTitle(mProcess.getName()); // this not work
}
#Override
public void onFailure(Call<Process> call, Throwable t) {
// ...
}
});
mProcess.getName() is a string from JSON file. I have tested with a hardcoded string too (prevent mProcess.getName() wrong value) but no effect.
Just before the call work like a charm.
Is there any way to update the toolbar title after getting the callback?
Update
Thanks for the help. Now I have found the real problem: Collapsing Toolbar.
I did a blank application to replicate the error and the code works but when I run the same code with Collapsing toolbar ... Bingo! The complete code below:
MainActivity.java:
package com.example.retrofittitle;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getData();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void getData() {
getSupportActionBar().setTitle("Here work ...");
// https://raw.githubusercontent.com/LearnWebCode/json-example/master/
final Call<Pet> getPet = MyApi.getService("https://raw.githubusercontent.com/LearnWebCode/json-example/master/").getPet();
getPet.enqueue(new Callback<Pet>() {
#Override
public void onResponse(Call<Pet> call, Response<Pet> response) {
Pet pet = response.body();
getSupportActionBar().setTitle(pet.getName()); // Here not work
TextView text = findViewById(R.id.log);
text.setText("Done");
}
#Override
public void onFailure(Call<Pet> call, Throwable t) {
getSupportActionBar().setTitle("Failure Title");
}
});
}
}
MyApi.java
package com.example.retrofittitle;
import retrofit2.Call;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
public class MyApi {
public interface ApiService {
#GET("pet-of-the-day.json")
Call<Pet> getPet();
}
public static ApiService getService(String url) {
retrofit2.Retrofit retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(ApiService.class);
}
}
Pet.java
package com.example.retrofittitle;
public class Pet {
private String name;
private String species;
private Integer age;
private String photo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSpecies() {
return species;
}
public void setSpecies(String species) {
this.species = species;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="#+id/log"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Requesting..."
android:layout_gravity="center" />
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="180dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleGravity="top"
app:expandedTitleMarginTop="?attr/actionBarSize"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
Solution
After discovery of the real problem I search and found solution here:
https://github.com/henrytao-me/smooth-app-bar-layout/issues/32
Setting CollapsingToolbarLayout widget id (collapsing_toolbar) and code for activity:
CollapsingToolbarLayout mCollapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
mCollapsingToolbarLayout.setTitle(pet.getName());
The name is now changed :D
I have tried getSupportActionBar().setTitle("hello"); inside retrofit callback it is working fine for me.
Your problem is that on retrofit call everytime onFailure is called. Hence getSupportActionBar().setTitle("hello") is not called.
try getSupportActionBar().setTitle("hello") in onFailure also.

RecyclerView not calling onCreateViewHolder on activity start

I've been trying to implement a simple scrollable list that gets its data from Firebase Database using RecyclerView on an activity called MyOrganisedEventsActivity. Problem is, when my main activity starts the MyOrganisedEventsActivity, there is no call made to the method onCreateViewHolder, and thus the RecyclerView is empty.
However, after waiting a moment and then locking and unlocking my phone, a call is made to onCreateViewHolder and the list items start appearing on the RecyclerView. Is there anyway to force the call when the activity is first started? Or is there something wrong with my code and how can I fix it?
Here's my code so far:
MyOrganisedEventsActivity.java:
package com.llawl.tristonpang.intheloop;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MyOrganisedEventsActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private OrganisedEventsAdapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private List<EventInfo> mEventsDataset;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_organised_events);
mRecyclerView = (RecyclerView) findViewById(R.id.org_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mEventsDataset = new ArrayList<>();
// specify an adapter (see also next example)
mAdapter = new OrganisedEventsAdapter(mEventsDataset);
mRecyclerView.setAdapter(mAdapter);
prepareEventsData();
}
private void prepareEventsData() {
final String currentUser = FirebaseAuth.getInstance().getCurrentUser().getEmail();
Log.d("InTheLoop", "prepareEventsData(), currentUser = " + currentUser);
FirebaseDatabase.getInstance().getReference().child("events_info").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
//EventInfo event = snapshot.getValue(EventInfo.class);
HashMap<String,String> data = (HashMap) snapshot.getValue();
//Log.d("InTheLoop", "Event name: " + event.getName());
//if (event.getOrganiser().equals(currentUser)) {
if (data.get("organiser").equals(currentUser)) {
Log.d("InTheLoop", "Adding event: " + data.get("name"));
EventInfo event = new EventInfo(data.get("name"), data.get("date"), data.get("time"), data.get("venue"),
data.get("desc"), data.get("imageName"), data.get("organiser"));
mEventsDataset.add(event);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
mAdapter.notifyDataSetChanged();
}
}
OrganisedEventsAdapter.java:
package com.llawl.tristonpang.intheloop;
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.TextView;
import java.util.List;
public class OrganisedEventsAdapter extends RecyclerView.Adapter<OrganisedEventsAdapter.ViewHolder> {
private List<EventInfo> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView mName;
public TextView mVenue;
public TextView mDate;
public ViewHolder(View v) {
super(v);
mName = v.findViewById(R.id.org_row_name);
mVenue = v.findViewById(R.id.org_row_venue);
mDate = v.findViewById(R.id.org_row_date);
}
}
public OrganisedEventsAdapter(List<EventInfo> dataset) {
mDataset = dataset;
}
// Create new views (invoked by the layout manager)
#Override
public OrganisedEventsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.organised_event_row, parent, false);
Log.d("InTheLoop", "Adapter, onCreateViewHolder");
return new ViewHolder(v);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
EventInfo event = mDataset.get(position);
Log.d("InTheLoop", "Adapter, Event name: " + event.getName());
holder.mName.setText(event.getName());
holder.mVenue.setText(event.getVenue());
holder.mDate.setText(event.getDate());
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.size();
}
}
EventInfo.java:
package com.llawl.tristonpang.intheloop;
public class EventInfo {
private String mName;
private String mDate;
private String mTime;
private String mVenue;
private String mDesc;
private String mImageName;
private String mOrganiser;
public EventInfo() {
}
public EventInfo(String name, String date, String time, String venue, String desc, String imageName, String organiser) {
mName = name;
mDate = date;
mTime = time;
mVenue = venue;
mDesc = desc;
mImageName = imageName;
mOrganiser = organiser;
}
public String getName() {
return mName;
}
public String getDate() {
return mDate;
}
public String getTime() {
return mTime;
}
public String getVenue() {
return mVenue;
}
public String getDesc() {
return mDesc;
}
public String getImageName() {
return mImageName;
}
public String getOrganiser() {
return mOrganiser;
}
}
organised_event_row.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/single_event_row"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:orientation="vertical"
android:paddingBottom="#dimen/row_padding_vertical"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/row_padding_vertical">
<TextView
android:id="#+id/org_row_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="name"
android:textColor="#color/black"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="#+id/org_row_venue"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/org_row_name"
android:text="venue" />
<TextView
android:id="#+id/org_row_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="date"
android:textColor="#color/black" />
</RelativeLayout>
activity_my_organised_events.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyOrganisedEventsActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/org_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
Any help is much appreciated! Thanks!
Move mAdapter.notifyDataSetChanged(); inside onDataChange(DataSnapshot dataSnapshot) . You have missed the nature of asynchronous call.
FirebaseDatabase.getInstance().getReference().child("events_info").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
// Build data here
}
mAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
call mAdapter.notifyDataSetChanged(); after you add data in List in for loop in onDataChange()
so basically add data in your data structure and then notify adapter to update itself with new data.

Categories

Resources