7

Any idea why RecyclerView items get deformed , each consecutive item gets worse?

UPDATE: I'm using CardViews and now there's no view "deformation" but the shadow/elevation height changes.

It seems that elevation gets higher depending on where on the screen the item is located vertically, the shadow grows as the item gets scrolled down. Please see the video here: https://youtu.be/nROYq8rpUMs.

I've set up a new project leaving only the code necessary to demonstrate the issue:

MainActivity.java

package tzig.schm00.masterdetail;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


import tzig.schm00.masterdetail.dummy.DummyContent;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View recyclerView = findViewById(R.id.item_list);
        setupRecyclerView((RecyclerView) recyclerView);

    }

    private void setupRecyclerView(@NonNull RecyclerView recyclerView) {
        recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(DummyContent.ITEMS));
    }

    public class SimpleItemRecyclerViewAdapter
            extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {

        private final List<DummyContent.DummyItem> mValues;

        public SimpleItemRecyclerViewAdapter(List<DummyContent.DummyItem> items) {
            mValues = items;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.list_item, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final ViewHolder holder, int position) {
            holder.mItem = mValues.get(position);
            holder.mIdView.setText(mValues.get(position).id);
            holder.mContentView.setText(mValues.get(position).content);
        }

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

        public class ViewHolder extends RecyclerView.ViewHolder {
            public final View mView;
            public final TextView mIdView;
            public final TextView mContentView;
            public DummyContent.DummyItem mItem;

            public ViewHolder(View view) {
                super(view);
                mView = view;
                mIdView = (TextView) view.findViewById(R.id.id);
                mContentView = (TextView) view.findViewById(R.id.content);
            }

            @Override
            public String toString() {
                return super.toString() + " '" + mContentView.getText() + "'";
            }
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    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:id="@+id/frameLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/item_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        app:layoutManager="LinearLayoutManager"
        tools:context="tzig.schm00.myapplication.MainActivity" />

</FrameLayout>

list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/cont_item_root"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="8dp"
    card_view:cardElevation="10dp"
    card_view:cardMaxElevation="10dp"
    card_view:cardUseCompatPadding="true">

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

        <TextView
            android:id="@+id/id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/text_margin"
            android:textAppearance="?attr/textAppearanceListItem" />

        <TextView
            android:id="@+id/content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/text_margin"
            android:textAppearance="?attr/textAppearanceListItem" />
    </LinearLayout>

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

New observation: seems like it's a standard behavior. Looks the same with the Image Picker displaying folders using CardViews...

Any help is greatly appreciated!

Thanks!!

stas
  • 71
  • 1
  • 3

3 Answers3

1

This is how it's intended to be according to Material Design: Environment: Light and shadows: Light.

Also see answer https://stackoverflow.com/a/51216164/6685260

0

Add a background to your RelativeLayout - seems that elevation needs it to work properly. I have tested this with your layout and it does work.

Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • Hi, thank you for your help. I've tried setting background for the RelativeLayout as well as for the CardView. Unfortunately it didn't sol e the problem. What I've noticed tbough is that elevation gets higher not with each next list item but depends on its location vertically. Pleaze check this video: https://youtu.be/nROYq8rpUMs – stas Mar 07 '17 at 07:24
  • Not sure about `CardView`. The answer I provided did demonstrably take care of the trapezoid problem you were having before `CardView` was introduced. – Cheticamp Mar 07 '17 at 15:04
0

I had the same issue, and in my case the problem was caused by a background drawable which I set in my RecyclerViewAdapter#onBindViewHolder:

// this spoiled the shadows!
cardView.setBackgroundDrawable(ContextCompat.getDrawable(context, myColorResourceId);

After I removed the line above the problem has disappeared!

(To have both a background and nice shadows I used an inner element filling the CardView and applied background to it instead of CardView)

Mikhail
  • 844
  • 8
  • 18