user1908375
user1908375

Reputation: 1089

Different width of layout inside RecyclerView and normal LinearLayout

I have a card view class which looks like:

public class CardTest extends LinearLayout {
    public CardTest(Context context) {
            super(context);
            LayoutInflater.from(getContext()).inflate(R.layout.card_main, this);
        }
}

the card_main.xml is like:

<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_height="wrap_content"
    android:layout_width="fill_parent"
    android:orientation="vertical"
    >
        <android.support.v7.widget.CardView
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            card_view:cardCornerRadius="4dp">

            <TextView
                android:id="@+id/tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Moscow"/>
        </android.support.v7.widget.CardView>
</LinearLayout>

then if I do in my Fragment

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.view_vll_scrollbar, null);

        LinearLayout ll = (LinearLayout) view.findViewById(R.id.vll);
        ll.addView(new CardTest(this.getActivity()));

        return view;
    }

I would see this result(actually, as I expect): enter image description here

but if I now using a RecyclerView with this code

 public class CalendarAdapter extends RecyclerView.Adapter<CalendarViewHolder> {

        private List<ItemCalendar> mList;

        public CalendarAdapter(List<ItemCalendar> list) {
            this.mList = list;
        }

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

        @Override
        public void onBindViewHolder(CalendarViewHolder calendarViewHolder, int i) {
            ItemCalendar ci = mList.get(i);
            calendarViewHolder.headerText.setText(ci.getCity());
        }

        @Override
        public CalendarViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View itemView = new CardTest(viewGroup.getContext());

            return new CalendarViewHolder(itemView);
        }
    }

    public static class CalendarViewHolder extends RecyclerView.ViewHolder {
        protected TextView headerText;
        protected TextView bodyText;


        public CalendarViewHolder(View v) {
            super(v);
            headerText = (TextView) v.findViewById(R.id.card_extender_header_text);
        }
    }

I would have this as result

enter image description here

Why are horzontal sizes of my card view different? Could it be something with context?

Upvotes: 3

Views: 6313

Answers (1)

Drew
Drew

Reputation: 3334

Basically CardTest becomes the layout it was not intended to be. In your adapter you create an instance of CardTest, not supplying layout params to it, and thus the layout structure of CardTest will be different from card_main.xml:

<com.yourpackage.CardTest
    layout_width="wrap_content"
    layout_height="wrap_content">

<!--inflated hierarchy is added into your custom viewgroup-->

<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_height="wrap_content"
    android:layout_width="fill_parent"
    android:orientation="vertical"
    >
        <android.support.v7.widget.CardView
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            card_view:cardCornerRadius="4dp">

            <TextView
                android:id="@+id/tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Moscow"/>
        </android.support.v7.widget.CardView>
</LinearLayout>
</com.yourpackage.CardTest>

and that's not what you meant, isn't it?

Just remove the outer LinearLayout (your view is already a LinearLayout itself) in card_main.xml:

<android.support.v7.widget.CardView
        xmlns:android= "http://schemas.android.com/apk/res/android"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        card_view:cardCornerRadius="4dp">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Moscow"/>
    </android.support.v7.widget.CardView>

Then add to your adapter method:

 @Override
        public CalendarViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
            View itemView = new CardTest(viewGroup.getContext());
            RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(
    ViewGroup.LayoutParams.MATCH_PARENT, //width
    ViewGroup.LayoutParams.WRAP_CONTENT);//height
            itemView.setLayoutParams(lp);//override default layout params
            return new CalendarViewHolder(itemView);
        }

...and send warm greetings to Moscow, taking the whole screen width :)

EDIT: You may also consider not creating your CardTest view hierarchy dynamically, but rather defining it in an XML and inflate it directly in onCreateViewHolder(..).

layout/my_item.xml

<com.yourpackage.CardTest
        xmlns:android= "http://schemas.android.com/apk/res/android"
        layout_width="match_parent"
        layout_height="wrap_content">
<android.support.v7.widget.CardView

        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        card_view:cardCornerRadius="4dp">

        <TextView
            android:id="@+id/tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Moscow"/>
    </android.support.v7.widget.CardView>
</com.yourpackage.CardTest>

And in code:

    @Override
    public CalendarViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.my_item, viewGroup, false);

        return new CalendarViewHolder(itemView);
    }

Upvotes: 5

Related Questions