[JAVA] Create a page control that can be used with RecyclerView

What is page control?

It is a dot-shaped pagination that is common in iOS. It is not provided as standard on Android, so you need to create it or use a library. page_control.gif Here, it is called page control after iOS, but in Android, there are many things named Indicator, and a famous library <a href"https://github.com/JakeWharton/ViewPagerIndicator"> ViewPageIndicator > And <a href+"https://github.com/ongakuer/CircleIndicator"> CircleIndicator . However, these libraries could only be used with ViewPager, so I created my own custom view.

Use RecyclerView like ViewPager

ViewPager in RecyclerView by using PagerSnapHelper that can be used with SupportLibrary25.1.0 or higher You can achieve the same behavior. This is useful when you want to avoid ViewPager in ViewPager.

MainActivity.java


RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);

PagerSnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);

If you cannot use PagerSnapHelper due to version, the following article will show you how to make snaps. http://qiita.com/hotpepsi/items/1167e5263f048a005e05

Make a page control

Make a dot

There are two types, default and selected.

res/drawable/shape_page_control_default.xml


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#FFFFFF" />
</shape>

res/drawable/shape_page_control_selected.xml


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="#B7B7B7" />
</shape>

Create a custom view

Create a custom view that does the following two things:

--Create as many dots as there are elements displayed by RecyclerView. ――When you snap, the dots also switch in tandem.

When switching dots in conjunction with snapping, the position of the element currently snapped is required, so it is acquired using `findLastVisibleItemPosition ()` of LinerLayoutManager.

PageControlView.java


public class PageControlView extends LinearLayout {
    private ImageView[] imageViews;

    public PageControlView(Context context) {
        this(context, null);
    }

    public PageControlView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PageControlView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setRecyclerView(RecyclerView recyclerView, final LinearLayoutManager layoutManager) {
        int itemCount = layoutManager.getItemCount();
        if (itemCount < 1) {
            return;
        }
        createPageControl(itemCount);

        //Switch dots as the RecyclerView scrolls
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int position = layoutManager.findLastVisibleItemPosition();
                int itemCount = layoutManager.getItemCount();

                for (int i = 0; i < itemCount; i++) {
                    imageViews[i].setImageResource(R.drawable.shape_page_control_default);
                }
                imageViews[position].setImageResource(R.drawable.shape_page_control_selected);
            }
        });
    }

  //Create as many dots as there are items in RecyclerView
    private void createPageControl (int itemCount) {
        imageViews = new ImageView[itemCount];

        for (int i = 0; i < imageViews.length; i++) {
            imageViews[i] = new ImageView(getContext());
            imageViews[i].setImageResource(R.drawable.shape_page_control_default);

       //Adjust dot size and spacing(The gif image at the top is 10dp)
            int dotSize = getResources().getDimensionPixelSize(R.dimen.page_control_dot_size);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dotSize, dotSize);
            params.setMargins(dotSize / 2, 0, dotSize / 2, 0);
            imageViews[i].setLayoutParams(params);

            addView(imageViews[i]);
        }
        imageViews[0].setImageResource(R.drawable.shape_page_control_selected);
    }
}

Use custom view

Arrange it like a normal view.

activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="com.hogehoge.fugafuga.MainActivity">
    
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <com.hogehoge.fugafuga.PageControlView
        android:id="@+id/page_control_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_gravity="center"/>
</LinearLayout>

MainActivity.java


PageControlView pageControlView = (PageControlView) findViewById(R.id.page_control_view);
pageControlView.setRecyclerView(recyclerView, layoutManager);

bonus

You can also use it with ViewPager by rewriting the setRecyclerView method as follows. This is easier because the listener has a position.

PageControlView.java


    public void setViewPager (final ViewPager viewPager) {
        int itemCount = viewPager.getAdapter().getCount();

        if (itemCount < 1) {
            return;
        }
        createPageControl(itemCount);

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                int itemCount = viewPager.getAdapter().getCount();

                for (int i = 0; i < itemCount; i++) {
                    imageViews[i].setImageResource(R.drawable.shape_page_control_default);
                }
                imageViews[position].setImageResource(R.drawable.shape_page_control_selected);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

Recommended Posts

Create a page control that can be used with RecyclerView
Organize methods that can be used with StringUtils
[Ruby] Methods that can be used with strings
[Rails] "pry-rails" that can be used when saving with the create method
Summary of css selectors that can be used with Nookogiri
Create a jar file that can be executed in Gradle
Firebase-Realtime Database on Android that can be used with copy
I made a question that can be used for a technical interview
SwiftUI View that can be used in combination with other frameworks
Simple slot machine implementation that can be used with copy and paste
Performance analysis and failure diagnostic tools that can be used with OpenJDK
Ruby array methods that can be used with Rails (other than each)
[OpenJDK11 & JavaFX13] Build a javaFX app with IntelliJ + gradle and create a package that can be distributed with a lightweight JRE
I made a THETA API client that can be used for plug-in development
[ERROR message display] A simplified version that can be used at any time with the rails partial template.
Write a class that can be ordered in Java
Range where variables can be used with ruby [Scope]
About the matter that hidden_field can be used insanely
Convenient shortcut keys that can be used in Eclipse
A ruby ​​script that creates an rsa private key that can be used with OpenSSL from any two prime numbers
Syntax and exception occurrence conditions that can be used when comparing with null in Java
Four-in-a-row with gravity that can be played on the console
Programming can be a god.
Create a method that can retrieve characters from any location
Create a playground with Xcode 12
Find a Switch statement that can be converted to a Switch expression
Learning Ruby with AtCoder Beginners Selection [Some Sums] Increase the methods that can be used
Object-oriented design that can be used when you want to return a response in form format
I can no longer connect to a VM with a Docker container that can be connected via SSH
Let's create a Docker container that can connect to CentOS 8 with the minimum configuration by SSH
Static analysis tool that can be used on GitHub [Java version]
Build an environment where pip3 can be used with CentOS7 + Python3
Summary of ORM "uroboroSQL" that can be used in enterprise Java
File form status check sheet that can be deleted with thumbnails
Power skills that can be used quickly at any time --Reflection
Mecab installation that can be done almost by typing a command
Summary of JDK that can be installed with Homebrew (as of November 2019)
Introduction to Java that can be understood even with Krillin (Part 1)
Create a Vue3 environment with Docker!
Create My Page with Rails devise
Create exceptions with a fluid interface
Create a Maven project with a command
[Java 8] Until converting standard input that can be used in coding tests into a list or array
Command line that can create a directory structure for building a Laravel environment with Docker in one shot
How to override in a model unit test so that Faker can be used to generate random values
Java file input / output processing that can be used through historical background
How to quickly create a reverse proxy that supports HTTPS with Docker
Maybe it can be used at a year-end party? Mosaic game code
I tried learning Java with a series that beginners can understand clearly
About the problem that the server can not be started with rails s
Set the access load that can be changed graphically with JMeter (Part 1)
Settings that should be done when operating a production environment with Rails
A memo that enabled VS Code + JUnit 5 to be used on Windows 10
[Swift] Color Picker that can be used with copy and paste (palette that allows you to freely select colors)
Create a jar file with the command
[Rails6] Create a new app with Rails [Beginner]
Create a simple web application with Dropwizard
Create a simple on-demand batch with Spring Batch
Create a GUI JSON Viewer with Ruby/GTK3
[Rails withdrawal] Create a simple withdrawal function with rails
Create a MySQL environment with Docker from 0-> 1