I made a list of values from a map retrieved from firestore database. The problem is that it won't appear on my listView. I initiated another list from another map and it appeared in my listView. Why is the list from the map retrieved from firestore document won't work while other list works fine?
public class RecipeActivity extends Activity {
private ListView listView;
private ArrayAdapter<Object> arrayAdapter;
private FirebaseFirestore newRecipeDb;
private Map<String, Object> meMap = new HashMap<String, Object>();
private List<Object> list = new ArrayList<>();
private List<String> listStrings = new ArrayList<> ();
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipe);
textView = findViewById(R.id. breadRecipe);
listView = findViewById(R.id.listIngredient);
arrayAdapter = new ArrayAdapter<Object>(this,
android.R.layout.simple_list_item_activated_1, list);
newRecipeDb = FirebaseFirestore.getInstance();
newRecipeDb.collection("users")
.document("bakeryMgt")
.collection("New Recipe")
.document("cherri pie")
.get()
.addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
System.out.println("DocumentSnapshot data " + document.getData());
meMap = document.getData();
list = new ArrayList<Object>(meMap.values());
listView.setAdapter(arrayAdapter);
} else {
System.out.println("No such document");
}
} else {
System.out.println("get failed with " + task.getException());
}
}
});
}
}
In your onCreate you're creating an ArrayAdapter based on list:
arrayAdapter = new ArrayAdapter<Object>(this,
android.R.layout.simple_list_item_activated_1, list);
Then inside onComplete, you create a new list:
list = new ArrayList<Object>(meMap.values());
This means that the arrayAdapter is not pointing to the list that you put the data into.
The solution is to add the data from the document to the existing list:
list.add(meMap.values());
I'd also recommend tying the adapter to the list view when you initialize both:
listView = findViewById(R.id.listIngredient);
arrayAdapter = new ArrayAdapter<Object>(this,
android.R.layout.simple_list_item_activated_1, list);
listView.setAdapter(arrayAdapter);
And then only notify the adapter that its data changed, once you add an item to the list:
list.add(meMap.values());
arrayAdapter.notifyDataSetChanged();
Related
FirebaseStorage storage;
StorageReference downloadRef;
StorageReference listRef;
Object Downloads;
ArrayList<String> arrayList;
ArrayAdapter arrayAdapter;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
arrayList = new ArrayList<>();
listRef = storage.getInstance().getReference("Project");
listRef.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult listResult) {
for (StorageReference items : listResult.getItems()) {
arrayList.add(items.getName());
}
}
});
arrayAdapter = new ArrayAdapter(MainActivity.this, android.R.layout.simple_list_item_1, arrayList);
listView.setAdapter(arrayAdapter);
}
So I am new to android, and this is what I tried to get the names of the documents so I can display them with listView. What am I getting wrong?
It seems like your onSuccess is getting called, which means you get a list of files from Firebase.
What's most likely happening is that you're processing this list correctly, but then not telling the adapter that you've changed its data. To tell the adapter that its data has changed call notifyDataSetChanged on it:
listRef.listAll().addOnSuccessListener(new OnSuccessListener<ListResult>() {
#Override
public void onSuccess(ListResult listResult) {
for (StorageReference items : listResult.getItems()) {
arrayList.add(items.getName());
}
arrayAdapter.notifyDataSetChanged();
}
});
At that point the adapter will repaint the associated views, and your data should show up.
I make a simple music app when I click on any item on Custom Listview its open new activity and when I press back button its showing listview from the top.
I need listView position where I click or where I am
//Getting List view.....
listView = (ListView) findViewById(R.id.MyListView);
myroot = FirebaseDatabase.getInstance().getReference("all");
readVariable = new ArrayList<>();
//Ends...............
// save index and top position
int index = listView.getFirstVisiblePosition();
View v = listView.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - listView.getPaddingTop());
// restore index and position
listView.setSelectionFromTop(index, top);
}
//FireBase Work>>>>>>>>>>>>>>>>>>>
#Override
protected void onStart() {
super.onStart();
myroot.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
readVariable.clear();
for (DataSnapshot artisSnapshot : dataSnapshot.getChildren()) {
ReadVariables read = artisSnapshot.getValue(ReadVariables.class);
readVariable.add(read);
}
CustomList adapter = new CustomList(MainActivity.this, readVariable);
listView.setAdapter(adapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Toast.makeText(MainActivity.this,"Check your network",Toast.LENGTH_LONG).show();
}
});
}
//Ends>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
}
Define readVariable and adapter as Global Variables.
CustomList adapter;
ArrayList<> readVariable = new ArrayList<>();
Remove
readVariable = new ArrayList<>();
We have already defined readVariable as a global variable and have initialized it.
Remove below lines from onDataChange
CustomList adapter = new CustomList(MainActivity.this, readVariable);
listView.setAdapter(adapter);
and write here like this
//Getting List view.....
listView = (ListView) findViewById(R.id.MyListView);
myroot = FirebaseDatabase.getInstance().getReference("all");
adapter = new CustomList(MainActivity.this, readVariable);
listView.setAdapter(adapter);
//Ends...............
Now where setAdapter line was written earlier in onDataChange,
Write this:
listView.notifyDataSetChanged();
I am trying to retrieve data from firebase to a listview...However this code returns a blank screen .My database has got 3 children with for data fields each.
All i see is an empty screen.
I have no idea on how to solve this anyone please:The code is here
public class Business extends AppCompatActivity {
private ListView business;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_business);
}
public ArrayList<String> arr;
public ArrayAdapter adapter;
#Override
protected void onStart() {
super.onStart();
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference();
arr = new ArrayList<>();
ValueEventListener listener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
map2list((Map) dataSnapshot.getValue());
//formats the datasnapshot entries to strings
adapter.notifyDataSetChanged();
//makes the ListView realtime
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
public void onCancelled(DatabaseError databaseError) {
// Getting Post failed, log a message
System.out.println(databaseError.toException());
// ...
}
};
mDatabase.addValueEventListener((com.google.firebase.database.ValueEventListener) listener);
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, arr);
ListView listView = (ListView) findViewById(R.id.business);
listView.setAdapter(adapter);
}
public void map2list(Map<String,Long> map){
arr.clear();
for (Map.Entry<String, Long> entry : map.entrySet()) {
Long key = Long.parseLong(entry.getKey());
String d = DateFormat.getDateTimeInstance().format(key);
Long value = entry.getValue();
arr.add(d + ": " + value);
}
}
}
If the whole page is blank when you set the content view, this might have happened if one of your views in your layout has a layout_height attribute of 'match parent'. This may be one of the reasons why you are not seeing anything. Another reason why you might not bee seeing anything is that listeners run on separate threads. Try rearranging your code like this.
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, arr);
ListView listView = (ListView) findViewById(R.id.business);
listView.setAdapter(adapter);
mDatabase.addValueEventListener((com.google.firebase.database.ValueEventListener) listener);
// add the listner after setting the adapter
I'm having trouble reloading the ListView after pushing a string to firebase. ListView updates when I restart the application. I have used the notifyDataSetChanged() function with my ListAdapter. Here is what I'm doing:
myFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d("App",dataSnapshot.getValue().toString());
names = dataSnapshot.getValue().toString();
String[] planets = new String[] { names, "Venus", "Earth", "Mars",
"Jupiter", "Saturn", "Uranus", "Neptune"};
ArrayList<String> planetList = new ArrayList<String>();
namesList.addAll( Arrays.asList(planets) );
// Create ArrayAdapter using the planet list.
listAdapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1, android.R.id.text1, namesList);
mainListView.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Firebase engineer here,
I would recommend checking out a simple chat example I made recently (what you're trying to do is detailed here) or our more fully fleshed out Android Chat example, which both demonstrate how to use model objects to bind to ArrayAdapters and ListViews.
The TL;DR is that you want to do something more like this:
// Create instance variables to be used from inside your activity
private ArrayList<Map<String, Object>> mMessages;
private Firebase mRef;
...
// Some time later, instantiate your instance variables
this.mMessages = new ArrayList<Message>();
// Set up ListAdapter
ListAdapter messageAdapter = new ArrayAdapter(this , R.layout.message_layout , mMessages);
this.setListAdapter(messageAdapter);
// Set up Firebase
Firebase.setAndroidContext(this);
this.mRef = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
// Add listener to your Firebase database reference
this.mRef.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
// Create objects and add to ArrayList, which should fire ArrayAdapter methods and update the ListView
Map<String, Object> data = (Map<String, Object>)dataSnapshot.getValue();
MainActivity.this.mMessages.add(data);
}
...
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Every time you are creating new listadapter. Just use the old one. There's a conflict here because you are creating a new adapter and setting it to the same time you are calling notifyDatachanged. It is not logical. Do not bind new adapter.
i trying tu put some elements from database to a List view,
my problem is that when i starrt my activity, I get this:
**com.example.restaurant.Restaurant#2be2d1d0
com.example.restaurant.Restaurant#2be3d3a8**
instead of database objects.
public class Liste extends Activity{
private ListView listview;
private Button boutonAjouter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.liste_restaurant);
listview = (ListView)findViewById(R.id.listView1);
Restaurant mcdo = new Restaurant("mcdo","brossard","take-out","fastfood","450-555-5555");
Restaurant burger = new Restaurant("burger","longueuil","take-out","fastfood","450-999-9999");
RestaurantBDD restaurantBDD = new RestaurantBDD(this);
restaurantBDD.openForWrite();
restaurantBDD.insertRestaurant(mcdo);
restaurantBDD.insertRestaurant(burger);
ArrayList <Restaurant> restaurantlist = restaurantBDD.getAllRestaurants();
restaurantBDD.close();
ArrayAdapter <Restaurant> adapter = new ArrayAdapter<Restaurant>(this, android.R.layout.simple_list_item_1, restaurantlist);
listview.setAdapter(adapter);
boutonAjouter = (Button) findViewById(R.id.btn_nouveau);
boutonAjouter.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Liste.this, Formulaire.class);
startActivity(intent);
}
});
}
}
If you want to show a list with the names of the restaurants, supposing that your Restaurant class contains a string attribute "name", you should first create an array containing the names of the restaurants and then use an ArrayAdapter <String>:
String[] values = new String[restaurantlist.size()];
for(int i=0;i<restaurantlist.size();i++) {
values[i] = restaurantlist.get(i).getName();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, values);
listview.setAdapter(adapter);