Firebase列表适配器没有工作显示错误.......当尝试初始化它?

时间:2017-12-19 04:12:14

标签: android firebase

我尝试了几次,但无法找到我在做错误的地方plz帮助我并且plz显示我的错误.......它在我初始化firebaseListAdapter对象时显示错误。在此行(MainActivity.this, Boxer.class,android.R.layout.simple_list_item_1, databaseReference)中,当我将鼠标悬停在线上时,它会显示FirebaseListAdapter() in FirebaseListAdapter cannot be applied to:

MainActivity.java

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);

    }
}

Boxer.java文件

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;
    }
}

app或build.gradle(Module:app)

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'

FirebaseListAdapter.java

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);
}

logcat的

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

1 个答案:

答案 0 :(得分:1)

在FirebaseUI的3.x.x版中,适配器的初始化与以前的版本不同。这在upgrade documentationdescribed 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) {
        ...
    }
};