Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RecyclerView styling at theme level

I'm trying to implement generic style parameters for RecyclerView at theme levels. As in contrast to ListView, I used something like this:

Defined a style:

<style name="StyleListView" parent="Widget.AppCompat.ListView">
     <item name="android:requiresFadingEdge">vertical</item>
     <item name="android:fadingEdgeLength">10dp</item>
     <item name="android:scrollbars">vertical</item>
</style>

and later used in my custom theme:

<item name="android:listViewStyle">@style/StyleListView</item>

This works perfectly fine for ListView. However, I'm unable to reflect this for RecyclerView as I thought it would work for any type of list.

So, is there any predefined style attribute available for RecyclerView, for example android:recyclerViewStyle or anything?

If not, then how can I achieve this at theme level?

like image 678
waqaslam Avatar asked Aug 22 '16 10:08

waqaslam


People also ask

What is ViewHolder in RecyclerView Android?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive findViewById results. While LayoutParams belong to the LayoutManager , ViewHolders belong to the adapter.

How many layouts are used in RecyclerView?

The RecyclerView library provides three layout managers, which handle the most common layout situations: LinearLayoutManager arranges the items in a one-dimensional list.


3 Answers

RecyclerView styling at theme level

RecyclerView now has a default style attribute: recyclerViewStyle, which allows setting of the default style in your theme

The following attributes are supported

    <!-- Class name of the Layout Manager to be used. -->
    <attr name="layoutManager" format="string" />
   
    <!-- ============================= -->
    <!-- Attributes for Layout Manager -->
    <!-- ============================= -->
    <attr name="android:orientation" />
    <attr name="android:descendantFocusability" />
    <attr name="android:clipToPadding" />
    <attr name="spanCount" format="integer"/>
    <attr name="reverseLayout" format="boolean" />
    <attr name="stackFromEnd" format="boolean" />
    <attr name="fastScrollEnabled" format="boolean" />
    <attr name="fastScrollVerticalThumbDrawable" format="reference" />
    <attr name="fastScrollVerticalTrackDrawable" format="reference" />
    <attr name="fastScrollHorizontalThumbDrawable" format="reference" />
    <attr name="fastScrollHorizontalTrackDrawable" format="reference" />

To use the above feature, add/update the following dependency in your build.gradle file.

dependencies {
    implementation 'androidx.recyclerview:recyclerview:1.1.0-beta05'
}

You can see the commit here.

Example:

1. Define your default style

<style name="DefaultRecyclerViewStyle">

    <item name="layoutManager">androidx.recyclerview.widget.GridLayoutManager</item>
    <item name="android:orientation">vertical</item>
    <item name="spanCount">2</item>

</style>

2. Add the above style into your default theme

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="recyclerViewStyle">@style/DefaultRecyclerViewStyle</item>
</style>

Thats, all. You have defined an application wide default style for your RecyclerView widgets.

like image 50
Darish Avatar answered Oct 16 '22 17:10

Darish


There's not an equivalent to listViewStyle for RecylerView, unfortunately.

I think the best you can do is define a style for your RecyclerView, then have whichever views you want to use that style use style="@style/RecyclerViewStyle" (if you're just wanting to define a couple attributes like in your example).

If you really just don't want to have to do that for every RecyclerView, then you'd have to subclass it and return a non-zero parameter for defStyle in the constructor. You'd have to replace all instances of your RecyclerView in XML with your newly subclassed class, though.

like image 39
Jason Robinson Avatar answered Oct 16 '22 17:10

Jason Robinson


As @Jason Robinson says you can subclass RecyclerView in this way, replace RecyclerView with RecyclerViewStyleable in xml and then style it with recyclerViewStyle

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RecyclerViewStyleable">
        <attr name="recyclerViewStyle"/>
    </declare-styleable>
</resources>

-

public class RecyclerViewStyleable extends RecyclerView {
    public RecyclerViewStyleable(Context context) {
        super(context);
    }

    public RecyclerViewStyleable(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.recyclerViewStyle);
    }

    public RecyclerViewStyleable(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}
like image 1
Anton Pogonets Avatar answered Oct 16 '22 17:10

Anton Pogonets