Search code examples
androidfirebasefirebase-realtime-databasefirebaseui

FirebaseRecyclerAdapter multiple viewHolder


I am trying to use FirebaseRecyclerAdapter with RecyclerView to display items of different types. Specifically stock transactions of a particular stock by a user. I have extended FirebaseRecyclerAdapter as per my understanding but it doesn't work. Following is the code:

public abstract class StockTransactionFirebaseRecyclerAdapter extends
        FirebaseRecyclerAdapter<StockTransactionType, TransactionViewHolder>
        implements ListenerInterface
{
    private static final String TAG = "StockTxnAdapter";
    private DatabaseReference mFirebaseDatabaseReference;
    private FirebaseListenerManager mFirebaseListenerManager;
    private String mUserId;

    public StockTransactionFirebaseRecyclerAdapter (Query ref, DatabaseReference databaseReference,
                                                    String userId)
    {
        // The layout portfolio_buy_transaction_item is just a dummy since we are
        // inflating our own layouts when required.
        super (StockTransactionType.class, R.layout.portfolio_buy_transaction_item,
                TransactionViewHolder.class, ref);

        mFirebaseDatabaseReference = databaseReference;
        mFirebaseListenerManager = new FirebaseListenerManager ();
        mUserId = userId;
        Log.e (TAG, "Inside StockTransactionFirebaseRecyclerAdapter");
    }

    @Override
    public int getItemViewType (int position)
    {
        StockTransactionType stockTransactionType = getItem (position);
        Log.e (TAG, "Inside getItemViewType (" + position + "): " + stockTransactionType.returnType ());
        return stockTransactionType.returnType ();
    }

    @Override
    public TransactionViewHolder onCreateViewHolder (ViewGroup parent, int viewType)
    {
        Log.e (TAG, "onCreateViewHolder for " + viewType);
        View itemView;
        switch (viewType)
        {
            case StockTransactionType.TRANSACTION_TYPE_BUY:
                itemView = LayoutInflater.from (parent.getContext ())
                        .inflate (R.layout.portfolio_buy_transaction_item, parent, false);
                return new BuyTransactionViewHolder (itemView);
            case StockTransactionType.TRANSACTION_TYPE_SELL:
                itemView = LayoutInflater.from (parent.getContext ())
                        .inflate (R.layout.portfolio_sell_transaction_item, parent, false);
                return new SellTransactionViewHolder (itemView);
            case StockTransactionType.TRANSACTION_TYPE_DIVIDEND:
                itemView = LayoutInflater.from (parent.getContext ())
                        .inflate (R.layout.portfolio_dividend_transaction_item, parent, false);
                return new DividendTransactionViewHolder (itemView);
            case StockTransactionType.TRANSACTION_TYPE_SPLIT:
                itemView = LayoutInflater.from (parent.getContext ())
                        .inflate (R.layout.portfolio_split_transaction_item, parent, false);
                return new SplitTransactionViewHolder (itemView);
        }

        throw new IllegalStateException ("Invalid transaction type: " + viewType);
    }

    @Override
    protected void populateViewHolder (final TransactionViewHolder viewHolder,
                                       StockTransactionType stockTransactionType, int position)
    {
        final String transactionId = this.getRef (position).getKey ();
        final Class transaction;
        final String location;

        Log.e (TAG, "populateViewHolder: " + stockTransactionType.getClass ().getName () + " "
                + position);

        switch (stockTransactionType.returnType ())
        {
            case StockTransactionType.TRANSACTION_TYPE_BUY:
                transaction = BuyStockTransaction.class;
                location = FirebaseDatabaseUtil.CHILD_TRANSACTIONS_BUY;
                break;
            case StockTransactionType.TRANSACTION_TYPE_SELL:
                transaction = SellStockTransaction.class;
                location = FirebaseDatabaseUtil.CHILD_TRANSACTIONS_SELL;
                break;
            case StockTransactionType.TRANSACTION_TYPE_SPLIT:
                transaction = SplitStockTransaction.class;
                location = FirebaseDatabaseUtil.CHILD_TRANSACTIONS_SPLIT;
                break;
            case StockTransactionType.TRANSACTION_TYPE_DIVIDEND:
                transaction = DividendStockTransaction.class;
                location = FirebaseDatabaseUtil.CHILD_TRANSACTIONS_DIVIDEND;
                break;
            default:
                throw new IllegalStateException ("Invalid transaction type: "
                        + stockTransactionType.renameTypeString ());
        }

        DatabaseReference databaseReference = mFirebaseDatabaseReference
                .child (location).child (mUserId).child (transactionId);
        ValueEventListener valueEventListener = databaseReference
                .addValueEventListener (new ValueEventListener ()
                {
                    @Override
                    public void onDataChange (DataSnapshot dataSnapshot)
                    {
                        StockTransaction stockTransaction = (StockTransaction) dataSnapshot.getValue (transaction);
                        viewHolder.assignViewHolder (stockTransaction);
                    }

                    @Override
                    public void onCancelled (DatabaseError databaseError)
                    {
                        if (getActivity () instanceof MainActivity)
                        {
                            MainActivity mainActivity = (MainActivity) getActivity ();
                            mainActivity.showDatabaseError (TAG, Thread.currentThread ()
                                    .getStackTrace (), databaseError);
                        }
                    }
                });

        mFirebaseListenerManager.addListner (databaseReference, valueEventListener);
    }

    protected abstract Activity getActivity ();

    @Override
    public void removeAllListeners ()
    {
        mFirebaseListenerManager.removeAllListners ();
    }
}

BuyTransactionViewHolder, SellTransactionViewHolder, etc. are subclasses of TransactionViewHolder, and, BuyStockTransaction, SellStockTransaction, etc. are subclasses of StockTransaction.

Apart from the constructor no function is even getting called. As I am new to android programming may be I am doing something silly. Can somebody help me understand what I am doing wrong?

Edit

This is how I am initializing adapter:

final DatabaseReference databaseReference = mFirebaseDatabaseReference
            .child (FirebaseDatabaseUtil.CHILD_USER_STOCK_TRANSACTIONS)
            .child (mUserId).child (mStockId);
mStockTransactionFirebaseRecyclerAdapter = new StockTransactionFirebaseRecyclerAdapter (
        databaseReference, mFirebaseDatabaseReference, mUserId)
{
    @Override
    protected Activity getActivity ()
    {
        return StockDisplayFragment.this.getActivity ();
    }
};

I hope I haven't missed out on something, and this clears all doubts. But if it doesn't I would be glad to add more info.


Solution

  • Ok. I implemented my own custom implementation of RecyclerAdapter instead of FirebaseRecyclerAdapter. Only to realise it didn't still work. But the real problem was that RecyclerView was not visible because of a textView above which had its layout_height set to match_parent. So it was my silly mistake all through.