RecyclerView items don't fill width
Asked Answered
C

4

15

I have designed a layout with map fragment and recyclerView. Each recyclerView item is cardview (I have specified give the xml layout).

The problem is RecyclerView item doesn't fill screen width. img here

I tried to change layout_width to fill_parent, match_parent ... but it can't help

Here is the layout for each item

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    android:id="@+id/cardView">

    <LinearLayout
        android:id="@+id/locationItemView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <ImageView
            android:layout_width="120px"
            android:layout_height="120px"
            android:id="@+id/imgIcon"
            android:background="@drawable/image_bg"
            android:layout_margin="5dp"
            android:scaleType="fitCenter"
            android:adjustViewBounds="true" />

        <LinearLayout
            android:id="@+id/layoutInfo"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/txtName"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Location Name"
                android:textColor="#d5c645"
                android:textStyle="bold"
                android:textSize="20dp"
                android:padding="3dp" />

            <TextView
                android:id="@+id/txtAddress"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Location Address"
                android:textSize="16dp"
                android:padding="3dp" />

            <TextView
                android:id="@+id/txtDistance"
                android:layout_width="match_parent"
                android:layout_height="fill_parent"
                android:text="Location Distance"
                android:textSize="14dp"
                android:textStyle="italic"
                android:padding="2dp"
                android:textAlignment="viewEnd" />
        </LinearLayout>
    </LinearLayout>
</android.support.v7.widget.CardView>

and the main_layout

<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">


<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
        android:layout_height="0px" android:id="@+id/map" tools:context=".Main"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_weight=".6"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/locationList"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight=".4"
        android:divider="#FEFFCC"
        android:dividerHeight="1dp" />

</LinearLayout>

<ListView
    android:id="@+id/navdrawer"
    android:layout_width="250px"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:background="?attr/colorPrimaryDark"
    android:choiceMode="singleChoice"
    android:divider="@android:color/white"
    android:dividerHeight="1dp"
    android:drawSelectorOnTop="false"/>
</android.support.v4.widget.DrawerLayout>

Hope anyone can help me. I am stuck with it for 3 days. Thank you.

==================================== Edit on 19/11/15 I don't thing the problem is my itemView layout because when I change it to GridLayout it still doesn't fill the width. Here is my CustomAdapter for RecyclerView

public class LocationDetailsAdapter extends RecyclerView.Adapter<LocationDetailsViewHolder> {
    Context _context;
    ArrayList<LocationDetails> _data;

    public LocationDetailsAdapter(Context _context, ArrayList<LocationDetails> _object) {
        this._context = _context;
        _data = _object;
    }

    @Override
    public LocationDetailsViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View _v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_location,null );
        LocationDetailsViewHolder _viewHolder = new LocationDetailsViewHolder(_v);

        return _viewHolder;
    }

    @Override
    public void onBindViewHolder(LocationDetailsViewHolder locationDetailsViewHolder, int i) {
        LocationDetails _location = _data.get(i);
        locationDetailsViewHolder._imgType.setImageResource(R.drawable.repair_img);
        locationDetailsViewHolder._locationName.setText(_location.get_locationName());
        locationDetailsViewHolder._locationAddress.setText(_location.get_locationAddress() + ", " + _location.get_district() + ", " + _location.get_province());
        locationDetailsViewHolder._distance.setText(String.valueOf(_location.get_distance()) + " km");

        locationDetailsViewHolder._locationName.setOnClickListener(clickListener);
        locationDetailsViewHolder._imgType.setOnClickListener(clickListener);
        locationDetailsViewHolder._locationAddress.setOnClickListener(clickListener);

locationDetailsViewHolder._locationName.setTag(locationDetailsViewHolder);
        locationDetailsViewHolder._imgType.setTag(locationDetailsViewHolder);
        locationDetailsViewHolder._locationAddress.setTag(locationDetailsViewHolder);
}

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

    View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            LocationDetailsViewHolder _holder = (LocationDetailsViewHolder)v.getTag();
            int _pos = _holder.getPosition();

            int _id = _data.get(_pos).get_id();

            Intent _intent = new Intent(CommonFields._context, ItemView.class);
            _intent.putExtra("LocationID",_id);
            _intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            CommonFields._context.startActivity(_intent);
        }
    };
}

