Android ViewPager infinite loop sliding and automatic scrolling complete example
- 2021-08-28 21:16:37
- OfStack
For ViewPager advertising page this function a lot of APP have this function on the Internet have also seen some information, I will be in this complete implementation of my own method to write it out
Basic ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/top_item"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/top_vp"
></android.support.v4.view.ViewPager>
</LinearLayout>
It's very simple. It's just an ViewPager
Next, add ImageView to Adapter of ViewPager under simple setting 1
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; // Simulate storing the picture to be displayed
private List<ImageView> imageViews ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
}
/**
* Initialize picture resources
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return imageViews.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imageViews.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(imageViews.get(position));
return imageViews.get(position);
}
});
}
}
The above is the most basic ViewPager. Below, we can transform it on this basis
Achieve infinite circular sliding:
Here I prior loop sliding way is very simple is to set adapter count to a very large value so that it can not slide to the head and then switch pictures can be achieved although the method is compared with LOW but the effect is still OK
The code is modified under the basic ViewPager as follows:
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; // Simulate storing the picture to be displayed
private List<ImageView> imageViews ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
}
/**
* Initialize picture resources
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
// return imageViews.size(); Amend as follows
return 10000;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// container.removeView(imageViews.get(position%imageViews.size())); Delete this sentence This sentence is not deleted Will appear Sliding The situation where the layout disappears Because it was removed This modification here will affect 1 Some performance. . . . .
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// container.addView(imageViews.get(position));
// return imageViews.get(position); Amend as follows
try {
container.addView(imageViews.get(position%imageViews.size()));
}catch (Exception e){
}
return imageViews.get(position%imageViews.size());
}
});
}
}
In this way, the infinite loop can be realized to slide right, but it is impossible to slide left when the program is just started. It is very simple to solve it only at the beginning
viewPager.setCurrentItem(1000*imageViews.size());
You can realize infinite left and right sliding in this way
Automatic timing cycle sliding:
Add the function of automatic timing sliding left and right below
The most important thing to realize automatic sliding is to realize timer function. I use Handler+Runnable method here to modify the following on the basis of the above code:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
handler = new Handler();
handler.postDelayed(new TimerRunnable(),5000);
}
class TimerRunnable implements Runnable{
@Override
public void run() {
int curItem = topVp.getCurrentItem();
topVp.setCurrentItem(curItem+1);
if (handler!=null){
handler.postDelayed(this,5000);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
handler = null; // Here in Activity Timely when exiting Recycle
}
After that, automatic sliding can be realized
Add a small round button in the lower left corner:
Next, add the navigation origin in the lower left corner
First modify the layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/top_item"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/top_vp"
></android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/lin_points"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
The origin we need to be in the LinearLayout layout
The main principle is to dynamically add small dots to this LinearLayout
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; // Simulate storing the picture to be displayed
private List<ImageView> imageViews ;
private List<TextView> txtPoints;
private LinearLayout lin_points;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lin_points = (LinearLayout) findViewById(R.id.lin_points);
initImageViews();
initVp();
initCircle();
/*
* Timer
*/
handler = new Handler();
handler.postDelayed(new TimerRunnable(),5000);
}
/**
* Initialize dot
*/
private void initCircle() {
txtPoints = new ArrayList<>();
int d = 20;
int m = 7;
for (int i = 0; i < imageViews.size(); i++) {
TextView txt = new TextView(this);
if (i == 0) {
txt.setBackgroundResource(R.drawable.point_pink);
} else {
txt.setBackgroundResource(R.drawable.point_grey);
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d, d);
params.setMargins(m, m, m, m);
txt.setLayoutParams(params);
txtPoints.add(txt);
lin_points.addView(txt);
}
}
class TimerRunnable implements Runnable{
@Override
public void run() {
int curItem = topVp.getCurrentItem();
topVp.setCurrentItem(curItem+1);
changePoints((curItem+1)%imageViews.size());
if (handler!=null){
handler.postDelayed(this,5000);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
handler = null;
}
/**
* Initialize picture resources
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
// return imageViews.size(); Amend as follows
return 10000;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// container.removeView(imageViews.get(position%imageViews.size())); Delete this sentence
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// container.addView(imageViews.get(position));
// return imageViews.get(position); Amend as follows
try {
container.addView(imageViews.get(position%imageViews.size()));
}catch (Exception e){
}
return imageViews.get(position%imageViews.size());
}
});
topVp.setCurrentItem(imageViews.size()*1000);
topVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
changePoints((position)%imageViews.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void changePoints(int pos) {
if (txtPoints != null) {
for (int i = 0; i < txtPoints.size(); i++) {
if (pos == i) {
txtPoints.get(i).setBackgroundResource(R.drawable.point_pink);
} else {
txtPoints.get(i).setBackgroundResource(R.drawable.point_grey);
}
}
}
}
}
Add switching animation to ViewPager:
topVp.setPageTransformer(true,new CubeOutTransformer());
Calling this line of code can add that the following TransFormer class is a custom transition effect class
Control the speed of ViewPager automatic switching
The switching speed of ViewPager itself is written dead, We can not modify, but we can see through the source code, ViewPager switching speed is through Scroller class control, and Scroller class can be set transition time, so we can create our own Scroller class inheritance Scroller and then through the reflection of ViewPager in the ViewPager attribute set to our own can set the time of Scroller class
Here's the code:
public class FixedSpeedScroller extends Scroller {
private int mDuration = 1500;
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
public void setmDuration(int time) {
mDuration = time;
}
public int getmDuration() {
return mDuration;
}
}
Reflection modifies ViewPager properties:
try {
Field field = ViewPager.class.getDeclaredField("mScroller");
field.setAccessible(true);
scroller = new FixedSpeedScroller(getActivity());
scroller.setmDuration(1000);
field.set(topVp, scroller);
} catch (Exception e) {
// e.printStackTrace();
System.out.println("aaaaaa Wrong ");
}
So you can control the speed
Ok, Android ViewPager advertisement page can slide infinitely and automatically scroll with the function of small dots is basically realized, the specific parameters can be set by yourself