我尝试了几次,但无法找到我在做错误的地方plz帮助我并且plz显示我的错误.......它在我初始化firebaseListAdapter对象时显示错误。在此行(MainActivity.this, Boxer.class,android.R.layout.simple_list_item_1, databaseReference)
中,当我将鼠标悬停在线上时,它会显示FirebaseListAdapter() in FirebaseListAdapter cannot be applied to:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseListAdapter;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
public class MainActivity extends AppCompatActivity {
ListView listView;
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
FirebaseListAdapter<Boxer> fireBaseListAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.listView);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
firebaseDatabase = FirebaseDatabase.getInstance();
databaseReference = firebaseDatabase.getReference();
databaseReference.keepSynced(true);
FirebaseListOptions<Boxer> options = new FirebaseListOptions.Builder<Boxer>()
.setQuery(databaseReference, Boxer.class)
.build();
fireBaseListAdapter = new FirebaseListAdapter<Boxer>(options) {
@Override
protected void populateView(View view, Boxer model, int position) {
((TextView)view.findViewById(android.R.id.text1)).setText(model.getBoxerName());
}
};
listView.setAdapter(fireBaseListAdapter);
}
}
public class Boxer {
private String boxerName;
private int punchPower;
private int punchSpeed;
public Boxer() {
}
public Boxer(String boxerName, int punchPower, int punchSpeed) {
this.boxerName = boxerName;
this.punchPower = punchPower;
this.punchSpeed = punchSpeed;
}
public String getBoxerName() {
return boxerName;
}
public int getPunchPower() {
return punchPower;
}
public int getPunchSpeed() {
return punchSpeed;
}
}
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.narayanmaity.firebase_list_adapter"
minSdkVersion 19
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner
"android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.0.1'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.google.firebase:firebase-database:11.6.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
implementation 'com.firebaseui:firebase-ui-database:3.1.1'
}
apply plugin: 'com.google.gms.google-services'
public abstract class FirebaseListAdapter<T> extends BaseAdapter implements FirebaseAdapter<T> {
private static final String TAG = "FirebaseListAdapter";
protected final Context mContext;
protected final ObservableSnapshotArray<T> mSnapshots;
protected final int mLayout;
/**
* @param context The {@link Activity} containing the {@link ListView}
* @param snapshots The data used to populate the adapter
* @param modelLayout This is the layout used to represent a single list item. You will be
* responsible for populating an instance of the corresponding view with the
* data from an instance of modelClass.
* @param owner the lifecycle owner used to automatically listen and cleanup after {@link
* FragmentActivity#onStart()} and {@link FragmentActivity#onStop()} events
* reflectively.
*/
public FirebaseListAdapter(Context context,
ObservableSnapshotArray<T> snapshots,
@LayoutRes int modelLayout,
LifecycleOwner owner) {
mContext = context;
mSnapshots = snapshots;
mLayout = modelLayout;
if (owner != null) { owner.getLifecycle().addObserver(this); }
}
/**
* @see #FirebaseListAdapter(Context, ObservableSnapshotArray, int, LifecycleOwner)
*/
public FirebaseListAdapter(Context context,
ObservableSnapshotArray<T> snapshots,
@LayoutRes int modelLayout) {
this(context, snapshots, modelLayout, null);
startListening();
}
/**
* @param parser a custom {@link SnapshotParser} to convert a {@link DataSnapshot} to the model
* class
* @param query The Firebase location to watch for data changes. Can also be a slice of a
* location, using some combination of {@code limit()}, {@code startAt()}, and
* {@code endAt()}. <b>Note, this can also be a {@link DatabaseReference}.</b>
* @see #FirebaseListAdapter(Context, ObservableSnapshotArray, int)
*/
public FirebaseListAdapter(Context context,
SnapshotParser<T> parser,
@LayoutRes int modelLayout,
Query query) {
this(context, new FirebaseArray<>(query, parser), modelLayout);
}
/**
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query)
* @see #FirebaseListAdapter(Context, ObservableSnapshotArray, int, LifecycleOwner)
*/
public FirebaseListAdapter(Context context,
SnapshotParser<T> parser,
@LayoutRes int modelLayout,
Query query,
LifecycleOwner owner) {
this(context, new FirebaseArray<>(query, parser), modelLayout, owner);
}
/**
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query)
*/
public FirebaseListAdapter(Context context,
Class<T> modelClass,
@LayoutRes int modelLayout,
Query query) {
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, query);
}
/**
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query, LifecycleOwner)
*/
public FirebaseListAdapter(Context context,
Class<T> modelClass,
@LayoutRes int modelLayout,
Query query,
LifecycleOwner owner) {
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, query, owner);
}
@Override
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void startListening() {
if (!mSnapshots.isListening(this)) {
mSnapshots.addChangeEventListener(this);
}
}
@Override
public void cleanup() {
mSnapshots.removeChangeEventListener(this);
}
@SuppressWarnings("unused")
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
void cleanup(LifecycleOwner source, Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_STOP) {
cleanup();
} else if (event == Lifecycle.Event.ON_DESTROY) {
source.getLifecycle().removeObserver(this);
}
}
@Override
public void onChildChanged(ChangeEventListener.EventType type,
DataSnapshot snapshot,
int index,
int oldIndex) {
notifyDataSetChanged();
}
@Override
public void onDataChanged() {
}
@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, error.toException());
}
@Override
public T getItem(int position) {
return mSnapshots.getObject(position);
}
@Override
public DatabaseReference getRef(int position) {
return mSnapshots.get(position).getRef();
}
@Override
public int getCount() {
return mSnapshots.size();
}
@Override
public long getItemId(int i) {
// http://stackoverflow.com/questions/5100071/whats-the-purpose-of-item-ids-in-android-listview-adapter
return mSnapshots.get(i).getKey().hashCode();
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
if (view == null) {
view = LayoutInflater.from(mContext).inflate(mLayout, viewGroup, false);
}
T model = getItem(position);
// Call out to subclass to marshall this model into the provided view
populateView(view, model, position);
return view;
}
/**
* Each time the data at the given Firebase location changes, this method will be called for
* each item that needs to be displayed. The first two arguments correspond to the mLayout and
* mModelClass given to the constructor of this class. The third argument is the item's position
* in the list.
* <p>
* Your implementation should populate the view using the data contained in the model.
*
* @param v The view to populate
* @param model The object containing the data used to populate the view
* @param position The position in the list of the view being populated
*/
protected abstract void populateView(View v, T model, int position);
}
12-19 00:06:31.599 2279-2279/? E/libprocessgroup: failed to make and chown /acct/uid_10061: Read-only file system
12-19 00:06:32.904 2279-2316/com.example.narayanmaity.firebase_list_adapter E/FirebaseInstanceId: Google Play services missing or without correct permission.
12-19 00:06:33.468 2279-2279/com.example.narayanmaity.firebase_list_adapter E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.narayanmaity.firebase_list_adapter, PID: 2279
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.narayanmaity.firebase_list_adapter/com.example.narayanmaity.firebase_list_adapter.MainActivity}: java.lang.RuntimeException: Layout cannot be null. Call setLayout.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.RuntimeException: Layout cannot be null. Call setLayout.
at com.firebase.ui.common.Preconditions.assertNonNull(Preconditions.java:24)
at com.firebase.ui.database.FirebaseListOptions$Builder.build(FirebaseListOptions.java:162)
at com.example.narayanmaity.firebase_list_adapter.MainActivity.onCreate(MainActivity.java:38)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
12-19 00:06:33.774 2279-2321/com.example.narayanmaity.firebase_list_adapter E/ActivityThread: Failed to find provider info for com.google.android.gms.chimera
答案 0 :(得分:1)
在FirebaseUI的3.x.x版中,适配器的初始化与以前的版本不同。这在upgrade documentation和described here中注明。
将您的代码更改为:
FirebaseListOptions<Boxer> options = new FirebaseListOptions.Builder<Boxer>()
.setQuery(databaseReference, Boxer.class)
.build();
fireBaseListAdapter = new FirebaseListAdapter<Boxer>(options) {
@Override
protected void populateView(View view, Boxer model, int position) {
...
}
};