i know that if i want to create a new line, i have to insert \n wherever i need to create the line. But what i get is the text without the lines that i already have in firebase database. can someone tell me how to fix that. so for example if i have in the database hello \n world. i get it as hello world. when i really should get it as
hello
world
will i need to change something in firebase or in my source code?
this is how i get the data from firebase
private void getData(){
firebaseDatabaseInstance = FirebaseDatabase.getInstance();
// get reference to 'users' node
booksInstance = firebaseDatabaseInstance.getReference("monzmat");
books.clear();
books.addAll(db.getAllBookMonzmat());
adapter = new qamoosAdapter(this, books);
gridView.setAdapter(adapter);
booksInstance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
storeData(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.w(TAG, "Failed to read value.", error.toException());
}
});
booksInstance.orderByChild("id").addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
qamoosData book = new qamoosData(
(String) dataSnapshot.child("id").getValue(),
(String) dataSnapshot.child("title").getValue(),
(String)dataSnapshot.child("content").getValue()
);
db.insertMonzmat(book);
reloadData();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
qamoosData book = new qamoosData(
(String) dataSnapshot.child("id").getValue(),
(String) dataSnapshot.child("title").getValue(),
(String)dataSnapshot.child("content").getValue()
);
db.updateABookMonzmat(book);
reloadData();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
qamoosData book = new qamoosData(
(String) dataSnapshot.child("id").getValue(),
(String) dataSnapshot.child("title").getValue(),
(String)dataSnapshot.child("content").getValue()
);
db.deleteABookMonzmat(book.getId());
reloadData();
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void storeData(DataSnapshot snapshot) {
books.clear();
for (DataSnapshot alert: snapshot.getChildren()) {
qamoosData book = new qamoosData(
(String)alert.child("id").getValue(),
(String)alert.child("title").getValue(),
(String)alert.child("content").getValue()
);
db.insertMonzmat(book);
}
books.addAll(db.getAllBookMonzmat());
// Constants.hideDialog();
adapter.notifyDataSetChanged();
}
This is my adapter
public class qamoosAdapter extends BaseAdapter {
Activity activity;
ArrayList<qamoosData> arrayList = new ArrayList<>();
ArrayList<qamoosData> filterList = new ArrayList<>();
LayoutInflater mLayoutInflater;
DBHandler db;
Storage storage;
public qamoosAdapter(Activity context, ArrayList<qamoosData> bookDatas){
this.activity = context;
this.arrayList = bookDatas;
this.db = new DBHandler(context);
this.filterList= bookDatas;
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
storage = SimpleStorage.getInternalStorage(context);
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
qamoosAdapter.ViewHolder holder = new qamoosAdapter.ViewHolder();
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.fragment_qamoos, null);
holder.name = (TextView) convertView.findViewById(R.id.bookName2_makotab_fragment);
if(holder.name.getText().toString().contains("\n")){
}
convertView.setTag(holder);
} else {
holder = (qamoosAdapter.ViewHolder) convertView.getTag();
}
holder.name.setText(arrayList.get(position).getTitle());
return convertView;
}
public class ViewHolder{
ImageView image;
TextView name;
}
}
You can put special characters sequence and replace it after retrieving the data.
Firebase database doesn't permit \ character.
So you can put in the database:Hello _b world
And after retrieving you replace this _b with \n
Firestore automatically converts \n into \\n. So if you want to use \n in Firestore, convert \\n into \n in android.
textView.text = text.replace("\\n", "\n")
Bonus
If you use data binding, you can use this binding adapter
#JvmStatic
#BindingAdapter("text_parse_new_line")
fun parseNewLine(textView: TextView, text: String?) {
textView.text = text?.replace("\\n", "\n")
}
In layout file use
<TextView
android:id="#+id/how_to_claim"
text_parse_new_line="#{viewModel.listing.howToClaim}" />
In firebase, store the newline command as "_n" without the quotes. Then in onBindViewHolder do this
if(holder.name.getText().toString().contains("_n")){
String newName = name.getText.replace("_n","\n");
holder.name.setText(newName);
}
Related
I have some data in firebase which gets changed on some specific actions and I want that change to be shown in the app.
I have a RecyclerView in which all the data from firebase is getting populated.
Here's code:
databaseReference.child("uListings").child(AccessToken.getCurrentAccessToken().getUserId()).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// recyclerview gets populated here
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.getValue() != null) {
Map<String,String> map = (Map<String,String>)dataSnapshot.getValue();
Map<ArrayList<String>,ArrayList<String>> map2 = (Map<ArrayList<String>,ArrayList<String>>)dataSnapshot.getValue();
String pDescription = map.get("pDescription");
String pDuration = map.get("pDuration");
String pPrice = map.get("pPrice");
String postedAt = map.get("postedAt");
String views = map.get("views");
ArrayList<String> imageUrl = map2.get("imageUrl");
if (imageUrl != null) {
UHandler pHandler = new UHandler(imageUrl.get(0), pDescription, pDuration, pPrice, postedAt, views);
list.add(pHandler);
adapter.notifyDataSetChanged();
progressBar.setVisibility(View.INVISIBLE);
} else {
Toast.makeText(getBaseContext(), "imageUrlNone", Toast.LENGTH_SHORT).show();
}
} else {
Log.d("PDPchange", "NULL");
progressBar.setVisibility(View.INVISIBLE);
}
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Here's UHandlerAdapter.java:
public class UHandlerAdapter extends RecyclerView.Adapter<UHandlerAdapter.MyViewHolder> {
private Context mContext;
private List<UHandler> listingList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView pDescription, pDuration, pPrice, postedAt, listingViews, imageUrl;
public ArrayList<String> imageUrls;
public CircleImageView pImage;
public MyViewHolder(View view) {
super(view);
pImage = (CircleImageView) view.findViewById(R.id.p_image_profile);
pDescription = (TextView) view.findViewById(R.id.p_description_profile);
pDuration = (TextView) view.findViewById(R.id.p_duration_profile);
pPrice = (TextView) view.findViewById(R.id.p_price_profile);
postedAt = (TextView) view.findViewById(R.id.p_posted_when_profile);
listingViews = (TextView) view.findViewById(R.id.listing_views_profile);
imageUrl = (TextView) view.findViewById(R.id.image_urls_profile);
}
}
public UHandlerAdapter(Context mContext, List<UProfileHandler> listingList) {
this.mContext = mContext;
this.listingList = listingList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.profile_all, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
UHandler handler = listingList.get(position);
holder.pDescription.setText(handler.getPDescriptionProfile());
holder.pDuration.setText(handler.getPDurationProfile());
holder.pPrice.setText(handler.getPPriceProfile());
holder.postedAt.setText(handler.getPostedAt());
holder.listingViews.setText(handler.getListingViews());
// loading album cover using Glide library
Glide.with(mContext)
.load(handler.getPImageProfile())
.apply(new RequestOptions().placeholder(R.drawable.ic_placeholder).error(R.drawable.ic_error))
.into(holder.pImage);
}
#Override
public int getItemCount() {
return listingList.size();
}
}
The problem is that in onChildChanged() the views which gets changed add a complete other item in the list reflecting it's changed value and not just gets updated in previously added items in onChildAdded().
How can I just update it in the previously added items itself?
You can store keys in order to update it e.g:
ArrayList<String> mKeys = new ArrayList<String>();
databaseReference.child("uListings").child(AccessToken.getCurrentAccessToken().getUserId()).addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// recyclerview gets populated here
String key = dataSnapshot.getKey();
mKeys.add(key);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.getValue() != null) {
.......
//now we get the index to update specific value
String key = dataSnapshot.getKey();
int index = mKeys.indexOf(key);
list.set(index, pHandler);
adapter.notifyDataSetChanged();
....
}
I'm trying to build a simple chat activity in side my app where all the requirements needed are in one place, the adapter, the attributes class, the viewholder class and the main activity are all to gather, at this point the activity sends one string line to firebase with no problem at all, but the code for data fetching is not working , I'm using the ChildEeventListiner to receive one single string line in the listview, ((((( my guess the DataSnapShot is not receiving any data )))))
PS: I've used the same code in the same app but holding more complex data and works fine, I'm not sure what is missing here, hope somebody can figure out what wrong here, ask me if there is any additional data u need.
public class MainActivity extends Activity {
//---------------------attributes Class ==> 1 string input-------------------
public class classChat {
String messageInPut;
public classChat(String messageInPut) {
this.messageInPut = messageInPut;
}
public String getMessageInPut() {
return messageInPut;
}
}
//---------------------------------------------------------------------------
FirebaseUser user;
DatabaseReference databaseChatView;
String msg;
classChat chats;
public static chatAdapter adapter;
ArrayList<classChat> bidChatdata;
ListView chatinstnc;
ImageView sendButton;
EditText messageArea;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//user = FirebaseAuth.getInstance().getCurrentUser();
databaseChatView = FirebaseDatabase.getInstance().getReference("Chat");
chatinstnc = (ListView) findViewById(R.id.chatinstnc);
sendButton = (ImageView)findViewById(R.id.sendButton);
messageArea = (EditText)findViewById(R.id.messageArea);
bidChatdata = new ArrayList<>();
//------------------sending to firebase------------------------------------
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String messageId = databaseChatView.push().getKey();
String msg = messageArea.getText().toString().trim();
databaseChatView.child(messageId).setValue(msg);
Toast.makeText(MainActivity.this, "chat: "+ chats, Toast.LENGTH_SHORT).show();
}
});
//--------------------List Item Click-------------------------------------
/* chatinstnc.setOnItemClickListener(new AdapterView.OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long messageId) {classChat dataModel = bidChatdata.get(position);}
});*/
//-------------Receiving Data From Firebase------------------------------
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
bidChatdata.clear();
for (DataSnapshot chatSnapshot : dataSnapshot.getChildren()) {
chats = chatSnapshot.getValue(classChat.class);
bidChatdata.add(chats);
}
adapter = new chatAdapter(MainActivity.this, bidChatdata);
chatinstnc.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
bidChatdata.clear();
for (DataSnapshot chatSnapshot : dataSnapshot.getChildren()) {
chats = chatSnapshot.getValue(classChat.class);
bidChatdata.add(chats);
}
adapter = new chatAdapter(MainActivity.this, bidChatdata);
chatinstnc.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseChatView.addChildEventListener(childEventListener);
}
//---------------adapter class--------------------------------------------
public class chatAdapter extends ArrayAdapter<classChat>{
ArrayList<classChat> chat;
Context Context;
public class ViewHolder {
TextView msg1;
}
public chatAdapter(Context context, ArrayList<classChat> chat) {
super(context, R.layout.list_view_items, chat);
this.chat = chat;
this.Context = context;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
final classChat chatdata = getItem(position);
ViewHolder viewHolder;
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.list_view_items, parent, false);
viewHolder.msg1 = (TextView)convertView.findViewById(R.id.msg1);
result = convertView;
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
result = convertView;
}
viewHolder.msg1.setText(chatdata.getMessageInPut());
return convertView;
}
}
}
Tried answers found on the internet, actually there is no change to the code as it seem correct but can't find where is the error.
My Input Parameters:
JSON RETURNED:
(I expected a "clocation" child and value but it won't even write that to the tree. Plus, the value of clocation is written to cbudget)
Project Class:
public class Project {
String ctitle, cdetail, clocation, cbudget;
public Project() {
}
public String getCtitle() {
return ctitle;
}
public void setCtitle(String ctitle) {
this.ctitle = ctitle;
}
public String getCdetail() {
return cdetail;
}
public void setCdetail(String cdetail) {
this.cdetail = cdetail;
}
public String getClocation() {
return clocation;
}
public void setClocation(String clocation) {
this.clocation = clocation;
}
public String getCbudget() {
return cbudget;
}
public void setCbudget(String cbudget) {
this.cbudget = cbudget;
}
MyViewHolder
public MyViewHolder(View itemView) {
super(itemView);
titleTxt = (TextView) itemView.findViewById(R.id.titleTxt);
detailTxt = (TextView) itemView.findViewById(R.id.detailTxt);
locationTxt = (TextView) itemView.findViewById(R.id.locationTxt);
budgetTxt = (TextView) itemView.findViewById(R.id.budgetTxt);
itemView.setOnClickListener(this);
}
MyAdapter
public MyAdapter(Context c, ArrayList<Project> projects) {
this.c = c;
this.projects = projects;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(c).inflate(R.layout.model,parent,false);
return new MyViewHolder(v);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Project s = projects.get(position);
holder.titleTxt.setText(s.getCtitle());
holder.detailTxt.setText(s.getCdetail());
holder.locationTxt.setText(s.getClocation());
holder.budgetTxt.setText(s.getCbudget());
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(int pos) {
//OPEN DETAIL ACTIVITY
openDetailActivity(s.getCtitle(),s.getCdetail(),s.getClocation(),s.getCbudget());
}
});
}
#Override
public int getItemCount() {
return projects.size();
}
//OPEN DETAIL ACTIVITY
private void openDetailActivity(String...details)
{
Intent i=new Intent(c,DetailActivity.class);
i.putExtra("TITLE_KEY",details[0]);
i.putExtra("DETAIL_KEY",details[1]);
i.putExtra("LOCATION_KEY",details[2]);
i.putExtra("BUDGET_KEY",details[3]);
c.startActivity(i);
}
FirebaseHelper
public class FirebaseHelper {
DatabaseReference db;
Boolean saved = null;
ArrayList<Project> projects=new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//WRITE IF NOT NULL
public Boolean save(Project project)
{
if(project==null)
{
saved=false;
}
else
{
try
{
db.child("Project").push().setValue(project);
saved=true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved=false;
}
}
return saved;
}
//IMPLEMENT FETCH DATA AND FILL ARRAYLIST
private void fetchData(DataSnapshot dataSnapshot)
{
projects.clear();
for (DataSnapshot ds : dataSnapshot.getChildren())
{
Project project = ds.getValue(Project.class);
projects.add(project);
}
}
//READ THEN RETURN ARRAYLIST
public ArrayList<Project> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return projects;
}
}
Receive and Bind Data:
//RECEIVE DATA
String title = i.getExtras().getString("TITLE_KEY");
String detail = i.getExtras().getString("DETAIL_KEY");
String location = i.getExtras().getString("LOCATION_KEY");
String budget = i.getExtras().getString("BUDGET_KEY");
//BIND DATA
titleTxt.setText(title);
detailTxt.setText(detail);
locationTxt.setText(location);
budgetTxt.setText(budget);
The problem in your code is that you are declaring the ArrayList<Project> projects=new ArrayList<>(); outside onChildAdded() and onChildChanged() methods. This means that your projects ArrayList is null, due the asyncronious behaviour of those methods, which are called before even you add those objects to the list.
To solve this, you need to declare that ArrayList inside fetchData() method right before that for loop.
This change will solve your problem.
Inside MainActivity, I have this function:
public void sortingData() {
mRootRef = new Firebase("https://fyp-1-43a27.firebaseio.com/User");
dbSortAllData = FirebaseDatabase.getInstance().getReference();
ListView mLvScore = (ListView) findViewById(R.id.lvScore);
final List<UserInformation> listScore = new LinkedList<>();
final ArrayAdapter<UserInformation> adapter
= new ArrayAdapter<UserInformation>
(this, R.layout.scoreboard_row, listScore) {
#NonNull
#Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = getLayoutInflater().inflate(R.layout.scoreboard_row, parent, false);
}
UserInformation item = listScore.get(position);
((TextView) view.findViewById(R.id.tvScoreName)).setText(item.getName());
((TextView) view.findViewById(R.id.tvScorePoint)).setText(item.getScore());
return view;
}
};
mLvScore.setAdapter(adapter);
com.firebase.client.Query queryRef = mRootRef.orderByChild("score").startAt("score").endAt("score").limitToFirst(50);
queryRef.addChildEventListener(new com.firebase.client.ChildEventListener() {
#Override
public void onChildAdded(com.firebase.client.DataSnapshot dataSnapshot, String s) {
UserInformation sI = dataSnapshot.getValue(UserInformation.class);
listScore.add(sI);
adapter.notifyDataSetChanged();
}
#Override
public void onChildChanged(com.firebase.client.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(com.firebase.client.DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(com.firebase.client.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
}
My Model Class:
public class UserInformation implements Comparable<UserInformation> {
public String name;
public String age;
public String score;
public UserInformation() {}
public UserInformation(String name, String age, String score) {
this.name = name;
this.age = age;
this.score = score;
}
// ... Getters and Setters here.
}
These piece of code works, it sorts from lowest to highest.
My Problem is how do I sort it from Highest to Lowest? Suggestions and advises are much appreciated.
You can reorder the data on the client side - just reverse the list.
Edit :
When you want to reverse the list, you can use :
Collections.reverse(listScore);
adapter.notifyDataSetChanged();
You can also just add each element that you get from the database to the front of the list to get it in reverse order :
public void onChildAdded(com.firebase.client.DataSnapshot dataSnapshot, String s) {
UserInformation sI = dataSnapshot.getValue(UserInformation.class);
listScore.addFirst(sI);
adapter.notifyDataSetChanged();
}
And change the declaration of listScore to :
final LinkedList<UserInformation> listScore = new LinkedList<>();
if you want in reverse order then create one extra key and store that newKey = value(multiplied by)-1 than do simple order by.
I have tried other solution by reversing ArrayList but when you add new data to existing list then it will get worst.
As you can see my priority score in negative so I can write
databaseReference = FirebaseDatabase.getInstance().getReference()
.child("node").child("event").orderByChild("priorityScore");
I have a custom listview to display data from Firebase database.
SectionDetails model
public class SectionDetails {
private String sectionCode;
private String sectionSeats;
public SectionDetails() {
}
public SectionDetails(String sectionCode, String sectionSeats) {
this.sectionCode = sectionCode;
this.sectionSeats = sectionSeats;
}
public String getSectionCode() {
return sectionCode;
}
public String getSectionSeats() {
return sectionSeats;
}
public void setSectionCode(String sectionCode) {
this.sectionCode = sectionCode;
}
public void setSectionSeats(String sectionSeats) {
this.sectionSeats = sectionSeats;
}
}
FirebaseHelper class
public class FirebaseHelper {
DatabaseReference db;
Boolean saved;
ArrayList<SectionDetails> sectionDetailsArrayList = new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
public Boolean save(SectionDetails sectionDetails) {
if (sectionDetails == null) {
saved = false;
} else {
try {
db.push().setValue(sectionDetails);
saved = true;
adapter.notifyDataSetChanged();
} catch(DatabaseException e) {
e.printStackTrace();
saved = false;
}
}
return saved;
}
private void fetchData(DataSnapshot dataSnapshot) {
sectionDetailsArrayList.clear();
SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
sectionDetailsArrayList.add(sectionDetails);
}
public ArrayList<SectionDetails> retrieve() {
db.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
return sectionDetailsArrayList;
}
}
CustomAdapter class
public class CustomAdapter extends BaseAdapter {
Context c;
ArrayList<SectionDetails> sectionDetailsArrayList;
public CustomAdapter(Context c, ArrayList<SectionDetails> sectionDetailsArrayList) {
this.c = c;
this.sectionDetailsArrayList = sectionDetailsArrayList;
}
#Override
public int getCount() {
return sectionDetailsArrayList.size();
}
#Override
public Object getItem(int position) {
return sectionDetailsArrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(c).inflate(R.layout.sections_custom_listview, parent, false);
}
TextView lvTvSectionCode = (TextView) convertView.findViewById(R.id.lvTvSectionCode);
TextView lvTvSectionSeats = (TextView) convertView.findViewById(R.id.lvTvSectionSeats);
final SectionDetails sd = (SectionDetails) this.getItem(position);
lvTvSectionCode.setText(sd.getSectionCode());
lvTvSectionSeats.setText("allocated seats: " + sd.getSectionSeats());
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(c, sd.getSectionCode(), Toast.LENGTH_LONG).show();
}
});
return convertView;
}
}
MainActivity class
public class AddSection extends AppCompatActivity implements View.OnClickListener {
DatabaseReference mRef;
FirebaseHelper helper;
CustomAdapter adapter;
Button btnCreateSection;
ListView lvSectionsListOne;
String getFullSection, seats;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_section);
lvSectionsListOne = (ListView) findViewById(R.id.lvSectionsList);
mRef = FirebaseDatabase.getInstance().getReference().child(Constants.FIREBASE_COURSES).child("sections");
helper = new FirebaseHelper(mRef);
adapter = new CustomAdapter(this, helper.retrieve());
lvSectionsListOne.setAdapter(adapter);
btnCreateSection = (Button) findViewById(R.id.btnCreateSection);
btnCreateSection.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if (v == btnCreateSection) {
getFullSection = "section 1A";
seats = "20";
SectionDetails sectionDetails = new SectionDetails(getFullSection, seats);
if (helper.save(sectionDetails)) {
adapter = new CustomAdapter(AddSection.this, helper.retrieve());
lvSectionsListOne.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}
}
}
I posted a similar question here, but this problem is different. When first data is added, nothing is shown in the listview. When second data is added, first data is shown in listview. And when third data is added, first data is replaced by second data, and second data is shown in listview. I have tried adding adapter.notifyDataSetChanged(), but still the same result.
Data is retrieved (and synchronized) from the Firebase Database to your app asynchronously. This means that your sectionDetailsArrayList may be modified at any time. When you modify the data, you need to tell the adapter about it, so that it can update the view.
private void fetchData(DataSnapshot dataSnapshot) {
sectionDetailsArrayList.clear();
SectionDetails sectionDetails = dataSnapshot.getValue(SectionDetails.class);
sectionDetailsArrayList.add(sectionDetails);
// tell the adapter that we changed its data
adapter.notifyDataSetChanged();
}
This should update the view. But since you clear out the list for every child that gets added or changed, the app will only show the latest added/modified item.
Setting up a synchronized array in Firebase is somewhat involved, since you have to deal with all event types and with the fact that evens can happen in any order. For that reason we create the FirebaseUI library, which contains adapters from the Firebase Database to a ListView and RecyclerView.