Android implements automatic rotation viewpager with indicator

preface

Recently, when working on a project, there is a need to realize the automatic rotation type viewpager. The most intuitive example is the viewpager at the top of Zhihu daily, which has several sub views. Each time, it will automatically slide to the next item view, and the indicator at the bottom will change accordingly. The advantage of using this viewpager is that it can display a variety of information in a limited space. Rotation viewpager is widely used in various applications, such as display advertising. With the purpose of learning and sharing, the author has written the rotating viewpager into an independent control to facilitate future use.

Effect display

Without much to say, let's take a look at the effect:

As can be seen from the dynamic diagram above, when we drag the viewpager with our fingers, the lower indicator slides with the sliding of the page. When we click the add data button, the viewpager has more data items, and the lower indicator also changes to adapt to the number of data items.

As can be seen from the dynamic diagram above, when we drag without fingers, the viewpager will automatically scroll every 4S. When scrolling to the last item view, it will scroll to the first position next time.

GitHub address and usage introduction

Readers can get the source code directly from my GitHub. GitHub: bannerviewpager. The control and its related files are placed in the library module under this directory, and the app module is a simple application shown above.

The control can be easily used through the following steps: 1. Like an ordinary viewpager, put the control in the layout file as follows:

2. Obtain the instance of bannerviewpager and configure it accordingly. For example, when we use viewpager, we also need to set its adapter. Here, the author implements a viewpageradapter, which is used as the adapter of bannerviewpager:

It is no different from the general viewpager: get an instance - create an adapter - set an adapter. The data set of the adapter is generally a view set, which is used as the item view of the viewpager, so the corresponding view set needs to be prepared in advance. In addition, the general rotation viewpager will open the corresponding page after clicking an item, so here is a listener for onpageclicklistener, which can be created when creating the adapter.

Principle analysis

Next, the author will briefly analyze the implementation idea of bannerviewpager. For details, please refer to the source code~

Automatic scrolling

First of all, let's think about it. The viewpager provided by the system is an independent control without indicator and automatic scrolling function, but it is a ready-made control that can slide left and right. We definitely need viewpager. Therefore, we can use a layout to wrap the viewpager and put an indicator in the layout 。

Then, the first step is to create a bannerviewpager.java, which inherits from the FrameLayout, which has two child elements: viewpager and indicator. As for the indicator, it will be mentioned below. Initialize these two controls in the constructor first:

There is nothing to say here. It is mainly to initialize the viewpager and viewpagerindicator and set their layout parameters so that they can be displayed correctly in the FrameLayout.

Then, it is not difficult to realize the principle of automatic scrolling for the viewpager. We only need to know the sliding state of the viewpager and the current page position value all the time. The viewpager has such a listener: viewpager.onpagechangelistener. As long as the viewpager slides, it will call back the following methods of the listener:

Then, we set up a listener for viewpager (call the addonpagechangelistener method), and rewrite these methods to meet our requirements:

Whenever the current page is selected, the onpageselected method will be called to save the current position value. So, what is the current page selected? After experimental verification, when an item is fully displayed in the viewpager, it is selected. However, if it is currently being dragged by a finger, even if the next item slides to the middle position, it is not selected. Next, let's look at the onpagescrollstatechanged method. It will be triggered when the state of the viewpager changes. So, what does * * viewpager's state change mean** Viewpager has the following three states: idle, stop and no finger touch; Dragging, being dragged by fingers; Setting: when releasing the finger, the viewpager slides to the last position due to inertia. In the method we rewritten, mviewpagesrollstate records the real-time state of viewpager. At the same time, when the state is stopped, it also records a mreleasingtime value. The role of this value will be described below. Through this listener, we get the values mcurrentposition and mviewpagescrollstate.

Next, we will consider the problem of automatic tasks. In Android, automatic tasks can be implemented using handler and runnable, and loops can be continuously implemented through the postdelay method. The code is as follows:

In the runable of mautorollingtask, we decide whether to let the viewpager scroll to the next page or wait according to different mviewpagerscrollstates, because if the user is currently touching the viewpage, it must not automatically scroll to the next page. In addition, there is another case when the user's finger leaves the screen, You need to wait for a period of time to start the automatic scrolling task, otherwise it will cause a bad user experience, which is the role of mrelaasingtime. In the handler, different operations are performed according to different information sent by runnable. If it is necessary to scroll to the next page, the viewpager#setcurrentitem method is called to slide. This method has two parameters. The first parameter is the position to slide, and the second parameter indicates whether to start the animation.

Implementation indicator

