我需要一些帮助: - 我的代码中出现异常的原因是什么。它是关于反序列化的吗? - 怎么修复这个bug? - 替代方法实现这个?
基本上,代码假设在我的片段上显示一些cardview,其中包含recyclelerView。
这是包含大部分实现的片段
public class Tab1Buy extends Fragment {
private DatabaseReference mDatabase;
private RecyclerView mPropertyRecyclerView;
private FirebaseRecyclerAdapter<Property, Tab1Buy.PropertyViewHolder> mPropertyAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.property_tab, container, false);
Log.d("debbug", "onCreateView called in TAb1");
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
Log.d("debbug", "onViewCreated called in TAb");
mDatabase = FirebaseDatabase.getInstance().getReference().child("Property");
mDatabase.keepSynced(true);
//TODO might need to remove view from findBy...
mPropertyRecyclerView = (RecyclerView) view.findViewById(R.id.property_recyclerView);
//TODO check is this is necessary?
DatabaseReference personRef = FirebaseDatabase.getInstance().getReference().child("Property");
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
Query personQuery = personRef.orderByKey();
mPropertyRecyclerView.hasFixedSize();
mPropertyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
FirebaseRecyclerOptions<Property> personsOptions =
new FirebaseRecyclerOptions.Builder<Property>()
.setQuery(personQuery, Property.class)
.build();
//FirebaseRecyclerOptions personsOptions = new FirebaseRecyclerOptions.Builder<>().setQuery(personQuery, Property.class);
mPropertyAdapter = new FirebaseRecyclerAdapter<Property, PropertyViewHolder>(personsOptions){
@Override
public Tab1Buy.PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.property_card for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.property_card, parent, false);
Log.d("debbug", "onCreateViewHolder called in Adapter");
return new Tab1Buy.PropertyViewHolder(view);
}
@Override
// Bind the Chat object to the ChatHolder
public void onBindViewHolder(Tab1Buy.PropertyViewHolder holder, final int position, final Property model){
holder.setPrice(model.getPrice());
Log.d("debbug", "onBindViewHolder called in TAb1");
}
};
mPropertyRecyclerView.setAdapter(mPropertyAdapter);
}
@Override
public void onStart(){
super.onStart();
mPropertyAdapter.startListening();
}
@Override
public void onStop(){
super.onStop();
mPropertyAdapter.stopListening();
}
public class PropertyViewHolder extends RecyclerView.ViewHolder {
//TODO correct itemView parm name & mView
View mView;
public PropertyViewHolder(View itemView) {
super(itemView);
mView = itemView;
Log.d("debbug", "PropertyViewHolder RecyclerView called in TAb1");
}
public void setPrice(long price) {
Log.d("debbug", "SetPrice method called PropertyViewHolder RecyclerView called in TAb1");
//TODO implement all the object views
TextView post_price = (TextView) mView.findViewById(R.id.post_price);
post_price.setText((int) price);
}
}
}
这是属性类
import android.util.Log;
/**
* Created by drake on 5/1/18.
*/
// TODO generate setters and getters
public class Property {
private int price;
private String address;
private int numberOfbed;
private int numberOfCar;
private int numberOfbath;
private String image;
public Property(){} //Needed for Firebase
public Property (int price, String address,
int numberOfbed, int numberOfCar,
int numberOfbath, String image) {
this.address = address;
this.price= price;
this.numberOfbath = numberOfbath;
this.numberOfbed = numberOfbed;
this.numberOfCar = numberOfCar;
this.image = image;
}
public int getPrice() {
Log.d("debbug", "GetPrice called in Property");
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getNumberOfbed() {
return numberOfbed;
}
public void setNumberOfbed(int numberOfbed) {
this.numberOfbed = numberOfbed;
}
public int getNumberOfCar() {
return numberOfCar;
}
public void setNumberOfCar(int numberOfCar) {
this.numberOfCar = numberOfCar;
}
public int getNumberOfbath() {
return numberOfbath;
}
public void setNumberOfbath(int numberOfbath) {
this.numberOfbath = numberOfbath;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
这是cardview的xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dfdfdf"
android:orientation="vertical">
<!-- TODO Add white icon -->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/property"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:cardUseCompatPadding="true"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="290dp"
android:orientation="vertical">
<ImageView
android:id="@+id/post_image"
android:contentDescription="@string/property"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="71dp"
android:scaleType="centerCrop"
android:src="@drawable/house1"
app:layout_constraintBottom_toTopOf="@+id/number_bedroom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/post_price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:text="55,000$"
android:textColor="@color/colorPrimary"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.79" />
<TextView
android:id="@+id/post_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginStart="5dp"
android:layout_marginTop="1dp"
android:text="23,Rue Duvivier-hall, Les Cayes, "
android:textColor="#737373"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/post_price"
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="100dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/bathroom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<ImageView
android:id="@+id/bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="25dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/bedroom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<TextView
android:id="@+id/number_bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="2"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/bathroom"
app:layout_constraintEnd_toStartOf="@+id/bathroom" />
<TextView
android:id="@+id/number_bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="3"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/bedroom"
app:layout_constraintEnd_toStartOf="@+id/bedroom" />
<TextView
android:id="@+id/number_garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="1"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/garage"
app:layout_constraintEnd_toStartOf="@+id/garage" />
<ImageView
android:id="@+id/garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="175dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/garage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
这里是logcat输出:
05-09 21:05:00.282 8391-8391/com.realty.drake.kunuk E/RecyclerView: No adapter attached; skipping layout
05-09 21:05:00.396 8391-8420/com.realty.drake.kunuk D/FA: Connected to remote service
05-09 21:05:00.397 8391-8420/com.realty.drake.kunuk V/FA: Processing queued up service tasks: 4
05-09 21:05:00.401 8391-8391/com.realty.drake.kunuk E/RecyclerView: No adapter attached; skipping layout
05-09 21:05:05.601 8391-8391/com.realty.drake.kunuk D/debbug: onCreateViewHolder called in Adapter
05-09 21:05:05.602 8391-8391/com.realty.drake.kunuk D/debbug: PropertyViewHolder RecyclerView called in TAb1
05-09 21:05:05.605 8391-8391/com.realty.drake.kunuk D/AndroidRuntime: Shutting down VM
05-09 21:05:05.608 8391-8391/com.realty.drake.kunuk E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.realty.drake.kunuk, PID: 8391
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.realty.drake.kunuk.Property
at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source)
at com.google.android.gms.internal.firebase_database.zzkt.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)
at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)
at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:35)
at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:106)
at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:122)
at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6482)
at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1767)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:132)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1361)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:869)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java:5438)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16647)
at android.view.ViewGroup.layout(ViewGroup.java`
更新了数据库结构
我修复了代码,这是完整的代码
package com.realty.drake.kunuk;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
/**
* Created by drake on 4/11/18
*/
public class Tab1Buy extends Fragment {
private DatabaseReference personRef;
private RecyclerView mPropertyRecyclerView;
FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;
//*private FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.property_tab, container, false);
mPropertyRecyclerView = rootView.findViewById(R.id.property_recyclerView);
return rootView;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPropertyRecyclerView.hasFixedSize();
mPropertyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
personRef = FirebaseDatabase.getInstance()
.getReference()
.child("Property");
personRef.keepSynced(true);
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
//Query personQuery = personRef.orderByKey();
FirebaseRecyclerOptions<Property> options =
new FirebaseRecyclerOptions.Builder<Property>()
.setQuery(personRef, Property.class)
.build();
//FirebaseRecyclerOptions personsOptions = new FirebaseRecyclerOptions.Builder<>().setQuery(personQuery, Property.class);
mPropertyAdapter = new FirebaseRecyclerAdapter<Property, PropertyViewHolder>(options) {
@Override
// Bind the Property object to the PropertyHolder
public void onBindViewHolder(@NonNull PropertyViewHolder holder, final int position, @NonNull final Property model) {
holder.setPrice(model.getPrice());
holder.setAddress(model.getAddress());
holder.setNumberOfBed(model.getNumberOfBed());
holder.setNumberOfBath(model.getNumberOfBath());
holder.setNumberOfCar(model.getNumberOfCar());
}
@Override
public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.property_card for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.property_card, parent, false);
return new PropertyViewHolder(view);
}
// @Override
// public void onDataChanged() {
// // Called each time there is a new data snapshot. You may want to use this method
// // to hide a loading spinner or check for the "no documents" state and update your UI.
// // ...
// }
// @Override
// public void onError(DatabaseError e) {
// // Called when there is an error getting data. You may want to update
// // your UI to display an error message to the user.
// // ...
// }
};
mPropertyRecyclerView.setAdapter(mPropertyAdapter);
}
@Override
public void onStart() {
super.onStart();
mPropertyAdapter.startListening();
}
@Override
public void onStop() {
super.onStop();
mPropertyAdapter.stopListening();
}
public class PropertyViewHolder extends RecyclerView.ViewHolder {
View mView;
public PropertyViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setPrice(int price) {
TextView Price = (TextView) mView.findViewById(R.id.post_price);
Price.setText(String.valueOf(price));
}
public void setAddress(String address){
TextView Address = (TextView) mView.findViewById(R.id.post_address);
Address.setText(String.valueOf(address));
}
public void setNumberOfBed(int numberOfBed){
TextView NumberOfBed = (TextView) mView.findViewById(R.id.post_bedroom);
NumberOfBed.setText(String.valueOf(numberOfBed));
}
public void setNumberOfBath(int numberOfBath){
TextView NumberOfBath = (TextView) mView.findViewById(R.id.post_bathroom);
NumberOfBath.setText(String.valueOf(numberOfBath));
}
public void setNumberOfCar(int numberOfCar) {
TextView NumberOfCar = (TextView) mView.findViewById(R.id.post_garage);
NumberOfCar.setText(String.valueOf(numberOfCar));
}
}
}