问题
I'm trying to make an application where when i press a button it would open the fragment which contains a Recycler view where the data is retried from Firebase Firestore and added to an adapter. I've managed to connect the pieces together but the recycler view does not seem to be showing but the other components inside the fragments are.
Anyone able to find out what am I missing in the code or what I'm doing wrong?
MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReport = findViewById(R.id.myReport);
publicReport = findViewById(R.id.publicReport);
myReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myReportFragment();
}
});
/*Opens separate fragment but similar code*/
publicReport.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
publicReportFragment();
}
});
}
public void publicReportFragment() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.report_fragments, new PublicReportFragment());
fragmentTransaction.commit();
}
public void myReportFragment() {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.report_fragments, new MyReportFragment());
fragmentTransaction.commit();
}
activity_main.xml
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/publicReport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginStart="74dp"
android:layout_marginLeft="74dp"
android:text="public report" />
<Button
android:id="@+id/myReport"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_marginTop="-1dp"
android:layout_marginEnd="67dp"
android:layout_marginRight="67dp"
android:text="public report"
app:layout_anchorGravity="top|center" />
<FrameLayout
android:id="@+id/report_fragments"
android:layout_below="@id/myReport"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</RelativeLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
MyReportFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_report, container, false);
Query query = reportRef.whereEqualTo("reportByUserID","K2TPzSkIjvXCI2m1QGhyYr7qWpw1").orderBy("date", Query.Direction.DESCENDING);
FirestoreRecyclerOptions<Report> options = new FirestoreRecyclerOptions.Builder<Report>()
.setQuery(query, Report.class)
.build();
adapter = new ReportAdapter(options);
myRecyclerView = view.findViewById(R.id.myReportRecyclerView);
myRecyclerView.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setAdapter(adapter);
return view;
}
fragment_my_report.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MyReportFragment">
<!--When button click the text view shows but recycler view doesnt*/-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MY REPORTS"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/myReportRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
ReportAdapter.java
public class ReportAdapter extends FirestoreRecyclerAdapter<Report, ReportAdapter.ReportHolder>{
public ReportAdapter(@NonNull FirestoreRecyclerOptions<Report> options) {
super(options);
}
@Override
protected void onBindViewHolder(@NonNull ReportHolder reportHolder, int i, @NonNull Report report) {
String seriousLvl = "";
reportHolder.txtTitle.setText(report.getReportType());
reportHolder.txtDescription.setText(report.getDescription());
reportHolder.txtDate.setText(report.getDate());
reportHolder.txtReportedBy.setText(report.getReportedBy());
seriousLvl = report.getSeriousness();
if(seriousLvl.equals("Low")){
reportHolder.seriousness.setBackgroundColor(Color.argb(100,0,255,11));
}else if(seriousLvl.equals("Medium")){
reportHolder.seriousness.setBackgroundColor(Color.argb(100,255,220,0));
}else if(seriousLvl.equals("High")){
reportHolder.seriousness.setBackgroundColor(Color.argb(100,255,0,0));
}else{
Log.d("ERROR", "NEITHER: ");
}
}
@NonNull
@Override
public ReportHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.note_item,parent,false);
return new ReportHolder(v);
}
class ReportHolder extends RecyclerView.ViewHolder {
TextView txtTitle,txtDescription,txtDate,txtReportedBy;
CardView seriousness;
public ReportHolder(@NonNull View itemView) {
super(itemView);
seriousness = itemView.findViewById(R.id.seriousness);
txtTitle = itemView.findViewById(R.id.text_view_title);
txtDescription = itemView.findViewById(R.id.text_view_description);
txtDate = itemView.findViewById(R.id.text_view_date);
txtReportedBy = itemView.findViewById(R.id.text_view_report_by);
}
}
}
回答1:
I think you forgot to set size in your adapter:-
@Override
public int getItemCount() {
return yourList.size();
}
回答2:
SOLVED
As mentioned by @Sandeep Malik first I was missing getItemCount()
function and second create a custom adapter to send data through the constructor. It may not be the most elegant way of dealing with the problem but it does solve the problem.
Here are the changes
MyReportFragment.java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mReport = new ArrayList<>();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_my_report, container, false);
myRecyclerView = view.findViewById(R.id.myReportRecyclerView);
Task<QuerySnapshot> query = reportRef
.whereEqualTo("reportedByUserID","K2TPzSkIjvXCI2m1QGhyYr7qWpw1")
.orderBy("date",Query.Direction.DESCENDING)
.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
for(QueryDocumentSnapshot documentSnapshot : queryDocumentSnapshots){
Report report = documentSnapshot.toObject(Report.class);
mReport.add(report);
}
adapter = new ReportsAdapter(getContext(),mReport);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
myRecyclerView.setLayoutManager(linearLayoutManager);
myRecyclerView.setAdapter(adapter);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d("ERROR", "onFailure: "+e.getMessage());
}
});
return view;
}
ReportsAdapter
public class ReportsAdapter extends RecyclerView.Adapter<ReportsAdapter.ReportHolder> {
private Context mContext;
private List<Report> mReports;
public ReportsAdapter(Context context, List<Report> reports){
mContext = context;
mReports = reports;
}
@NonNull
@Override
public ReportHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.note_item, parent, false);
return new ReportHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ReportHolder holder, int position) {
String seriousLvl = "";
Report report = mReports.get(position);
holder.txtTitle.setText(report.getReportType());
holder.txtDescription.setText(report.getDescription());
holder.txtDate.setText(report.getDate());
holder.txtReportedBy.setText(report.getReportedBy());
seriousLvl = report.getSeriousness();
if (seriousLvl.equals("Low")) {
holder.seriousness.setBackgroundColor(Color.argb(100, 0, 255, 11));
} else if (seriousLvl.equals("Medium")) {
holder.seriousness.setBackgroundColor(Color.argb(100, 255, 220, 0));
} else if (seriousLvl.equals("High")) {
holder.seriousness.setBackgroundColor(Color.argb(100, 255, 0, 0));
} else {
Log.d("ERROR", "NEITHER: ");
}
}
@Override
public int getItemCount() {
return mReports.size();
}
public class ReportHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView txtTitle, txtDescription, txtDate, txtReportedBy;
CardView seriousness;
public ReportHolder(@NonNull View itemView) {
super(itemView);
seriousness = itemView.findViewById(R.id.seriousness);
txtTitle = itemView.findViewById(R.id.text_view_title);
txtDescription = itemView.findViewById(R.id.text_view_description);
txtDate = itemView.findViewById(R.id.text_view_date);
txtReportedBy = itemView.findViewById(R.id.text_view_report_by);
}
@Override
public void onClick(View view) {
}
}
}
来源:https://stackoverflow.com/questions/56964999/recycler-view-not-displaying-in-fragment