android - কিভাবে RecyclerView আইটেম মধ্যে বিভাজক এবং স্পেস যোগ করতে?




android-recyclerview divider (20)

অক্টোবর 2016 আপডেট

সমর্থন লাইব্রেরি v25.0.0 সঙ্গে অবশেষে মৌলিক অনুভূমিক এবং উল্লম্ব dividers উপলব্ধ একটি ডিফল্ট বাস্তবায়ন!

DividerItemDecoration

ডিভাইডার এবং ডিভাইড হাইট প্যারামিটারগুলি ব্যবহার করে এটি তালিকা ভিউ ক্লাসে পূর্বে কীভাবে করা যায় তা উদাহরণস্বরূপ:

<ListView
    android:id="@+id/activity_home_list_view"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:divider="@android:color/transparent"
    android:dividerHeight="8dp"/>

যাইহোক, আমি RecyclerView ক্লাসে এই ধরনের সম্ভাবনা দেখতে পাচ্ছি না।

<android.support.v7.widget.RecyclerView
    android:id="@+id/activity_home_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical"/>

সেই ক্ষেত্রে, মার্জিনগুলি সংজ্ঞায়িত করা এবং / অথবা একটি তালিকা আইটেমের বিন্যাসে সরাসরি একটি কাস্টম ডিভাইডার ভিউ যুক্ত করা বা আমার লক্ষ্য অর্জনের আরও ভাল উপায় কি ঠিক আছে?


আপনার মতামত একটি মার্জিন যোগ করুন, এটা আমার জন্য কাজ।

android:layout_marginTop="10dp"

আপনি যদি কেবলমাত্র সমান layoutMargin করতে চান এবং এক্সএমএল এ এটি করতে চান তবে আপনার RecyclerView layoutMargin padding সেট করুন এবং সমান পরিমাণ layoutMargin আপনার layoutMargin আইটেমটিতে আপনি যে পরিমাণ আইটেমটি layoutMargin তাতে layoutMargin এবং পটভূমির রঙটি ফাঁকা রঙ নির্ধারণ করুন।


আমি এই বিশেষ ফাইলটিতে আপনার দৃষ্টি আকর্ষণ করতে পারব অ্যালেক্স ফু দ্বারা গিথুব: https://gist.github.com/alexfu/0f464fc3742f134ccd1e

এটি DividerItemDecoration.java উদাহরণ ফাইল "সমর্থন সমর্থকদের থেকে সরাসরি টেনে নেওয়া হয়েছে"। ( https://plus.google.com/103498612790395592106/posts/VVEB3m7NkSS )

আমি আমার প্রোজেক্টে এই ফাইলটি আমদানি করার পরে সুন্দরভাবে বিভাজক লাইন পেতে এবং পুনঃব্যবহারযোগ্য দর্শনে আইটেম সজ্জা হিসাবে এটি যোগ করতে সক্ষম হয়েছিলাম।

আমার অনক্রিপট ভিউটি আমার ফাঁকা অংশে কেমন লাগছে যেটি Recyclerview ধারণ করে:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_recycler_view, container, false);

    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
    mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    return rootView;
}

আমি নিশ্চিত অতিরিক্ত স্টাইল করা যাবে, কিন্তু এটি একটি শুরু বিন্দু। :)


আমি ডিভাইডার আইটিমেডেকোরেশনকে একটি পুরোনো অংশ থেকে ফর্ক করেছিলাম এবং এটি আমার ব্যবহারের ক্ষেত্রে ফিট করার জন্য সরল করেছিলাম, এবং আমি তালিকা তালিকাতে ড্রয়ারের মতো ড্রয়ারারগুলি আঁকতে এটিও সংশোধন করেছি, শেষ তালিকার আইটেমের পরে একটি ডিভাইডার সহ। এটি উল্লম্ব আইটেম অ্যানিমেটর অ্যানিমেশনগুলি পরিচালনা করবে:

