user3623979
user3623979

Reputation:

how to Inflate multiple card view layout

I have a list view. Displayed as a card view. In card view I have an image which I want to change dynamically based on object TYPE. So for that I have created two different layouts which contain small and big image. I have created an adapter and tried to inflate two different layouts in onCreateViewHolder.I am getting a Null pointer exception on these lines of code. No idea what I am missing...Please Help..

itemViewHolder.big.setImageDrawable(drawable1);
  itemViewHolder.small.setImageDrawable(drawable);
public class IAdapter extends RecyclerView.Adapter<IAdapter.ItemViewHolder> {

Adapter code

    public class ItemAdapter extends RecyclerView.Adapter<IAdapter.ItemViewHolder> {

    List<Expense> items;
    public static final int TYPE1 = 1;
    public static final int TYPE2 = 2;

    IAdapter(List<Expense> items) {

        this.items = items;

    }

    @Override
    public int getItemCount() {
        return items.size();

    }

    @Override
    public int getItemViewType(int position) {

        Expense e = new Expense();
        if (TYPE1 == 1) {
            int type = e.getExpenseType();
            return type;
        } else {
            return TYPE2;
        }

    }

    @Override
    public void onBindViewHolder(ItemViewHolder itemViewHolder, int i) {

        itemViewHolder.amount.setText(items.get(i).amount);
        itemViewHolder.expense.setText(items.get(i).expense);
        TextDrawable drawable = TextDrawable.builder()
                .beginConfig()
                .withBorder(4)
                .textColor(Color.BLACK)
                .useFont(Typeface.DEFAULT)
                .fontSize(25)
                .bold()
                .toUpperCase()
                .endConfig()
                .buildRound("11:00", Color.GRAY);
        itemViewHolder.small.setImageDrawable(drawable);

        TextDrawable drawable1 = TextDrawable.builder()
                .beginConfig()
                .withBorder(4)
                .textColor(Color.BLACK)
                .useFont(Typeface.DEFAULT)
                .fontSize(25)
                .bold()
                .toUpperCase()
                .endConfig()
                .buildRound("10 Jan", Color.CYAN);
        itemViewHolder.big.setImageDrawable(drawable1);

    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        if (viewType == TYPE1) {
            View itemView = LayoutInflater.
                    from(viewGroup.getContext()).
                    inflate(R.layout.cardlayout, viewGroup, false);
            return new ItemViewHolder(itemView, viewType);
        } else {
            View itemView = LayoutInflater.
                    from(viewGroup.getContext()).
                    inflate(R.layout.bigcircle, viewGroup, false);
            ItemViewHolder ivh = new ItemViewHolder(itemView, viewType);
            return ivh;
        }
    }

    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView amount;
        TextView expense;
        ImageView small;
        ImageView big;

        ItemViewHolder(View itemView, int viewType) {
            super(itemView);
            amount = (TextView) itemView.findViewById(R.id.txtAmount);
            expense = (TextView) itemView.findViewById(R.id.txtexpense);
            cv = (CardView) itemView.findViewById(R.id.card_view);
            small = (ImageView) itemView.findViewById(R.id.small);
            big=(ImageView)itemView.findViewById(R.id.big);
            //   cv1 = (CardView) itemView.findViewById(R.id.card_view);

            //TextDrawable drawable1 = TextDrawable.builder()
            // .buildRound("20 Jan", Color.RED);

        }
    }


    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

}

cardlayout code

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1"
android:orientation="vertical"
android:measureWithLargestChild="false"
android:background="@android:color/white">
<!-- A CardView that contains a TextView -->

<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    card_view:cardCornerRadius="4dp"
    android:background="@android:color/white">


    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/relativeLayout"
        android:background="@android:color/white"
        android:layout_alignParentTop="true">


        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+id/txtAmount"
            android:text="text1"
            android:layout_centerVertical="true"
            android:layout_toLeftOf="@+id/linearLayout"
            android:layout_toStartOf="@+id/linearLayout"
            android:layout_marginRight="24dp"
            android:layout_marginEnd="24dp" />

        <LinearLayout
            android:orientation="vertical"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:weightSum="1"
            android:id="@+id/linearLayout"
            android:gravity="center_vertical"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true">


            <ImageView
                android:layout_width="40dp"
                android:layout_height="25dp"
                android:id="@+id/imageView2"
                android:background="@drawable/line" />

            <ImageView

                android:id="@+id/small"
                android:focusableInTouchMode="false"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:background="@drawable/circle"/>


            <ImageView
                android:layout_width="40dp"
                android:layout_height="25dp"
                android:id="@+id/imageView3"
                android:background="@drawable/line" />
        </LinearLayout>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="Medium Text"
            android:id="@+id/txtexpense"
            android:layout_centerVertical="true"
            android:layout_toRightOf="@+id/linearLayout"
            android:layout_toEndOf="@+id/linearLayout"
            android:layout_marginLeft="24dp"
            android:layout_marginStart="24dp" />
    </RelativeLayout>