and here I get RecylerView in main

_locationView = (RecyclerView)findViewById(R.id.locationList);
_locationView.setLayoutManager(new LinearLayoutManager(this));
_adapter = new LocationDetailsAdapter(Main.this, CommonFields._locationData);
_locationView.setAdapter(_adapter);
Coneflower answered 18/11, 2015 at 4:42 Comment(7)
Show your Java code. In particular, the spot where you inflate the itemView layout when creating a ViewHolder.Calvert
show a screen shot to how do your item look ?Assort
Check out this : #24504260Flaunt
can you use match_parent instead of fill_parent?Ironwork
@Arslan I can't attach an image in this post so I have a link to it, you can see in the top "img here"Coneflower
@HareshChhelana: tks, but it doesn't helpConeflower
@Droidekas: I tried all but nothing changedConeflower
C
63

When inflating a View from a LayoutInflater, you need to pass a parent parameter in order for layout_* attributes to be used. That's because these attributes need to create the correct LayoutParams class. That means that you can't use inflate(R.layout.*, null), but must instead pass a ViewGroup for the second parameter. In most cases, you also want to use the three-parameter version of the method and pass false as the third parameter. If this is omitted or true then the View is immediately added to the parent, which causes problems in places like onCreateViewHolder() because the framework is designed to perform this operation later instead. For more details, see this answer.

In your case, you have the line

 View _v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_location,null );

You should change it to

 View _v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_location, viewGroup, false );
Calvert answered 19/11, 2015 at 4:57 Comment(3)
Thanks for your help and explaination. It work. It seem to have so many thing I have to learnConeflower
Man you are a life saver! I have been struggling with this small mistake around a week now.Scold
perfect solution and explanation, saved me bunch of time... thanks dude!Polysepalous
I
4

You should create View like this

@Override
public CardViewDataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {  
// create a new view
   View itemLayoutView = LayoutInflater.from(viewGroup.getContext()).inflate(
                R.layout.card_view, viewGroup, false);
// create ViewHolder
   ViewHolder viewHolder = new ViewHolder(itemLayoutView);
   return viewHolder;
 }
Irrelievable answered 18/11, 2015 at 4:53 Comment(1)
I just create custom adapter for RecyclerView, not for CardView. I just edit my postConeflower
P
0

Maybe my answer has a different approach, but it works to occupy the entire width of the screen and not break the elements when passing through the recycling view.

Adapter adapterBalanceInquiry = new Adapter(getActivity(), list);
        recyclerView.setHasFixedSize(true);
        recyclerView.setNestedScrollingEnabled(false);
        recyclerView.setAdapter(adapterBalanceInquiry);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), RecyclerView.HORIZONTAL, false));
        recyclerView.post(new Runnable() {
            @Override
            public void run() {
                try {
                    int dx = (recyclerView.getWidth() - recyclerView.getChildAt(0).getWidth());
                    recyclerView.scrollBy(-dx, 0);
                    LinearSnapHelper snapHelper = new LinearSnapHelper();
                    recyclerView.setOnFlingListener(null);
                    snapHelper.attachToRecyclerView(recyclerView);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });

enter image description here

Piefer answered 24/9, 2019 at 21:43 Comment(0)
H
0

Improved answer @RussHWolf If you are using data binding in Adapter than

val binding = ViewBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )

return MyViewHolder(binding)

finally

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int):
        MyViewHolder{
        val binding = ViewBinding.inflate(
            LayoutInflater.from(parent.context),
            parent,
            false
        )
        return MyViewHolder(binding)
    }
Huntley answered 9/11, 2023 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.