我正在RecyclerView
中构建Fragment
,它会从 Firebase 数据库中提取数据,并假设在CardView
上显示这些数据。我编写了如下所示的所有代码,但运行时显示的所有代码都是空的RecyclerView
片段,方法getItemCount()
总是返回0。
card_item.xml
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="10dp"
android:orientation="horizontal"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="5dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<TextView
android:id="@+id/primaryText"
android:layout_width="300dp"
android:layout_height="60dp"
android:textColor="@color/colorPrimary"
android:textSize="24sp" />
<TextView
android:id="@+id/subText"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textColor="@color/colorPrimary"
android:textSize="14sp" />
<TextView
android:id="@+id/rateValue"
android:layout_width="300dp"
android:layout_height="60dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/subText"
android:textColor="@color/colorPrimary"
android:textSize="24sp" />
</RelativeLayout>
fragment_profile.xml
<LinearLayout 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"
android:background="#F1F1F1"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/placesRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
PlacesModel.java
public class PlaceModel {
private String mPrimaryText, mSubText, mRateValue;
public PlaceModel() {
}
public PlaceModel(String mCardImage, String mPrimaryText,
String mSubText, String mRateValue) {
//this.mCardImageURL = mCardImage;
this.mPrimaryText = mPrimaryText;
this.mSubText = mSubText;
this.mRateValue = mRateValue;
}
public void setmPrimaryText(String mPrimaryText) {
this.mPrimaryText = mPrimaryText;
}
public void setmSubText(String mSubText) {
this.mSubText = mSubText;
}
public void setmRateValue(String mRateValue) {
this.mRateValue = mRateValue;
}
public String getmPrimaryText() {
return mPrimaryText;
}
public String getmSubText() {
return mSubText;
}
public String getmRateValue() {
return mRateValue;
}}
PlacesAdapter.java
public class PlacesAdapter extends RecyclerView.Adapter<PlacesAdapter.PlacesViewHolder> {
private ArrayList<PlaceModel> cardContents;
private Context context;
public PlacesAdapter(Context context, ArrayList<PlaceModel> cardContents) {
this.cardContents = cardContents;
this.context = context;
}
@Override
public PlacesViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.card_item, parent, false);
return new PlacesViewHolder(view);
}
@Override
public void onBindViewHolder(PlacesViewHolder holder, int position) {
PlaceModel place = cardContents.get(position);
holder.primaryText.setText(place.getmPrimaryText());
holder.subText.setText(place.getmSubText());
holder.rateValue.setText(place.getmRateValue());
}
@Override
public int getItemCount() {
return cardContents.size();
}
public class PlacesViewHolder extends RecyclerView.ViewHolder {
CardView cardView;
public TextView primaryText, subText, rateValue;
public PlacesViewHolder(View itemView) {
super(itemView);
cardView = (CardView) itemView.findViewById(R.id.cardView);
primaryText = (TextView) itemView.findViewById(R.id.primaryText);
subText = (TextView) itemView.findViewById(R.id.subText);
rateValue = (TextView) itemView.findViewById(R.id.rateValue);
}
}}
FirebaseConnector.java
public class FirebaseConnector {
DatabaseReference db;
PlaceModel placeModel = new PlaceModel();
ArrayList<PlaceModel> cardContent = new ArrayList<>();
public FirebaseConnector(DatabaseReference db) {
this.db = db;
}
public ArrayList<PlaceModel> retrieve() {
db.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
fetchData(dataSnapshot);
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
return cardContent;
}
private void fetchData(DataSnapshot dataSnapshot) {
cardContent.clear(); //clear card content from last usage
for (DataSnapshot ds : dataSnapshot.getChildren()) {
placeModel = ds.child("Place Model").getValue(PlaceModel.class);
cardContent.add(placeModel);
}
}}
ProfileFragment.java
public class ProfileFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
/////////////////////////////////////////////////////////////
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private RecyclerView placesRecycler;
private PlacesAdapter placesAdapter;
private FirebaseConnector connector;
private DatabaseReference ref;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public ProfileFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static ProfileFragment newInstance(String param1, String param2) {
ProfileFragment fragment = new ProfileFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_profile, container, false);
mAuth = FirebaseAuth.getInstance();
//Initialize Database..
ref = FirebaseDatabase.getInstance().getReference();
connector = new FirebaseConnector(ref);
//Initialize RecyclerView
placesRecycler = (RecyclerView)v.findViewById(R.id.placesRecycler);
placesRecycler.setLayoutManager(new LinearLayoutManager(this.getActivity()));
//Adapter
placesAdapter = new PlacesAdapter(this.getActivity(), connector.retrieve());
placesRecycler.setAdapter(placesAdapter);
Toast.makeText(getActivity(), "We have "+placesAdapter.getItemCount()+" cards", Toast.LENGTH_LONG).show();
return v;
}
@Override
public void onStart() {
super.onStart();
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}
public void updateUI() {
if (mAuth.getCurrentUser() == null) {
startActivity(new Intent(getActivity(), LoginActivity.class));
}
}}
数据库试用结构 Database trial structure
答案 0 :(得分:1)
我看到retrieve方法将返回空数组列表,因为它不会等待监听器完成(注意监听器在另一个线程中工作)
每次更新ArrayList写入
时,您都可以将侦听器移动到配置文件片段placesRecycler.notifydatasetchanged();