Next, let's consider how the indicator is implemented. The indicator has the following requirements: the indicator is composed of a series of dots. The dots corresponding to the unselected page are gray, while the dots corresponding to the selected page are orange. The orange dots can slide with the sliding of the page. When the data of the viewpage changes, such as a new page, the indicator will contain more dots.

Then, we can realize the requirements in this way: the gray dot is used as the background of the indicator and drawn by ondraw() method, while the orange dot is displayed by a sub view, and its position is controlled by onlayout() method. In this way, the effect of orange dot moving on the gray dot can be realized. For their specific position control, you can use the viewpager. Onpagechangelistener #onpagescrolled method above to obtain the specific position and position offset percentage.

Let's first implement the drawing part, create a new viewpagerindicator.java, inherit from LinearLayout, and initialize the property first:

From the above code, we can see that in the init () method, we call the setwillnotdraw (false) method. What's the use of this method? Readers who have written custom views should know that the ViewGroup will not call its own OnDraw () method by default. The OnDraw () method will be called only when the method is called and set to false or set a background color for the ViewGroup.

After solving this problem, let's look at the onmeasure () method. In this method, we need to measure the width and height of the indicator for the next layout and drawing process. For our needs, as long as the layout can wrap our indicator and leave a certain space on four sides, the width of the layout is related to the number of pages. For convenience, a default value is given here. For example, five pages correspond to five gray dots. Let's next look at the OnDraw () method, which draws circles according to the number of mitemcounts. There's nothing to talk about here. Just pay attention to the distance between them.

Next, we draw orange dots and create an internal class, which inherits from view. We also use onmeasure and OnDraw methods to measure and draw the process, but the color changes.

OK, the drawing part is finished. The next step is to move the moveview. To make the moveview slide with the sliding of the page, we need the specific position and position offset of the page, and these two values are obtained in the bannerviewpager, so we can call the onpagescrolled method every time in the bannerviewpager, To call a method of our viewpagerindicator, and request the layout inside this method, so as to realize the effect that moveview slides with the sliding of the page, as follows:

The requestlayout () method is called in the setpositionandoffset method. This method will lead to the measurement, layout and redrawing process of the view tree. Therefore, in the onlayout method, you can control the position of the moveview through the values of mcurrentposition and mpositionoffset.

Well, up to now, the viewpagerindicator has been basically completed, but there is another problem. If the data in the adapter is refreshed, the number of pages will increase, but the number of indicators will still remain unchanged. The mitemcount we used above is the default value of 5. Therefore, we must notify the indicator in time to increase the number of indicators when the data is refreshed. However, let's think further. The data list is saved in the adapter. If the viewpagerindicator wants to obtain data, it needs to get a reference from the adapter, or the adapter needs to get a reference from the viewpagerindicator so that it can be notified. If you do so, it is equivalent to connecting two classes with little correlation, and the coupling degree is too high, This is not conducive to future maintenance.

Therefore, the author adopts the observer mode to realize the requirement of notifying the viewpagerindicator when the adapter data is refreshed. First, create two new interfaces. One is datasetsubscriber, observer; The other is datasetsubject, the observed.

The implementation idea here is as follows: implement a datasetsubscriber (observer) in bannerviewpager and a datasetsubject (observed) in viewpageadapter. Register through the registersubscriber method. When the data list of viewpageadapter changes, call back the update () method of datasetsubscriber and pass in the current data length as a parameter, Bannerviewpager can further call the viewpagerindicator method to rearrange the layout.

Let's start with viewpagerindicator. Java:

Since the notifydatasetchanged () method is usually called for changes in the data list, we can call the notifysubscriber () method within this method. In bannerviewpager, you can implement the update() method of datasetsubscriber, as shown below:

Within the update () method, the viewpagerindicator#setitemcount method was called to rearrange the layout. Then, the indicator is implemented.

Realize the click event processing of page

The last requirement is to handle the click of page, because the content of viewpager is only a general content. In order to get more detailed information, users usually click its item to open a new page, so we need to deal with the click event. In fact, the implementation method is not difficult. The idea is similar to the way the author handled click events in the related articles of recyclerview. By defining a new interface: onpageclicklistener, define an onpageclick method. As follows:

Just set a view.onclicklistener for each item view when the item view is initialized, and call our onpageclick method in the onclick method.

The details are as follows: viewpageradapter:

When building the adapter, you can implement onpageclicklistener at the same time.

The above is the whole content of this article. Thank you very much for reading ~ welcome to GitHub to obtain the source code of this article and welcome star or fork. Thanks again!

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>