</android.support.v7.widget.CardView>

bigcircle card layout code

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:weightSum="1"
    android:orientation="vertical"
    android:measureWithLargestChild="false">
    <!-- A CardView that contains a TextView -->

    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view1"
        android:layout_width="match_parent"
        android:layout_height="80dp"
        card_view:cardCornerRadius="4dp"
        android:background="@android:color/white">


        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/relativeLayout"
            android:background="@android:color/white"
            android:layout_alignParentTop="true">


            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:id="@+id/txtAmount"
                android:text="text1"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@+id/linearLayout"
                android:layout_toStartOf="@+id/linearLayout"
                android:layout_marginRight="24dp"
                android:layout_marginEnd="24dp" />

            <LinearLayout
                android:orientation="vertical"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:weightSum="1"
                android:id="@+id/linearLayout"
                android:gravity="center_vertical"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true">


                <ImageView
                    android:layout_width="50dp"
                    android:layout_height="25dp"
                    android:id="@+id/imageView2"
                    android:background="@drawable/line" />

                <ImageView

                    android:id="@+id/big"
                    android:focusableInTouchMode="false"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:background="@drawable/circle1"/>


                <ImageView
                    android:layout_width="50dp"
                    android:layout_height="25dp"
                    android:id="@+id/imageView3"
                    android:background="@drawable/line" />
            </LinearLayout>

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:text="Medium Text"
                android:id="@+id/txtexpense"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@+id/linearLayout"
                android:layout_toEndOf="@+id/linearLayout"
                android:layout_marginLeft="24dp"
                android:layout_marginStart="24dp" />
        </RelativeLayout>

    </android.support.v7.widget.CardView>
</LinearLayout>

What am I missing???

Upvotes: 2

Views: 3589

Answers (3)

user3623979
user3623979

Reputation:

public class IAdapter extends RecyclerView.Adapter<IAdapter.ItemViewHolder> {

    List<Expense> items;
    public static final int TYPE1=1;



    IAdapter(List<Expense> items) {

        this.items = items;

    }

    @Override
    public int getItemCount() {
        return items.size();

    }

    @Override
        public int getItemViewType(int position) {
            return items.get(position).getExpenseType();// Assume that this return 1 0r 2
        }

    @Override
    public void onBindViewHolder(ItemViewHolder itemViewHolder, int i) {

        itemViewHolder.amount.setText(items.get(i).amount);
        itemViewHolder.expense.setText(items.get(i).expense);
    }

    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup,int viewType) {

        if (viewType==TYPE1) {
            View itemView = LayoutInflater.
                    from(viewGroup.getContext()).
                    inflate(R.layout.cardlayout, viewGroup, false);
            return new ItemViewHolder(itemView,viewType);
        } else {
            View itemView = LayoutInflater.from(viewGroup.getContext()).
                    inflate(R.layout.bigcircle, viewGroup, false);
            ItemViewHolder ivh = new ItemViewHolder(itemView, viewType);
            return ivh;
        }
    }


    public static class ItemViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView amount;
        TextView expense;
        ImageView small;
        ImageView big;

        ItemViewHolder(View itemView, int viewType) {
            super(itemView);
            amount = (TextView) itemView.findViewById(R.id.txtAmount);
            expense = (TextView) itemView.findViewById(R.id.txtexpense);
            cv = (CardView) itemView.findViewById(R.id.card_view);

            if(viewType==TYPE1) {
                small = (ImageView) itemView.findViewById(R.id.small);
                TextDrawable drawable = TextDrawable.builder()
                        .beginConfig()
                        .withBorder(4)
                        .textColor(Color.BLACK)
                        .useFont(Typeface.DEFAULT)
                        .fontSize(25)
                        .bold()
                        .toUpperCase()
                        .endConfig()
                        .buildRound("11:00", Color.GRAY);
                small.setImageDrawable(drawable);
            }else{
                big=(ImageView)itemView.findViewById(R.id.big);
                TextDrawable drawable = TextDrawable.builder()
                        .beginConfig()
                        .withBorder(4)
                        .textColor(Color.BLACK)
                        .useFont(Typeface.DEFAULT)
                        .fontSize(25)
                        .bold()
                        .toUpperCase()
                        .endConfig()
                        .buildRound("10Jan", Color.CYAN);
                big.setImageDrawable(drawable);
            }

            //   cv1 = (CardView) itemView.findViewById(R.id.card_view);

            //TextDrawable drawable1 = TextDrawable.builder()
            // .buildRound("20 Jan", Color.RED);

        }
    }


    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

}

