Reputation: 25
Hey I'm new to working with Android and took this app to make I am following a tutorial, and the tutorial reads and writes data from MainActivity.java while I am trying to work in a Fragment.
Although there is no error the app shows nothing the Firebase Realtime Database has JSON data which isn't being displayed in RecylerView as expected.
Here are my Files
MainActivity.java
package com.example.plutus;
import android.os.Bundle;
import android.view.MenuItem;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
private TaskFragment taskFragment;
private TimeFragment timeFragment;
private HabitFragment habitFragment;
private HourFragment hourFragment;
private BottomNavigationView mMainNav;
private FrameLayout mMainFrame;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMainNav = (BottomNavigationView) findViewById(R.id.main_nav);
mMainFrame = (FrameLayout) findViewById(R.id.main_frame);
taskFragment = new TaskFragment();
timeFragment = new TimeFragment();
habitFragment = new HabitFragment();
hourFragment = new HourFragment();
setFragment(taskFragment);
mMainNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_task:
setFragment(taskFragment);
return true;
case R.id.nav_time:
setFragment(timeFragment);
return true;
case R.id.nav_habit:
setFragment(habitFragment);
return true;
case R.id.nav_hour:
setFragment(hourFragment);
return true;
default:
return false;
}
}
});
}
private void setFragment(Fragment fragment) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.main_frame, fragment);
fragmentTransaction.commit();
}
}
TaskAdapter.java
package com.example.plutus;
import android.content.Context;
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.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.MyViewHolder> {
ValueEventListener context;
ArrayList<MyTasks> myTasks;
public TaskAdapter(ValueEventListener c, ArrayList<MyTasks> p) {
context = c;
myTasks = p;
}
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from((Context) context).inflate(R.layout.task_item, parent, false));
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tasktitle.setText(myTasks.get(position).getTasktitle());
}
@Override
public int getItemCount() {
return myTasks.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tasktitle;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tasktitle = (TextView) itemView.findViewById(R.id.tasktitletext);
}
}
}
TaskFragment.java
package com.example.plutus;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
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.ValueEventListener;
import java.util.ArrayList;
/**
* A simple {@link Fragment} subclass.
*/
public class TaskFragment extends Fragment {
//Firebase Json integration
RecyclerView ourTasks;
ArrayList<MyTasks> list;
TaskAdapter taskAdapter;
public TaskFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_task, container, false);
ourTasks = rootView.findViewById(R.id.ourTasks);
ourTasks.setLayoutManager(new LinearLayoutManager(getActivity()));
list = new ArrayList<MyTasks>();
// Inflate the layout for this fragment
DatabaseReference taskDatabaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference taskuser = taskDatabaseReference.child("Task1").child("tasktitle");
taskuser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1: dataSnapshot.getChildren()){
MyTasks p = dataSnapshot1.getValue(MyTasks.class);
list.add(p);
}
taskAdapter = new TaskAdapter(this, list);
ourTasks.setAdapter(taskAdapter);
taskAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Toast.makeText(getContext(), "I'm fetching this", Toast.LENGTH_SHORT).show();
}
});
return rootView;
};
}
MyTasks.java
package com.example.plutus;
public class MyTasks {
String tasktitle;
public MyTasks() {
}
public MyTasks(String tasktitle) {
this.tasktitle = tasktitle;
}
public String getTasktitle() {
return tasktitle;
}
public void setTasktitle(String tasktitle) {
this.tasktitle = tasktitle;
}
}
I can't understand where is the actual problem.
Edit: Included JSON Files.
{
"Plutus":{
"Task1":{
"tasktitle":"Create an awesome app"
},
"Task2":{
"tasktitle":"Learn More Android"
},
"Task3":{
"tasktitle":"Learn Android Pentesting too"
},
"Task4":{
"tasktitle":"Oi don't forget Bug Hunting"
}
}
}
Upvotes: 0
Views: 51
Reputation: 598728
A few problems in your code:
Plutus
level of your JSON in your code.getChildren()
.title
node only, the result is not a MyTasks
.To load only the title of the one task, you'd do something like:
DatabaseReference taskDatabaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference taskuser = taskDatabaseReference.child("Plutus/Task1/tasktitle");
taskuser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
Log.i("Firebase", dataSnapshot.getValue(String.class));
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // make sure to show the programming error
}
});
To load a single task, but the entire task, it'd be something like:
DatabaseReference taskDatabaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference taskuser = taskDatabaseReference.child("Plutus/Task1");
taskuser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
MyTasks p = dataSnapshot.getValue(MyTasks.class);
Log.i("Firebase", p.toString());
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // make sure to show the programming error
}
});
And to load all tasks, and add them to an adapter/view, it'd be something like:
taskAdapter = new TaskAdapter(this, list);
ourTasks.setAdapter(taskAdapter);
DatabaseReference taskDatabaseReference = FirebaseDatabase.getInstance().getReference();
DatabaseReference taskuser = taskDatabaseReference.child("Plutus");
taskuser.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot taskSnapshot: dataSnapshot.getChildren()){
MyTasks p = taskSnapshot.getValue(MyTasks.class);
list.add(p);
}
taskAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
throw databaseError.toException(); // make sure to show the programming error
}
});
You'll note that I pulled the adapter out of the listener here. You don't need to rebuild a new adapter every time the data changes, but can instead just update the data in list
and then notify the adapter, so that it updates the UI.
Upvotes: 1