Search code examples
androidandroid-recyclerviewnestedrecyclerview

recyclerview items size not the same size in layout


I'm trying to make a nested recyclerview with multiple items and after finishing the adatper and design and going in testing I got this in the emulator

enter image description here enter image description here

I didn't understand why items appears like that, the items not the same height and width which I make it for the design of it's layout.

here is the code for recyclerview setup

    mRecyclerView.setHasFixedSize(true);
    adapter = new CheckoutMainRecyAdapter(CheckOutActivity.this, allSampleData);
    mRecyclerView.setLayoutManager(new LinearLayoutManager(CheckOutActivity.this));
    mRecyclerView.setAdapter(adapter);

and here is the adapter code

public class CheckoutMainRecyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    private ArrayList<CheckoutMainModel> dataList;
    private Context mContext;

public CheckoutMainRecyAdapter(Context context, ArrayList<CheckoutMainModel> dataList) {
    this.dataList = dataList;
    this.mContext = context;

}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
    View view;
    switch (i) {
        case Constants.type_checkout_address:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.checkout_address_item, null);
            CheckoutMainRecyAdapter.AddressItemHolder mho = new CheckoutMainRecyAdapter.AddressItemHolder(view);
            return mho;
        case Constants.type_checkout_policy:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.checkout_policy_item, null);
            CheckoutMainRecyAdapter.TermsItemHolder pro = new CheckoutMainRecyAdapter.TermsItemHolder(view);
            return pro;
        case Constants.type_checkout_payment:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.checkout_payment_item, null);
            CheckoutMainRecyAdapter.PaymentItemHolder proO = new CheckoutMainRecyAdapter.PaymentItemHolder(view);
            return proO;
        case Constants.type_checkout_button:
            view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.checkout_button_item, null);
            CheckoutMainRecyAdapter.ButtonItemHolder proOO = new CheckoutMainRecyAdapter.ButtonItemHolder(view);
            return proOO;

    }

    return null;
}

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder itemRowHolder, final int i) {

    CheckoutMainModel newCheckoutItemsModel = dataList.get(i);
    Log.d("itemType", String.valueOf(newCheckoutItemsModel.getType()));
    Log.d("lastitem", ":ii:" + String.valueOf(i));

    Activity activity = (Activity) mContext;
    switch (newCheckoutItemsModel.getType()) {

        case Constants.type_checkout_button:
            ((ButtonItemHolder) itemRowHolder).confirmBtn.setText("confirm btn");
            ((ButtonItemHolder) itemRowHolder).confirmBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent3 = new Intent(mContext, CategoryActivity.class);
                    intent3.putExtra("from", "Home");
                    mContext.startActivity(intent3);
                }
            });

            break;

        case Constants.type_checkout_address:

            ((AddressItemHolder) itemRowHolder).addressTitle.setText("adress title");
            ((AddressItemHolder) itemRowHolder).addressDetails.setText("addressDetails");


            if (dataList.get(i).getAddressModels().size()<=1){
                ((AddressItemHolder) itemRowHolder).changeBtn.setVisibility(View.GONE);
            }

            ((AddressItemHolder) itemRowHolder).addBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });

            ((AddressItemHolder) itemRowHolder).changeBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                }
            });


            break;
        case Constants.type_checkout_payment:

            Log.d("lastitem", ":iin:" + String.valueOf(i));

            final String sectionName = dataList.get(i).getTitle();
            ((PaymentItemHolder) itemRowHolder).paymentTitle.setText(sectionName);
            ((PaymentItemHolder) itemRowHolder).cashCL.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent3 = new Intent(mContext, CategoryActivity.class);
                    intent3.putExtra("from", "Home");
                    mContext.startActivity(intent3);
                    //Toast.makeText(v.getContext(), sectionName, Toast.LENGTH_SHORT).show();
                }
            });

            ((PaymentItemHolder) itemRowHolder).onlinePaymentCl.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent3 = new Intent(mContext, CategoryActivity.class);
                    intent3.putExtra("from", "Home");
                    mContext.startActivity(intent3);
                }
            });
            break;


        case Constants.type_checkout_policy:

            final String policySectionName = dataList.get(i).getTitle();
            final String policySectionDetails = dataList.get(i).getApp_policy();

            ((TermsItemHolder) itemRowHolder).termsTitle.setText(policySectionName);
            ((TermsItemHolder) itemRowHolder).termsDetails.setText(policySectionDetails);

            ((TermsItemHolder) itemRowHolder).accept_policy.setOnCheckedChangeListener
                    (new CompoundButton.OnCheckedChangeListener() {
                         @Override
                         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                         }
                     }
                    );
            break;

    }


}

@Override
public int getItemViewType(int position) {
    CheckoutMainModel newCheckoutItemsModel = dataList.get(position);
    if (newCheckoutItemsModel != null) {
        return newCheckoutItemsModel.getType();
    }
    // return super.getItemViewType(position);
    return 0;
}

@Override
public int getItemCount() {
    return (null != dataList ? dataList.size() : 0);
}

@Override
public long getItemId(int position) {
    return position;
}

public class AddressItemHolder extends RecyclerView.ViewHolder {

    protected TextView addressTitle;
    protected TextView addressDetails;
    protected RecyclerView recycler_view_list;
    protected Button changeBtn;
    protected Button addBtn;

    public AddressItemHolder(View view) {
        super(view);

        this.addressTitle = (TextView) view.findViewById(R.id.addressTitleCheckout);
        this.recycler_view_list = (RecyclerView) view.findViewById(R.id.address_rv_checkout);
        this.addressDetails = (TextView) view.findViewById(R.id.address_details);
        this.addBtn = view.findViewById(R.id.add_address_btn);
        this.changeBtn = view.findViewById(R.id.change_address_btn);


    }
}

