ViewPager auto carousel with dots

Realize the automatic infinite rotation of ViewPager, as shown in the following renderings; request several image addresses on the network to display images using xutils;

1. First, you need to draw small dots, and the small dots need to be displayed using the ImageView control. Create; and the same ImageView needs to display different resources according to the scene; so create the image resource file directory as follows;

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <corners android:radius="8dp" />

    <solid android:color="#fff" >
    </solid>

</shape>

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >

    <corners android:radius="8dp" />

    <solid android:color="#000" >
    </solid>
</shape>

2 Image carousel layout
<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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <android.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="200dp" />

    <LinearLayout
        android:id="@+id/ll_dot"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
		android:layout_alignBottom="@id/vp"        
        
        >
    </LinearLayout>

</RelativeLayout>


3.1 It is necessary to create a corresponding number of small dots according to the number of image addresses

private void initdot() {
		for (int i = 0; i < urls.length; i++) {
			ImageView img = new ImageView(this); // now empty
			if (i == 0) {
				img.setImageResource(R.drawable.dot_focus);
			} else {
				img.setImageResource(R.drawable.dot_normal);
			}
			LayoutParams params = new LayoutParams(20, 20);
			/**
			 *
			 */
			params.setMargins(5, 0, 5, 5);
			
			// load into the layout container
			ll_dot.addView(img, params);
			dots.add(img);
		}

	}

3.2 Because you need to delay the display of pictures, you need to use Handler to automatically play pictures every 2 seconds
	Handler handler = new Handler () {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case 1:
				int po = vp.getCurrentItem();
				vp.setCurrentItem(++po);
				// send delayed message
				this.sendEmptyMessageDelayed(1, 2000);
				break;
			default:
				break;
			}
		};
	};
 

3.3 Use ViewPager to rotate pictures
	String[] urls = BbImages.imgs;
	// Container for recording the number of dots
	List<ImageView> dots = new ArrayList<ImageView>();
	private ViewPager vp;
	private LinearLayout ll_dot;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate (savedInstanceState);
		setContentView(R.layout.activity_main);
		vp = (ViewPager) findViewById(R.id.vp);
		ll_dot = (LinearLayout) findViewById(R.id.ll_dot);
		initdot();
		vp.setAdapter(new VPAdapter(urls, this, handler));
		handler.sendEmptyMessageDelayed (1, 2000);
		vp.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int postion) {
				//
				for (int i = 0; i < dots.size(); i++) {
					ImageView img = dots.get(i);
					if (i == postion % dots.size()) {
						img.setImageResource(R.drawable.dot_focus);
					} else {
						img.setImageResource(R.drawable.dot_normal);
					}
				}
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {

			}

			@Override
			public void onPageScrollStateChanged(int arg0) {

			}
		});
	}


4 The return value of the getCount() method of ViewPager's adaptation page class
: This value is directly related to the "boundary" of ViewPager, so when we set it to Integer.MAX_VALUE, the user basically cannot see this boundary (estimated sliding By the time I got here, the battery was already dead o_O). Of course, it is also possible to set it to 100 times the actual number of content under normal circumstances, which is what an implementation I looked at earlier did.

•InstantiateItem() method position processing: Since we set the count to Integer.MAX_VALUE, the value range of this position is very large, but the actual content we want to display is definitely not so much (often only a few items), so There must be a modulo operation here. However, there is a problem with simple modulo: consider the situation where the user swipes to the left, the position may have a negative value. So we need to process the negative values ​​one more time to make them fall in the correct range.

•InstantiateItem() method parent component processing: Usually we will addView directly, but if it is written like this directly, IllegalStateException will be thrown. Assuming there are 2 views in total, this exception will be triggered when the user slides the first view for the second time, because we are trying to add a View with a parent component to another component. So we can initialize a new layout view every time, and then change the content of the controls in the layout, so we don't have to worry about the conflict between the number of views and the position of the post

package com.example.day17_viewpagerround.adapter;

import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.example.day17_viewpagerround.R;
import com.lidroid.xutils.BitmapUtils;

public class VPAdapter extends PagerAdapter {

	String[] urls;
	Context context;
	Trades trades;

	public VPAdapter(String[] urls, Context context, Handler handler) {
		super();
		this.urls = urls;
		this.context = context;
		this.handler = handler;
	}

	@Override
	public int getCount() {
		return Integer.MAX_VALUE;
	}

	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0 == arg1;
	}

	@Override
	public Object instantiateItem(ViewGroup container, int position) {
		View v = View.inflate(context, R.layout.view_item, null);
		ImageView img = (ImageView) v.findViewById(R.id.imageView1);
		/**
		 * Add touch listener to img
		 */
		img.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					handler.removeCallbacksAndMessages(null);
					break;
				case MotionEvent.ACTION_UP:
				case MotionEvent.ACTION_CANCEL:
					handler.sendEmptyMessageDelayed (1, 2000);
					break;
				}

				return true;
			}

		});

		BitmapUtils utils = new BitmapUtils(context);
		String uri = urls[position % urls.length];
		utils.display(img, uri);

		/**
		 * Load into container
		 */
		container.addView(v);

		return v;
	}

	@Override
	public void destroyItem(ViewGroup container, int position, Object object) {
		// TODO Auto-generated method stub
		container.removeView((View) object);
	}

}


Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326577888&siteId=291194637