Можно ли использовать Layout вместо Drawable для DividerItemDecoration? - PullRequest
1 голос
/ 28 марта 2019

Я хочу использовать пользовательский разделитель между горизонтально прокручиваемыми элементами в RecyclerView.Я могу использовать значок как Drawable, но этот значок заполнил все пространство как разделитель и оказался растянутым.Я сделал пользовательский RelativeLayout, где я центрировал этот разделитель как ImageView и добавил к нему пользовательский отступ.Я не хочу добавлять этот разделитель (стрелка) к вертикальному центру Layout, но немного ниже центра.Это пользовательский значок с пользовательским заполнением.

При этом я хочу каким-то образом добавить этот разделитель в DividerItemDecoration, но он принимает только Drawable.

ОБНОВЛЕНИЕ:

Я попытался раздуть этот пользовательский макет и преобразовать его в Drawable.Проблема в том, что раздутая компоновка имеет ширину и высоту 0.

val view = LayoutInflater.from(app).inflate(R.layout.separator, null)
val bitmapDecoration = view?.let { viewToBitmap(it, it.width, it.height) }
val drawableDecoration = BitmapDrawable(app.resources, bitmapDecoration)
itemDecoration.setDrawable(drawableDecoration)

Пример моего разделителя:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="40dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:paddingTop="4dp"
        android:src="@drawable/arrow_black_short"/>

</RelativeLayout>

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

enter image description here

Если я использую только значок делителя в качестве Drawable и добавляю его к DividerItemDecoration, он выглядит так (растягивается для заполнения до родительского элемента):

enter image description here

Ответы [ 2 ]

1 голос
/ 29 марта 2019

Обновлен:

  1. Создайте следующий класс:

    public class HorizontalDrawableDecoration extends RecyclerView.ItemDecoration {
        private final int paddingTopPx, paddingBottomPx, paddingLeftPx, paddingRightPx;
        private final Drawable drawable;
        private Rect bounds;
    
        public HorizontalDrawableDecoration(Context context,
                                        @DrawableRes int drawableId,
                                        @DimenRes int paddingTop, @DimenRes int paddingBottom,
                                        @DimenRes int paddingLeft, @DimenRes int paddingRight ) {
            this.paddingTopPx = getDimenPx(context, paddingTop);
            this.paddingBottomPx = getDimenPx(context, paddingBottom);
            this.paddingLeftPx = getDimenPx(context, paddingLeft);
            this.paddingRightPx = getDimenPx(context, paddingRight);
            this.drawable = ContextCompat.getDrawable(context, drawableId);
            bounds = new Rect();
        }
    
        @Override
        public void onDraw(@NonNull Canvas canvas, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.onDraw(canvas, parent, state);
            int top = Math.round((parent.getHeight() + paddingTopPx + paddingBottomPx - drawable.getIntrinsicHeight()) / 2f);
            int bottom = top + drawable.getIntrinsicHeight();
            int childCount = parent.getChildCount();
            for (int i=0; i< childCount; i++) {
                View child = parent.getChildAt(i);
                parent.getDecoratedBoundsWithMargins(child, bounds);
                final int right = bounds.right + Math.round(child.getTranslationX()) - paddingRightPx;
                final int left = right - drawable.getIntrinsicWidth();
                drawable.setBounds(left, top, right, bottom );
                drawable.draw(canvas);
            }
        }
    
        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            if (parent.getChildAdapterPosition(view) == state.getItemCount() - 1) {
                outRect.setEmpty();
            } else {
                outRect.set(0,0, drawable.getIntrinsicWidth() + paddingLeftPx + paddingRightPx, 0);
            }
        }
    
        private int getDimenPx(Context context, @DimenRes int dimenId) {
            return (context == null || dimenId == 0)? 0: context.getResources().getDimensionPixelSize(dimenId);
        }
    }
    
  2. Добавьте элемент HorizontalDrawableDecoration и добавьте его в свой RecyclerView.

    recyclerView.addItemDecoration(new HorizontalDrawableDecoration(
            this, R.drawable.arrow_black_short, R.dimen.dp4, 0, R.dimen.dp8, R.dimen.dp8));
    
  3. Еще одна вещь, добавьте измерения в файл измерения.xml в res / values:

    <dimen name="dp8">8dp</dimen>
    <dimen name="dp4">4dp</dimen>
    
0 голосов
/ 28 марта 2019

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

Начиная с API 25 вы также можете использовать это.

var decoration: DividerItemDecoration =  DividerItemDecoration(getApplicationContext(), VERTICAL)
recyclerview.addItemDecoration(decoration)

Надеюсь, это поможет вам выбрать верный путь к тому, чего вы хотите достичь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...