public class TermsItemHolder extends RecyclerView.ViewHolder {

    protected TextView termsTitle;
    protected TextView termsDetails;
    protected CheckBox accept_policy;

    public TermsItemHolder(View view) {
        super(view);

        this.termsTitle = (TextView) view.findViewById(R.id.policy_title);
        this.termsDetails = (TextView) view.findViewById(R.id.policy_messge);
        this.accept_policy = view.findViewById(R.id.checkBox_policy);


    }
}

public class ButtonItemHolder extends RecyclerView.ViewHolder {

    protected Button confirmBtn;

    public ButtonItemHolder(View view) {
        super(view);
        this.confirmBtn = view.findViewById(R.id.checkout_item_btn);


    }
}

public class PaymentItemHolder extends RecyclerView.ViewHolder {

    protected TextView paymentTitle;
    protected TextView cashText;
    protected TextView creditText;
    protected ConstraintLayout cashCL;
    protected ConstraintLayout onlinePaymentCl;

    public PaymentItemHolder(View view) {
        super(view);

        this.paymentTitle = (TextView) view.findViewById(R.id.payment_method_title);
        this.cashText = (TextView) view.findViewById(R.id.cash_tv);
        this.creditText = (TextView) view.findViewById(R.id.onlinePayment_tv);
        this.cashCL = view.findViewById(R.id.cash_cl);
        this.onlinePaymentCl = view.findViewById(R.id.credit_cl);


    }
    }   
}

and here the layouts of recyclerview items

first item

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="-10dp"
app:cardCornerRadius="4dp"
app:cardElevation="0.7dp"
app:cardMaxElevation="1dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
app:contentPaddingBottom="0dp">

<android.support.constraint.ConstraintLayout
    android:background="@color/colorGray"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <TextView
        android:id="@+id/payment_method_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="@string/deliver_to"
        android:textColor="@color/colorButtonRed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/addressTitleCheckout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="المنزل"
        app:layout_constraintEnd_toStartOf="@+id/add_address_btn"
        app:layout_constraintStart_toEndOf="@+id/payment_method_title"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/address_details"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="شارع طلعت حرب"
        app:layout_constraintEnd_toStartOf="@+id/add_address_btn"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/addressTitleCheckout" />

    <Button
        android:id="@+id/change_address_btn"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/dots_border_bg"
        android:text="@string/change_button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/add_address_btn" />

    <Button
        android:id="@+id/add_address_btn"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:background="@drawable/dots_border_bg"
        android:text="@string/add_address_button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/address_rv_checkout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/change_address_btn" />


</android.support.constraint.ConstraintLayout>

second item

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="-10dp"
app:cardCornerRadius="4dp"
app:cardElevation="0.7dp"
app:cardMaxElevation="1dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
app:contentPaddingBottom="0dp">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:background="@color/colorGray"
    android:layout_height="match_parent">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <TextView
        android:id="@+id/payment_method_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="@string/payment_method"
        android:textColor="@color/colorButtonRed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <android.support.constraint.ConstraintLayout
        android:id="@+id/cash_cl"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="@+id/guideline"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/payment_method_title">

        <TextView
            android:id="@+id/cash_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:text="@string/cash_payment"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/cash_tv"
            app:layout_constraintTop_toTopOf="parent"
            card_view:srcCompat="@drawable/iv_cash" />
    </android.support.constraint.ConstraintLayout>

    <android.support.constraint.ConstraintLayout
        android:id="@+id/credit_cl"
        android:layout_width="0dp"
        android:layout_height="40dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@+id/guideline"
        app:layout_constraintTop_toBottomOf="@+id/payment_method_title">

        <TextView
            android:id="@+id/onlinePayment_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginBottom="8dp"
            android:text="@string/online_payment"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_marginStart="8dp"
            android:layout_marginTop="8dp"
            android:layout_marginEnd="8dp"
            android:layout_marginBottom="8dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toEndOf="@+id/onlinePayment_tv"
            app:layout_constraintTop_toTopOf="parent"
            card_view:srcCompat="@drawable/iv_online_payment" />

    </android.support.constraint.ConstraintLayout>


</android.support.constraint.ConstraintLayout>

third item

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="-10dp"
app:cardCornerRadius="4dp"
app:cardElevation="0.7dp"
app:cardMaxElevation="1dp"
app:cardPreventCornerOverlap="true"
app:cardUseCompatPadding="true"
app:contentPaddingBottom="0dp">

<android.support.constraint.ConstraintLayout
    android:layout_width="match_parent"
    android:background="@color/colorGray"
    android:layout_height="match_parent">

    <android.support.constraint.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintGuide_percent="0.5" />

    <TextView
        android:id="@+id/policy_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:text="@string/terms"
        android:textColor="@color/colorButtonRed"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/policy_messge"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="@string/delivery_fee_cost_terms"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/policy_title" />

    <CheckBox
        android:id="@+id/checkBox_policy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:checked="true"
        android:text="@string/yes"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/policy_messge" />


</android.support.constraint.ConstraintLayout>

and here is the activity layout which recyclerview in

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/checkout_rv"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/checkout_btn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@drawable/btn_bg_no_radius"
        android:text="@string/cart_details_submit"
        android:textColor="@color/white"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />
</android.support.constraint.ConstraintLayout>

Solution

    1. You have to supply the recycler as the root to the inflate method, so that the inflated view gets the correct layout parameters from the parent
    2. You have to set attachToRoot to false, because the recycler view handles the attaching.

    Example:

    view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.your_layout, viewGroup, false);