1) আপনার প্রকল্পের এই ক্লাস যোগ করুন:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable divider;

    public DividerItemDecoration(Context context) {
        try {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            divider = a.getDrawable(0);
            a.recycle();
        } catch (Resources.NotFoundException e) {
            // TODO Log or handle as necessary.
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (divider == null) return;
        if (parent.getChildAdapterPosition(view) < 1) return;

        if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
            outRect.top = divider.getIntrinsicHeight();
        else
            throw new IllegalArgumentException("Only usable with vertical lists");
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (divider == null) {
            super.onDrawOver(c, parent, state);
            return;
        }

        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 size = divider.getIntrinsicHeight();
            final int top = (int) (child.getTop() - params.topMargin - size + child.getTranslationY());
            final int bottom = top + size;
            divider.setBounds(left, top, right, bottom);
            divider.draw(c);

            if (i == childCount - 1) {
                final int newTop = (int) (child.getBottom() + params.bottomMargin + child.getTranslationY());
                final int newBottom = newTop + size;
                divider.setBounds(left, newTop, right, newBottom);
                divider.draw(c);
            }
        }
    }

    private int getOrientation(RecyclerView parent) {
        if (!(parent.getLayoutManager() instanceof LinearLayoutManager))
            throw new IllegalStateException("Layout manager must be an instance of LinearLayoutManager");
        return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
    }
}

2) আপনার RecylerView থেকে শোভাকর যোগ করুন:

recyclerView.addItemDecoration(new DividerItemDecoration(getActivity()));

এটি আসলে সমস্যাটি সমাধান করে না, তবে একটি অস্থায়ী useCompatPadding হিসাবে, আপনি আপনার XML useCompatPadding কার্ডটি ব্যবহার করে useCompatPadding সম্পত্তি সেট করতে পারেন যেমন এটি পূর্ব-ললিপপ সংস্করণগুলির উপর একই রকম করে।

card_view:cardUseCompatPadding="true"

এটি সহজ, আপনি এই ধরনের জটিল কোড প্রয়োজন হবে না

DividerItemDecoration divider = new 
DividerItemDecoration(mRVMovieReview.getContext(), 
DividerItemDecoration.VERTICAL);
divider.setDrawable(
    ContextCompat.getDrawable(getBaseContext(), R.drawable.line_divider)
);
mRVMovieReview.addItemDecoration(divider);

আপনার ড্রয়েবেলে এটি যুক্ত করুন: line_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
  android:shape="rectangle">
    <size android:height="1dp" />
    <solid android:color="@android:color/black" />
</shape>

যে কেউ যদি কেবলমাত্র আইটেমগুলির মধ্যে 10 ডিপি স্পেস যুক্ত করতে চান তবে আপনি DividerItemDecoration সেট করে এটি করতে পারেন:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(
    recyclerView.getContext(),
    layoutManager.getOrientation()
);

dividerItemDecoration.setDrawable(
    ContextCompat.getDrawable(getContext(), R.drawable.divider_10dp)
); 

যেখানে divider_10dp একটি divider_10dp সম্পদ রয়েছে:

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <size android:height="10dp"/>
    <solid android:color="@android:color/transparent"/>
</shape>

যেহেতু এখনও মাল্টিমিডিয়া ডিজাইন ব্যবহার করে এটি বাস্তবায়ন করার কোনও সঠিক উপায় নেই, তাই আমি সরাসরি তালিকা আইটেমের উপর একটি ডিভাইডার যোগ করার জন্য নিম্নলিখিত কৌশলটি ব্যবহার করেছি:

<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/dividerColor"/>

সব আইটেম মধ্যে সমান স্পেস জন্য সহজ আইটেম ItemDecoration বাস্তবায়ন।

public class SpacesItemDecoration extends RecyclerView.ItemDecoration {
    private int space;

    public SpacesItemDecoration(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.left = space;
        outRect.right = space;
        outRect.bottom = space;

        // Add top margin only for the first item to avoid double space between items
        if(parent.getChildAdapterPosition(view) == 0) {
            outRect.top = space;
        }
    }
}

সহজ এক আইটেম জন্য RecyclerView এবং বিভিন্ন ব্যাকগ্রাউন্ড রঙের জন্য পটভূমি রঙ সেট করা হয়। এখানে একটি উদাহরণ ...

<android.support.v7.widget.RecyclerView
    android:background="#ECEFF1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scrollbars="vertical"/>

