Just trying to show in a RecyclerView the info from my database.
everything works fine. The objects are displayed.
but logcat says:
E/RecyclerView: No adapter attached; skipping layout
This is my the code (DisplayImages.java)
public class DisplayImages extends AppCompatActivity {
DatabaseReference databaseReference;
RecyclerView recyclerView;
RecyclerView.Adapter adapter;
ProgressDialog progressDialog;
List<ImageUploadInfo> list = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_images);
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
progressDialog = new ProgressDialog(DisplayImages.this);
progressDialog.setMessage("Loading Images From Firebase.");
progressDialog.show();
// Setting up Firebase image upload folder path in databaseReference.
// The path is already defined in MainActivity.
databaseReference = FirebaseDatabase.getInstance().getReference(Main.Database_Path);
databaseReference.addValueEventListener(new ValueEventListener() {
#override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
ImageUploadInfo imageUploadInfo = postSnapshot.getValue(ImageUploadInfo.class);
list.add(imageUploadInfo);
}
adapter = new RecyclerViewAdapter(getApplicationContext(), list);
recyclerView.setAdapter(adapter);
progressDialog.dismiss();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
}
And If it makes any difference, this is what i wrote in MainActivity about the DataBase_Path :
public class Main extends AppCompatActivity implements View.OnClickListener {
DatabaseReference databaseReference;
public static final String Database_Path = "All_Image_Uploads_Database";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseReference = FirebaseDatabase.getInstance().getReference(Database_Path);
As you can see I have attached an adapter for Recycleview. so why do I keep getting this error?
i have read other questions related to same problem but none helps.
Yyou need to set the adapter after you set the layour manager, otherwise you'll get the error message you're seeing.
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
//don't set adapter here
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
//set adapter here
Moreover, you can set the adapter with an empty list first and then when you receive the callback from firebase you can update the list and call notifyDatasetChanged() on the adapter. The problem you see is due to the fact that you're not actually setting the adapter until very later in the process (when your firebase call comes back)
Like this:
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(DisplayImages.this));
adapter = new RecyclerViewAdapter(getApplicationContext(), list);
recyclerView.setAdapter(adapter);
databaseReference.addValueEventListener(new ValueEventListener() {
#override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
ImageUploadInfo imageUploadInfo = postSnapshot.getValue(ImageUploadInfo.class);
list.add(imageUploadInfo);
}
adapter.notifyDatasetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
progressDialog.dismiss();
}
});
I don't see anywhere you are creating an adapter and setting that adapter to RecyclerView. You need to create an adapter and set adapter like following:
mAppAdapter = new AppAdapter(mModel); // or whatever constructor you want
recyclerView.setAdapter(mAppAdapter);
EDIT:
You are setting adapter to RecyclerView inside an asynchronous method. So your program will have a non deterministinc amount of time where the adapter is not actually set to recyclerView. To get rid off the warning you get you should initialize and set the adapter above the async method and only update data of the adapter inside the async method
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.
Actually, I make a 1st query which returns a number of objects.
As we could with a standard recyclerView, I would like to filter dynamically these objects with an EditText after the view is created, and update the view dynamically.
For example, if my first query returns and displays 10 objects, the user will be able to search one objet through the 10 objects by making a request with an EditText. The view will display only this object.
Query query = collectionRef.whereArrayContains("customerNearMe", getCurrentUser().getUid());
private void sendToAdapter(Query query) {
FirestoreRecyclerOptions<Restaurant> options = new FirestoreRecyclerOptions.Builder<Restaurant>()
.setQuery(query, Restaurant.class)
.build();
adapter = new RestaurantAdapter(options);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setAdapter(adapter);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(new SimpleItemDecorator(getContext()));
adapter.notifyDataSetChanged();
}
#Override
public void onStart() {
super.onStart();
adapter.startListening();
}
#Override
public void onDestroy() {
super.onDestroy();
adapter.stopListening();
}
Actually, I know how to do it with a simple RecyclerView
private void filter(String text) {
ArrayList<ExampleItem> filteredList = new ArrayList<>();
for (ExampleItem item : mExampleList) {
if (item.getText1().toLowerCase().contains(text.toLowerCase())) {
filteredList.add(item);
}
}
mAdapter.filterList(filteredList);
}
but I am a newbie with Firestore.
I'm trying to populate my ListView with User objects from Firebase Database. I've seen some people use RecyclerView but I cannot get RecyclerView to work on my Android Studio (maybe i'm using incompatible dependencies).
Anyway here is my code:
// necessary imports
public class List extends AppCompatActivity {
ListView usersList;
private DatabaseReference userDatabase;
ArrayList<String> list = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
usersList = (ListView) findViewById(R.id.list_users);
userDatabase = FirebaseDatabase.getInstance().getReference().child("Users");
}
#Override
protected void onStart() {
super.onStart();
// Populate ArrayAdapter with User objects from Firebase Database.
ArrayAdapter<Users> Adapter = new ArrayAdapter<Users>(this, Users.class, android.R.layout.simple_expandable_list_item_1, userDatabase){
// Populate here, don't know what to do.
};
usersList.setAdapter(Adapter);
usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Users.connectTo = list.get(i);
Intent chatActivity = new Intent(List.this, ChatActivity.class);
startActivity(chatActivity);
}
});
}
}
I know my ArrayList takes a String at the beginning, I will change that to Users.
ArrayAdapter parameters are not working, despite looking at the docs and it telling me this way.
Not sure how to properly implement RecyclerView
Not got much experience with Android Studio/Java.
I have created listview, which contains data from firebase. Now, I want to add this data into table, but I don't have any idea how to do it.
Here is my code:
DatabaseReference mDatabase = FirebaseDatabase.getInstance().getReference("Highscore");
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
final List<String> areas = new ArrayList<String>();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
Score score = postSnapshot.getValue(Score.class);
areas.add(score.getName()+" "+score.getLevel()+" "+score.getScore());
}
ListView highScoreSpin = (ListView)findViewById(R.id.list);
ArrayAdapter<String> areasAdapter = new ArrayAdapter<String>(HighscoreActivity.this, android.R.layout.simple_list_item_1, areas);
areasAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
highScoreSpin.setAdapter(areasAdapter);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
}
});
Having score.getName(), score.getLevel() and score.getScore() you can easely add it into a TableView. Please read this post to learn how it can be done.
Remember to put this lines of code outside the onDataChange() method.
ListView highScoreSpin = (ListView)findViewById(R.id.list);
ArrayAdapter<String> areasAdapter = new ArrayAdapter<String>(HighscoreActivity.this, android.R.layout.simple_list_item_1, areas);
areasAdapter.setDropDownViewResource(android.R.layout.simple_list_item_1);
highScoreSpin.setAdapter(areasAdapter);
Hope it helps.
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