this is giving the desired result..

Upvotes: 0

diyoda_
diyoda_

Reputation: 5420

It is because you are using the ItemViewHolder that is passed from the onCreateViewHoldermethod inside the onBindViewHoldermethod. The reason it fails is that, You have 2 different inflated views passed one containing view element with id big and the other with id small. So, either itemViewHolder.big or itemViewHolder.small becomes null. That throws an NullPointerException

I think the way you approached this is correct.

Option One: This is a different way of achieving this.

if you have completely different layouts for these two, you have to do it this way. But if the layout of the cards are the same only those big and small images are changing, I suggest you to keep a single layout and change the image view grammatically.

Option Two

Your approach. I suggest you to stick to it because that is the elegant way of doing this. But you will have to do some minor tweaks.

    @Override
    public int getItemViewType(int position) {
          return items.get(position).getExpenseType();// Assume that this return 1 0r 2
    }

I suggest you to check the type before you set the value here, Assuming that you have a TYPE class variable to keep the Type for each item.

@Override
    public void onBindViewHolder(ItemViewHolder itemViewHolder, int i) {

       itemViewHolder.amount.setText(items.get(i).amount);
       itemViewHolder.expense.setText(items.get(i).expense);

       if(getItemViewType(i) == 1){
        TextDrawable drawable = TextDrawable.builder()
                .beginConfig()
                .withBorder(4)
                .textColor(Color.BLACK)
                .useFont(Typeface.DEFAULT)
                .fontSize(25)
                .bold()
                .toUpperCase()
                .endConfig()
                .buildRound("11:00", Color.GRAY);
        itemViewHolder.small.setImageDrawable(drawable);
       }else{
        TextDrawable drawable1 = TextDrawable.builder()
                .beginConfig()
                .withBorder(4)
                .textColor(Color.BLACK)
                .useFont(Typeface.DEFAULT)
                .fontSize(25)
                .bold()
                .toUpperCase()
                .endConfig()
                .buildRound("10 Jan", Color.CYAN);
        itemViewHolder.big.setImageDrawable(drawable1);
      }
    }

This has not changed my answer. But this will give you a good idea. The cavity thing that you are missing is in this,

public static class ItemViewHolder extends RecyclerView.ViewHolder {
        CardView cv;
        TextView amount;
        TextView expense;
        ImageView small;
        ImageView big;

        ItemViewHolder(View itemView, int viewType) {
            super(itemView);
            amount = (TextView) itemView.findViewById(R.id.txtAmount);
            expense = (TextView) itemView.findViewById(R.id.txtexpense);
            cv = (CardView) itemView.findViewById(R.id.card_view);
            small = (ImageView) itemView.findViewById(R.id.small);
            big=(ImageView)itemView.findViewById(R.id.big);
            //   cv1 = (CardView) itemView.findViewById(R.id.card_view);

            //TextDrawable drawable1 = TextDrawable.builder()
            // .buildRound("20 Jan", Color.RED);

        }
    }

even though you do

small = (ImageView) itemView.findViewById(R.id.small);
big=(ImageView)itemView.findViewById(R.id.big);

either small or big variable will get assigned null. But you have to check that before calling a method on it. Otherwise it will give a NullPointerException

Edit:

Or you can do,

@Override
public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup,int viewType) {

    View itemView;
    if (getItemViewType(i)==1) {
        itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.cardlayout, viewGroup, false);

    } else {
        itemView = LayoutInflater.from(viewGroup.getContext()).
                inflate(R.layout.bigcircle, viewGroup, false);
    }

    return new ItemViewHolder(itemView,viewType);
}

Upvotes: 1

user3623979
user3623979

Reputation:

@Override public ItemViewHolder onCreateViewHolder(ViewGroup viewGroup,int viewType) {

    if (getItemViewType(i)==1) {
        View itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.cardlayout, viewGroup, false);
        return new ItemViewHolder(itemView,viewType);
    } else {
        View itemView = LayoutInflater.from(viewGroup.getContext()).
                inflate(R.layout.bigcircle, viewGroup, false);
        ItemViewHolder ivh = new ItemViewHolder(itemView, viewType);
        return ivh;
    }
}

is this right??

Upvotes: 0

Related Questions