এবং TextView আইটেম (এটি যদিও কিছু হতে পারে) নীচে মার্জিন "x" DP বা PX দিয়ে।

<TextView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginBottom="1dp"
    android:background="#FFFFFF"/>

আউটপুট ...


RecyclerView.ItemDecoration এর নিজস্ব সংস্করণ বাস্তবায়ন

public class SpacingItemDecoration extends RecyclerView.ItemDecoration {
    private int spacingPx;
    private boolean addStartSpacing;
    private boolean addEndSpacing;

    public SpacingItemDecoration(int spacingPx) {
        this(spacingPx, false, false);
    }

    public SpacingItemDecoration(int spacingPx, boolean addStartSpacing, boolean addEndSpacing) {
        this.spacingPx = spacingPx;
        this.addStartSpacing = addStartSpacing;
        this.addEndSpacing = addEndSpacing;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (spacingPx <= 0) {
            return;
        }

        if (addStartSpacing && parent.getChildLayoutPosition(view) < 1 || parent.getChildLayoutPosition(view) >= 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.top = spacingPx;
            } else {
                outRect.left = spacingPx;
            }
        }

        if (addEndSpacing && parent.getChildAdapterPosition(view) == getTotalItemCount(parent) - 1) {
            if (getOrientation(parent) == LinearLayoutManager.VERTICAL) {
                outRect.bottom = spacingPx;
            } else {
                outRect.right = spacingPx;
            }
        }
    }

    private int getTotalItemCount(RecyclerView parent) {
        return parent.getAdapter().getItemCount();
    }

    private int getOrientation(RecyclerView parent) {
        if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            return ((LinearLayoutManager) parent.getLayoutManager()).getOrientation();
        } else {
            throw new IllegalStateException("SpacingItemDecoration can only be used with a LinearLayoutManager.");
        }
    }
}

আপনি প্রোগ্রাম্যাটিকভাবে সহজে যোগ করতে পারেন।

যদি আপনার লেআউট ম্যানেজার লিনিয়ারআলআউট হয় তবে আপনি এটি ব্যবহার করতে পারেন:

DividerItemDecoration একটি RecyclerView.ItemDecoration যা একটি LinearLayoutManager আইটেমগুলির মধ্যে বিভাজক হিসাবে ব্যবহার করা যেতে পারে। এটি উভয় হরাইজন্টাল এবং ভার্চুয়াল ভিত্তিক সমর্থন করে।

 mDividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(),
         mLayoutManager.getOrientation());
 recyclerView.addItemDecoration(mDividerItemDecoration);

DividerItemDecoration


আমি নীচের মত তালিকা আইটেম একটি লাইন যোগ করেছেন

<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/dividerColor"/>

1px পাতলা লাইন আঁকা হবে।

divider.setVisiblity(View.GONE);শেষ তালিকার জন্য বিভাজককে লুকিয়ে রাখতে চান তবে শেষ তালিকা আইটেমের জন্য অনবিন্দুহোল্ডারের উপর।


আমি মনে করি একটি সহজ, কোড ভিত্তিক উত্তর প্রয়োজন যা XML ব্যবহার করে না

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);

ShapeDrawable shapeDrawableForDivider = new ShapeDrawable(new RectShape());

int dividerThickness = // (int) (SomeOtherView.getHeight() * desiredPercent);
shapeDrawableForDivider.setIntrinsicHeight(dividerThickness);
shapeDrawableForDivider.setAlpha(0);

dividerItemDecoration.setDrawable(shapeDrawableForDivider);

recyclerView.addItemDecoration(dividerItemDecoration);

যদি আপনি আইটেমগুলির জন্য একই স্থান যুক্ত করতে চান তবে সর্বাধিক উপায়টি RecycleView এর জন্য শীর্ষ + বাম প্যাডিং এবং ডান আইটেমগুলির কার্ড আইটেমগুলির নীচে মার্জিন যোগ করা।

dimens.xml

<resources>
    <dimen name="divider">1dp</dimen>
</resources>

list_item.xml

<CardView
 android:layout_marginBottom="@dimen/divider"
 android:layout_marginRight="@dimen/divider">
 ...
</CardView>

list.xml

<RecyclerView
 android:paddingLeft="@dimen/divider"
 android:paddingTop="@dimen/divider"
