Проблемы, связанные с воссозданием списков материального дизайна с оставлением в Android

Я хотел бы воссоздать список материалов : элементы управления на Android в скользящей панели.

Список материалов с маской раскладки справа от Руководства по дизайну материалов

Я использую:

Я закончил использование частей библиотек поддержки, но это конкретное приложение 5.0+ только, так что в моем коде могут быть только вещи Lollipop.

Вот макет элемента списка в моем RecyclerView:

<com.daimajia.swipe.SwipeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="right">
    <RelativeLayout
        android:layout_width="42dp"
        android:layout_height="match_parent"
        android:background="?android:selectableItemBackground"
        android:clickable="true"
        android:focusable="true">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerVertical="true"
            android:layout_centerHorizontal="true"
            android:src="@drawable/ic_delete_black_24dp"/>

    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/ripple_floating"
        android:clickable="true"
        android:focusable="true"
        android:minHeight="48dp"
        android:paddingEnd="16dp"
        android:paddingStart="16dp"
        android:elevation="2dp">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_centerVertical="true"
            android:ellipsize="end"
            android:singleLine="true"
            android:text="..."/>

    </RelativeLayout>
</com.daimajia.swipe.SwipeLayout>

И это текущий результат.

Пример приложения без разделителей и один элемент списка

Остальные проблемы для решения - это тени и разделители высоты.

Как вы можете видеть на изображении, есть несколько разумных теней по сторонам элементов списка. Однако на нижней части предметов нет теней высоты, поэтому, когда объект обнаружен, тень не отображается над открытой областью.

Вторая проблема - разделители. У меня есть список с одним элементом, без значков/изображений, поэтому для правильной разработки нужно использовать разделители для элементов.

Однако я не могу использовать DividerItemDecoration из serso/android-linear-layout-manager, потому что он не интегрирован в слайдер, и это происходит, когда 2 смежных элемента сдвинуты. Пример приложения с разделителями и двумя показанными элементами списка

Кто-нибудь знает какие-либо доступные, атрибут или библиотеку, которые я должен использовать, чтобы стилизовать эти элементы списка как материальные листы с тенями и границами высоты?

Ответ 1

Тени/Высота

Для того, чтобы тени или возвышения выглядели так, вы можете использовать вид карты с общим трюком, чтобы сделать их чуть шире ширины экрана ( "карты полной ширины" ).

Например:

<android.support.v7.widget.CardView
    android:layout_width="match_parent"
    android:layout_height="72dp"
    android:layout_marginLeft="@dimen/card_margin_horizontal"
    android:layout_marginRight="@dimen/card_margin_horizontal"
    app:cardCornerRadius="0dp"
    app:cardElevation="4dp">

В значениях /dimens.xml:

<dimen name="card_margin_horizontal">-3dp</dimen>

В значениях-v21/dimens.xml

<dimen name="card_margin_horizontal">0dp</dimen>

Разделитель

И с этим вам может не понадобиться менять разделитель, это может выглядеть нормально. В противном случае попробуйте добавить разделитель к самому виду (вид сверху или контролировать его видимость самостоятельно). Это может быть только вид с высотой 1dp и шириной match_parent и backgroundColor, установленный на некоторый темно-серый (или разделяемый системный разделитель (R.attr.listDivider).

Ответ 2

Для разделительной части вашего вопроса я бы рекомендовал изучить ItemDecorators. Вы можете добавить ItemDecorator в свой LayoutManager и получить разделители. Примером одного является здесь (и есть несколько там, если вы его рекламируете)

Ответ 3

Создайте класс с именем DividerItemDecoration.java и вставьте следующий код

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;


public class DividerItemDecoration extends RecyclerView.ItemDecoration {

private static final int[] ATTRS = new int[]{
        android.R.attr.listDivider
};

public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

private Drawable mDivider;

private int mOrientation;

public DividerItemDecoration(Context context, int orientation) {
    final TypedArray a = context.obtainStyledAttributes(ATTRS);
    mDivider = a.getDrawable(0);
    a.recycle();
    setOrientation(orientation);
}

public void setOrientation(int orientation) {
    if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
        throw new IllegalArgumentException("invalid orientation");
    }
    mOrientation = orientation;
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    if (mOrientation == VERTICAL_LIST) {
        drawVertical(c, parent);
    } else {
        drawHorizontal(c, parent);
    }
}

public void drawVertical(Canvas c, RecyclerView parent) {
    final int left = parent.getPaddingLeft();
    final int right = parent.getWidth() - parent.getPaddingRight();

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int top = child.getBottom() + params.bottomMargin;
        final int bottom = top + mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

public void drawHorizontal(Canvas c, RecyclerView parent) {
    final int top = parent.getPaddingTop();
    final int bottom = parent.getHeight() - parent.getPaddingBottom();

    final int childCount = parent.getChildCount();
    for (int i = 0; i < childCount; i++) {
        final View child = parent.getChildAt(i);
        final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                .getLayoutParams();
        final int left = child.getRight() + params.rightMargin;
        final int right = left + mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    if (mOrientation == VERTICAL_LIST) {
        outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
    } else {
        outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
    }
}
}

и используйте addItemDecoration(). вы можете найти полный учебник на этой странице:

http://www.androidhive.info/2016/01/android-working-with-recycler-view/

Ответ 4

Добавить android:clipChildren = "false" в SwipeLayout и RecyclerView.
Вот макет элемента списка в моем RecyclerView:

<com.daimajia.swipe.SwipeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/swipe_layout"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:layout_marginBottom="1px"
    android:clipChildren="false"
    app:show_mode="lay_down">

    <ImageView
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:scaleType="center"
        android:src="@drawable/ic_settings_black_24dp"/>

    <FrameLayout
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:elevation="2dp">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="@string/app_name"/>
    </FrameLayout>
</com.daimajia.swipe.SwipeLayout>

Вот макет моего RecyclerView:

<android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorBackground"
        android:clipChildren="false"
        android:scrollbarStyle="outsideOverlay"
        android:scrollbars="vertical"/>

И это текущий результат.

введите описание изображения здесь