Reputation: 3216
I made a FirebaseRecylerAdapter
for a RecyclerView and my problem is that FirebaseRecyclerAdapter
is not calling the onCreateViewHolder
(consequently the recyclerView displays nothing). I found on some posts that it's because getItemCount = 0
(At the beginning of my project I had no getItemCount
method). So I made it and it doesn't solve my problem because getItemCount
returns 0 and I don't understand why. I can write on my database correctly so I know that my db is successfully connected and I run into debug mode and we can see that.
MainActivity.java :
public class MainActivity extends AppCompatActivity {
private RecyclerView mTaskList;
private DatabaseReference mDatabase;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mTaskList = findViewById(R.id.task_list);
//mTaskList.setHasFixedSize(true);
mTaskList.setLayoutManager(new LinearLayoutManager(this));
mDatabase = FirebaseDatabase.getInstance().getReference().child("Tasks");
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, AddTaskActivity.class);
startActivity(intent);
}
});
}
public static class TaskViewHolder extends RecyclerView.ViewHolder{
public TaskViewHolder(View itemView) {
super(itemView);
View mView = itemView;
}
public void setName(String name)
{
TextView task_name = itemView.findViewById(R.id.task_name);
task_name.setText(name);
}
/*public void setTime(String time)
{
TextView task_time = itemView.findViewById(R.id.task_time);
task_time.setText(time);
}*/
}
@Override
protected void onStart() {
super.onStart();
Log.d("POS", "onStart: ");
FirebaseRecyclerOptions<Task> options =
new FirebaseRecyclerOptions.Builder<Task>()
.setQuery(mDatabase, Task.class)
.build();
FirebaseRecyclerAdapter<Task, TaskViewHolder> array = new FirebaseRecyclerAdapter<Task, TaskViewHolder>(options) {
@Override
public int getItemCount() {
Log.d("NB", "getItemCount: " + super.getItemCount());
return super.getItemCount();
}
@Override
protected void onBindViewHolder(TaskViewHolder holder, int position, Task model) {
holder.setName(model.getName());
Log.d("BIND", "onBindViewHolder: pass");
//holder.setTime(model.getTime());
}
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_main,
parent, false);
Log.d("CREATE", "onCreate: pass");
return new TaskViewHolder(view);
}
};
array.notifyDataSetChanged();
mTaskList.setAdapter(array);
}
Task.java :
public class Task {
private String name;
//private String time;
public Task(String name){
this.name = name;
//this.time = time;
}
public Task(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
AddTaskActivity.java :
public class AddTaskActivity extends AppCompatActivity {
private FirebaseDatabase db;
DatabaseReference myRef;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_task);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_task, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
editText = findViewById(R.id.desc);
String desc = editText.getText().toString();
//noinspection SimplifiableIfStatement
if (id == R.id.action_save) {
myRef = db.getInstance().getReference().child("Tasks");
DatabaseReference newTask = myRef.push();
newTask.child("name").setValue(desc);
AddTaskActivity.this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
Thank you in advance and do let me know if you need more information.
and my logcat when I launch mainActivity :
01-15 10:57:57.830 18882-18882/? W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[2], Con:u:r:zygote:s0 RAM:SEPF_SECMOBILE_7.0_0009, [-1 -1 -1 -1 0 1]
01-15 10:57:57.832 18882-18882/? I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=com.thauvi_a.todolist
01-15 10:57:57.834 18882-18882/? I/art: Late-enabling -Xcheck:jni
01-15 10:57:57.854 18882-18882/? D/TimaKeyStoreProvider: TimaKeyStore is enabled: try add TimaSignature Service and generateKeyPair Service
01-15 10:57:57.883 18882-18882/? I/ResourcesManager: updateResourcesForOpenThemeChange for Desktop mode
01-15 10:57:57.994 18882-18882/com.thauvi_a.todolist W/System: ClassLoader referenced unknown path: /data/app/com.thauvi_a.todolist-2/lib/arm64
01-15 10:57:58.013 18882-18882/com.thauvi_a.todolist D/FirebaseApp: com.google.firebase.auth.FirebaseAuth is not linked. Skipping initialization.
01-15 10:57:58.019 18882-18882/com.thauvi_a.todolist D/FirebaseApp: com.google.firebase.crash.FirebaseCrash is not linked. Skipping initialization.
01-15 10:57:58.063 18882-18882/com.thauvi_a.todolist I/FirebaseInitProvider: FirebaseApp initialization successful
01-15 10:57:58.066 18882-18882/com.thauvi_a.todolist I/InstantRun: starting instant run server: is main process
01-15 10:57:58.071 18882-18898/com.thauvi_a.todolist I/FA: App measurement is starting up, version: 11910
01-15 10:57:58.071 18882-18898/com.thauvi_a.todolist I/FA: To enable debug logging run: adb shell setprop log.tag.FA VERBOSE
01-15 10:57:58.072 18882-18898/com.thauvi_a.todolist I/FA: To enable faster debug mode event logging run:
adb shell setprop debug.firebase.analytics.app com.thauvi_a.todolist
01-15 10:57:58.072 18882-18898/com.thauvi_a.todolist D/FA: Debug-level message logging enabled
01-15 10:57:58.110 18882-18882/com.thauvi_a.todolist W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
01-15 10:57:58.190 18882-18882/com.thauvi_a.todolist D/TextView: setTypeface with style : 0
01-15 10:57:58.190 18882-18882/com.thauvi_a.todolist D/TextView: setTypeface with style : 0
01-15 10:57:58.210 18882-18882/com.thauvi_a.todolist D/POS: onStart:
01-15 10:57:58.221 18882-18898/com.thauvi_a.todolist I/FA: Tag Manager is not found and thus will not be used
01-15 10:57:58.221 18882-18898/com.thauvi_a.todolist D/FA: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_screen_class(_sc)=MainActivity, firebase_screen_id(_si)=8779723142852401023}]
01-15 10:57:58.222 18882-18882/com.thauvi_a.todolist D/Choreographer: init sf_choreo_doframe debug_Level : 0x4f4cdebug_game_running : false
01-15 10:57:58.224 18882-18882/com.thauvi_a.todolist I/SemDesktopModeManager: registerListener: android.view.ViewRootImpl$3@3835360
01-15 10:57:58.224 18882-18901/com.thauvi_a.todolist I/DynamiteModule: Considering local module com.google.android.gms.firebase_database:4 and remote module com.google.android.gms.firebase_database:6
01-15 10:57:58.224 18882-18901/com.thauvi_a.todolist I/DynamiteModule: Selected remote version of com.google.android.gms.firebase_database, version >= 6
01-15 10:57:58.229 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: ThreadedRenderer.create() translucent=false
01-15 10:57:58.229 18882-18901/com.thauvi_a.todolist W/System: ClassLoader referenced unknown path:
01-15 10:57:58.232 18882-18882/com.thauvi_a.todolist D/InputTransport: Input channel constructed: fd=74
01-15 10:57:58.232 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: setView = DecorView@4b0d4ea[MainActivity] touchMode=true
01-15 10:57:58.241 18882-18901/com.thauvi_a.todolist W/System: ClassLoader referenced unknown path: /data/user_de/0/com.google.android.gms/app_chimera/m/00000035/n/arm64-v8a
01-15 10:57:58.245 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: dispatchAttachedToWindow
01-15 10:57:58.263 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: Relayout returned: oldFrame=[0,0][0,0] newFrame=[0,0][1440,2960] result=0x27 surface={isValid=true 532786037248} surfaceGenerationChanged=true
01-15 10:57:58.263 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: mHardwareRenderer.initialize() mSurface={isValid=true 532786037248} hwInitialized=true
01-15 10:57:58.272 18882-18904/com.thauvi_a.todolist D/NetworkSecurityConfig: No Network Security Config specified, using platform default
01-15 10:57:58.272 18882-18882/com.thauvi_a.todolist D/NB: getItemCount: 0
01-15 10:57:58.272 18882-18882/com.thauvi_a.todolist D/NB: getItemCount: 0
01-15 10:57:58.289 18882-18902/com.thauvi_a.todolist D/libEGL: loaded /vendor/lib64/egl/libGLES_mali.so
01-15 10:57:58.295 18882-18882/com.thauvi_a.todolist W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
01-15 10:57:58.306 18882-18902/com.thauvi_a.todolist I/OpenGLRenderer: Initialized EGL, version 1.4
01-15 10:57:58.307 18882-18902/com.thauvi_a.todolist D/OpenGLRenderer: Swap behavior 1
01-15 10:57:58.310 18882-18902/com.thauvi_a.todolist D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1440x2960]-format:1
01-15 10:57:58.364 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: MSG_RESIZED_REPORT: frame=Rect(0, 0 - 1440, 2960) ci=Rect(0, 96 - 0, 192) vi=Rect(0, 96 - 0, 192) or=1
01-15 10:57:58.364 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
01-15 10:57:58.364 18882-18882/com.thauvi_a.todolist D/ViewRootImpl@e91f019[MainActivity]: mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true 532786037248}
01-15 10:57:58.364 18882-18882/com.thauvi_a.todolist I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
01-15 10:57:58.367 18882-18904/com.thauvi_a.todolist D/TcpOptimizer: TcpOptimizer-ON
01-15 10:57:58.370 18882-18898/com.thauvi_a.todolist D/FA: Connected to remote service
Upvotes: 1
Views: 1212
Reputation: 7720
You need to call FirebaseRecyclerAdapter#startListening()
method to start the data listener. It's best to start the listener in the activity's onStart()
method and then remove the listener in the onStop()
method.
By the way, you can move the adapter declaration in the onCreate()
method for better app performance.
private RecyclerView mTaskList;
private DatabaseReference mDatabase;
private FirebaseRecyclerAdapter<Task, TaskViewHolder> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTaskList = findViewById(R.id.task_list);
mTaskList.setLayoutManager(new LinearLayoutManager(this));
mDatabase = FirebaseDatabase.getInstance().getReference().child("Tasks");
FirebaseRecyclerOptions<Task> options = new FirebaseRecyclerOptions.Builder<Task>()
.setQuery(mDatabase, Task.class)
.build();
adapter = new FirebaseRecyclerAdapter<Task, TaskViewHolder>(options) {
@Override
protected void onBindViewHolder(TaskViewHolder holder, int position, Task model) { }
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { }
};
mTaskList.setAdapter(adapter);
}
Below is the code to start and stop the data listener
@Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
Hope this helps :)
Upvotes: 3