/>

1. এক উপায় হল কার্ডভিউ এবং পুনর্ব্যবহারযোগ্য একসাথে ব্যবহার করে আমরা সহজেই ডিভাইডারের মত প্রভাব যুক্ত করতে পারি। প্রাক্তন। https://developer.android.com/training/material/lists-cards.html

2. এবং অন্যান্য recycler ভিউ list_item_layout divider হিসাবে ভিউ যোগ করে ।

        <View
            android:id="@+id/view1"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="@color/colorAccent" />

RecyclerView-FlexibleDivider ব্যবহার করা একটি সত্যিই সহজ সমাধানRecyclerView-FlexibleDivider

নির্ভরতা যোগ করুন:

compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'

আপনার recyclerview যোগ করুন:

recyclerView.addItemDecoration(new HorizontalDividerItemDecoration.Builder(context).build());

এবং তুমি করে ফেলেছ!


RecyclerViewথেকে একটু ভিন্ন ListView। প্রকৃতপক্ষে, এটি RecyclerViewএকটি ListViewঅনুরূপ গঠন প্রয়োজন । উদাহরণস্বরূপ, একটি LinearLayout। দ্য LinearLayoutপ্রতিটি উপাদান বিভাজক জন্য প্যারামিটার আছে। কোড নিচে আমি একটি আছে RecyclerViewগঠিত CardViewবস্তু একটি মধ্যে LinearLayoutএকটি "প্যাডিং" যে আইটেম মধ্যে কিছু স্থান করা হবে না। যে স্থান সত্যিই ছোট করুন এবং আপনি একটি লাইন পেতে।

এখানে recyclerview_layout.xml পুনর্ব্যবহারযোগ্য দেখুন

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".ToDoList">

    <!-- A RecyclerView with some commonly used attributes -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/todo_recycler_view"
        android:scrollbars="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

এবং এখানে প্রতিটি আইটেম দেখতে কেমন হয় (এবং এটি অ্যানড্রয়েডের কারণে বিভক্ত হিসাবে দেখায়: লিনিয়ার এলয়েটের প্যাডিং যা সবকিছু ঘিরে থাকে।) অন্য ফাইলের মধ্যে: card_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    **android:padding="@dimen/activity_vertical_margin"**>
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView
        xmlns:card_view="http://schemas.android.com/apk/res-auto"
        android:id="@+id/card_view"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:elevation="30dp"
        card_view:cardElevation="3dp">
            <TextView
                android:id="@+id/info_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
    </android.support.v7.widget.CardView>
</LinearLayout>

খুব দেরী কিন্তু GridLayoutManagerআমি এই ব্যবহার করতে:

public class GridSpacesItemDecoration : RecyclerView.ItemDecoration
{
    private int space;

    public GridSpacesItemDecoration(int space) {
        this.space = space;
    }

    public override void GetItemOffsets(Android.Graphics.Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        var position = parent.GetChildLayoutPosition(view);

        /// Only for GridLayoutManager Layouts
        var manager = parent.GetLayoutManager() as GridLayoutManager;

        if (parent.GetChildLayoutPosition(view) < manager.SpanCount)
            outRect.Top = space;

        if (position % 2 != 0) {
            outRect.Right = space;
        }

        outRect.Left = space;
        outRect.Bottom = space;
    }
}

আপনার কোন গণনা গণনা জন্য এই কাজ।

Ollie।


পরিবর্তে shape xmlবিভাজক উচ্চতা এবং রঙ পরিবর্তন জন্য একটি তৈরি করতে । আপনি প্রোগ্রাম্যাটিকভাবে মত তৈরি করতে পারেন

val divider = DividerItemDecoration(context,
        DividerItemDecoration.VERTICAL)

divider.setDrawable(ShapeDrawable().apply {
    intrinsicHeight = resources.getDimensionPixelOffset(R.dimen.dp_15)
    paint.color = Color.RED // note: currently (support version 28.0.0), we can not use tranparent color here, if we use transparent, we still see a small divider line. So if we want to display transparent space, we can set color = background color or we can create a custom ItemDecoration instead of DividerItemDecoration. 
})

recycler_devices.addItemDecoration(divider)




divider