0

我試圖實現一個自定義的PagerAdapter實現Firebase,就像FirebaseListAdapter和FirebaseRecyclerAdapter一樣。我查看了GitHub here上的源代碼,但在Android Studio中遇到了一些錯誤。下面是一個使用了大量的類都是從給定鏈路我FirebasePagerAdapter:如何在Android中使用Firebase實現自定義PagerAdapter?

  • ChangeEventListener
  • ClassSnapshotParser
  • FirebaseAdapter
  • FirebaseArray
  • ObservableSnapshotArray:從給定鏈路使用

    public abstract class FirebasePagerAdapter<T> extends PagerAdapter implements FirebaseAdapter, ChangeEventListener { 
    
        private static String TAG = "firebasepageradapter"; 
        protected final Activity mActivity; 
        protected final ObservableSnapshotArray<T> mSnapshots; 
        protected final int mLayout; 
    
        /** 
        * @param activity The {@link Activity} containing the {@link android.support.v4.view.ViewPager} 
        * @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 snapshots The data used to populate the adapter 
        */ 
        public FirebasePagerAdapter(Activity activity, 
               ObservableSnapshotArray<T> snapshots, 
               @LayoutRes int modelLayout) { 
         mActivity = activity; 
         mSnapshots = snapshots; 
         mLayout = modelLayout; 
    
         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 #FirebasePagerAdapter(Activity, ObservableSnapshotArray, int) 
        */ 
        public FirebasePagerAdapter(Activity activity, 
               SnapshotParser<T> parser, 
               @LayoutRes int modelLayout, 
               Query query) { 
         this(activity, new FirebaseArray<>(query, parser), modelLayout); 
        } 
    
        /** 
        * @see #FirebasePagerAdapter(Activity, SnapshotParser, int, Query) 
        */ 
        public FirebasePagerAdapter(Activity activity, 
               Class<T> modelClass, 
               @LayoutRes int modelLayout, 
               Query query) { 
         this(activity, new ClassSnapshotParser<>(modelClass), modelLayout, query); 
        } 
    
        @Override 
        public int getCount() { 
         return mSnapshots.size(); 
        } 
    
        @Override 
        public boolean isViewFromObject(View view, Object object) { 
         return false; 
        } 
    
        @Override 
        public void startListening() { 
         if (!mSnapshots.isListening(this)) { 
          mSnapshots.addChangeEventListener(this); 
         } 
        } 
    
        @Override 
        public void cleanup() { 
         mSnapshots.removeChangeEventListener(this); 
        } 
    
        @Override 
        public Object getItem(int position) { 
         return mSnapshots.get(position).getKey().hashCode(); 
        } 
    
        @Override 
        public DatabaseReference getRef(int position) { 
         return mSnapshots.get(position).getRef(); 
        } 
    
        @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 Object instantiateItem(ViewGroup container, int position) { 
         View view = mActivity.getLayoutInflater().inflate(mLayout, container, 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); 
    
    } 
    

  • 前提
  • SnapshotParser

我已經強烈搜查谷歌和SO爲例或解決方案,但儘管需要一個FirebasePagerAdapter,沒有人提出了一個解決方案,或者至少使其公開。我希望得到此工作並將其公開給其他可能會發現它有用的開發人員。

我得到的錯誤是在instantiateItem方法T model = getItem(position);「不兼容的類型:需要T,發現物體」 與this(activity, new FirebaseArray<>(query, parser), modelLayout);「不能推斷論據」。

我的希望是通過解決這些錯誤,適配器將按預期工作。

+0

注意:這不是其他類似問題的重複。我看過其他的SO問題,他們都沒有給出他們嘗試過的或者從頭開始的例子。這個問題爲任何能夠幫助解決問題的人提供了一個很好的起點。 –

回答

0

我已經通過將getItem方法更改爲GenericType public T getItem(int position)來解決此問題。它現在完美。這裏是我的完整FirebasePagerAdapter類:

public abstract class FirebasePagerAdapter<T> extends PagerAdapter implements FirebaseAdapter, ChangeEventListener { 

    private static String TAG = "firebasepageradapter"; 
    protected final Activity mActivity; 
    protected final ObservableSnapshotArray<T> mSnapshots; 
    protected final int mLayout; 

    /** 
    * @param activity The {@link Activity} containing the {@link android.support.v4.view.ViewPager} 
    * @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 snapshots The data used to populate the adapter 
    */ 
    public FirebasePagerAdapter(Activity activity, 
           ObservableSnapshotArray<T> snapshots, 
           @LayoutRes int modelLayout) { 
     mActivity = activity; 
     mSnapshots = snapshots; 
     mLayout = modelLayout; 

     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 #FirebasePagerAdapter(Activity, ObservableSnapshotArray, int) 
    */ 
    public FirebasePagerAdapter(Activity activity, 
           SnapshotParser<T> parser, 
           @LayoutRes int modelLayout, 
           Query query) { 
     this(activity, new FirebaseArray<>(query, parser), modelLayout); 
    } 

    /** 
    * @see #FirebasePagerAdapter(Activity, SnapshotParser, int, Query) 
    */ 
    public FirebasePagerAdapter(Activity activity, 
           Class<T> modelClass, 
           @LayoutRes int modelLayout, 
           Query query) { 
     this(activity, new ClassSnapshotParser<>(modelClass), modelLayout, query); 
    } 

    @Override 
    public int getCount() { 
     return mSnapshots.size(); 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object object) { 
     return view == object; 
    } 

    @Override 
    public void startListening() { 
     if (!mSnapshots.isListening(this)) { 
      mSnapshots.addChangeEventListener(this); 
     } 
    } 

    @Override 
    public void cleanup() { 
     mSnapshots.removeChangeEventListener(this); 
    } 

    @Override 
    public T getItem(int position) { 
     return mSnapshots.getObject(position); 
    } 

    @Override 
    public DatabaseReference getRef(int position) { 
     return mSnapshots.get(position).getRef(); 
    } 

    @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 Object instantiateItem(ViewGroup container, int position) { 
     View view = mActivity.getLayoutInflater().inflate(mLayout, container, false); 

     //T model = getItem(position); 
     T model = getItem(position); 

     // Call out to subclass to marshall this model into the provided view 
     populateView(view, model, position); 
     container.addView(view); 
     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); 

    @Override 
    public void destroyItem(ViewGroup container, int position, Object object) { 
     container.removeView((RelativeLayout)object); 
    } 

} 

我已經發布需要這個一切都在GitHub上工作的其他人可能會發現它很有用。你可以找到它here