Android ViewPager使用小结

Viewpager在项目中随处可见,通常用来做引导页、图片轮翻,或结合Fragment搭建Tab+Fragment+ViewPager项目整体框架。简单总结了一下ViewPager的常见使用方式,由于比较简单直接上代码!

1、引导页实现

引导页一般分为两种,左右滑动引导,上下滑动引导,通过ViewPager轻松实现左右滑动的引导页,并且实现引导点跟随滑动而移动的引导页。
效果图:
这里写图片描述

activity_main.xml

<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.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>

    <FrameLayout
        android:id="@+id/layout_frame"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true" >

        <LinearLayout
            android:id="@+id/layout_point"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </FrameLayout>

    <Button
        android:id="@+id/btn_go"
        android:layout_width="wrap_content"
        android:layout_height="35dp"
        android:layout_above="@id/layout_frame"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp"
        android:background="@drawable/shape_white_blue_4"
        android:padding="5dp"
        android:text="立即进入"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        android:visibility="gone" />

</RelativeLayout>

引入v4包中的ViewPager,添加引导点的布局,其中FrameLayout包裹LinearLayout是因为,选中点(即亮点)需要跟随移动,当某个Pager被选中时选中点将该Pager之前的未选中点(即暗点)进行了遮挡,所以需要上下层关系,在布局中体现包裹关系。
MainActivity.java

/**
 * Created by magic on 2016年9月28日.引导点跟随移动的引导页
 */
public class MainActivity extends Activity implements OnPageChangeListener {

	ViewPager viewPager;
	FrameLayout layout_frame;
	LinearLayout layout_point;
	// 带颜色的引导点
	ImageView img_colorPoint;
	Button btn_go;

	List<View> list_view = new ArrayList<View>();
	List<ImageView> list_pointView = new ArrayList<ImageView>();

	//ViewPager 适配器
	ViewPagerAdapter adapter;

	// 两点之间间距
	int pointSpacing;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initView();
		initGuideView();
	}

	/**
	 * 初始化引导页相关
	 */
	private void initGuideView() {
		//添加展示的View
		LayoutInflater inflater = LayoutInflater.from(this);
		list_view.add(inflater.inflate(R.layout.guide_one, null));
		list_view.add(inflater.inflate(R.layout.guide_two, null));
		list_view.add(inflater.inflate(R.layout.guide_three, null));
		adapter = new ViewPagerAdapter(list_view);
		viewPager.setAdapter(adapter);

		//添加引导点
		for (int i = 0; i < list_view.size(); i++) {
			ImageView point = new ImageView(this);
			//设置暗点
			point.setBackgroundResource(R.drawable.img_guide_point);
			LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);
			lp.setMargins(10, 0, 10, 0);
			point.setLayoutParams(lp);
			list_pointView.add(point);
			layout_point.addView(point);
		}

		//添加选中的引导点
		img_colorPoint = new ImageView(MainActivity.this);
		//设置亮点
		img_colorPoint.setBackgroundResource(R.drawable.img_guide_point_selected);
		LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
		img_colorPoint.setLayoutParams(lp);
		layout_frame.addView(img_colorPoint);
		layout_frame.post(new Runnable() {

			@Override
			public void run() {
				//待布局绘制完毕  设置选中白点 的初始化位置
				FrameLayout.LayoutParams l = (FrameLayout.LayoutParams) img_colorPoint.getLayoutParams();
				l.leftMargin = list_pointView.get(0).getLeft();
				img_colorPoint.setLayoutParams(l);
			}
		});

		layout_point.post(new Runnable() {

			@Override
			public void run() {
				// 获取引导的之间的间隔
				pointSpacing = layout_point.getChildAt(1).getLeft()- layout_point.getChildAt(0).getLeft();
			}
		});

	}

	private void initView() {
		viewPager = (ViewPager) findViewById(R.id.viewPager);
		layout_frame = (FrameLayout) findViewById(R.id.layout_frame);
		layout_point = (LinearLayout) findViewById(R.id.layout_point);
		btn_go = (Button) findViewById(R.id.btn_go);
		viewPager.setOnPageChangeListener(this);
		
		btn_go.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				startActivity(new Intent(MainActivity.this,TwoActivity.class));
			}
		});
	}

	@Override
	public void onPageScrollStateChanged(int arg0) {
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		FrameLayout.LayoutParams l = (FrameLayout.LayoutParams) img_colorPoint
				.getLayoutParams();
		//根据滑动动态设置左外边距
		l.leftMargin = (int) (list_pointView.get(arg0).getLeft() + pointSpacing
				* arg1);
		img_colorPoint.setLayoutParams(l);
	}

	@Override
	public void onPageSelected(int arg0) {
		//根据Pager位置设置btn的显示
		if (arg0 == list_view.size() - 1) {
			btn_go.setVisibility(View.VISIBLE);
		} else {
			btn_go.setVisibility(View.GONE);
		}
	}

}

ViewPager的onPageScrolled(int arg0, float arg1, int arg2)回调在滑动过程中会一直调用,参数arg0 :当前页面,点击滑动的页面;arg1:当前页面偏移的百分比;arg2:当前页面偏移的像素位置 。有个这个方法就可以计算小白点的偏移位置了,两引导点之间间距相对两个Pager之间的间距即ViewPager的“宽度”,因此偏移百分比是相同的。
ViewPagerAdapter.java

/**
 * Created by magic on 2016年9月28日.ViewPager适配器
 */
public class ViewPagerAdapter extends PagerAdapter {

	private List<View> views;

	public ViewPagerAdapter(List<View> list) {
		super();
		this.views = list;
	}

	// 从当前container中删除指定位置(position)的View
	@Override
	public void destroyItem(View container, int position, Object object) {
		((ViewPager) container).removeView(views.get(position));
	}

	// 第一:将当前视图添加到container中,第二:返回当前View
	@Override
	public Object instantiateItem(View container, int position) {
		// 将当前视图添加到container中
		((ViewPager) container).addView(views.get(position));
		// 设置当前视图的唯一标示Key
		return views.get(position);
	}

	// getCount():返回要滑动的View的个数
	@Override
	public int getCount() {
		return views.size();
	}

	// 通过标识arg1找到view
	@Override
	public boolean isViewFromObject(View arg0, Object arg1) {
		return arg0 == arg1;
	}
}

2、图片轮翻实现

图片轮翻和引导页代码几乎是一致的,只是添加了定时器,用于自动切换界面。
效果图:
这里写图片描述

activity_two.xml

<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" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="180dp" >

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

        <FrameLayout
            android:id="@+id/layout_frame"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_alignParentBottom="true" >

            <LinearLayout
                android:id="@+id/layout_point"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center_horizontal"
                android:orientation="horizontal" >
            </LinearLayout>
        </FrameLayout>
    </RelativeLayout>

</RelativeLayout>

TwoActivity.java

/**
 * Created by magic on 2016年9月28日.图片轮番
 */
public class TwoActivity extends Activity implements OnPageChangeListener {

	ViewPager viewPager;
	FrameLayout layout_frame;
	LinearLayout layout_point;
	// 带颜色的引导点
	ImageView img_colorPoint;

	List<View> list_view = new ArrayList<View>();
	List<ImageView> list_pointView = new ArrayList<ImageView>();

	ViewPagerAdapter adapter;

	// 两点之间间距
	int pointSpacing;
	//当前ViewPager选中位置
	int pageSelect = 0;

	//定时器
	Timer timer;
	Task task;

	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			viewPager.setCurrentItem(pageSelect);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_two);
		initView();
		initGuideView();

		timer = new Timer();
		task = new Task();
		//设置定时延迟1000开始  时间周期1500
		timer.schedule(task, 1000, 1500);
	}

	private void initGuideView() {
		LayoutInflater inflater = LayoutInflater.from(this);
		list_view.add(inflater.inflate(R.layout.guide_one, null));
		list_view.add(inflater.inflate(R.layout.guide_two, null));
		list_view.add(inflater.inflate(R.layout.guide_three, null));
		adapter = new ViewPagerAdapter(list_view);
		viewPager.setAdapter(adapter);

		for (View view : list_view) {
			view.setOnClickListener(new View.OnClickListener() {
				
				@Override
				public void onClick(View v) {
					startActivity(new Intent(TwoActivity.this,ThreeActivity.class));
				}
			});
		}
		
		
		
		for (int i = 0; i < list_view.size(); i++) {
			ImageView point = new ImageView(this);
			point.setBackgroundResource(R.drawable.img_guide_point);
			LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);
			lp.setMargins(10, 0, 10, 0);
			point.setLayoutParams(lp);
			list_pointView.add(point);
			layout_point.addView(point);
		}

		img_colorPoint = new ImageView(TwoActivity.this);
		img_colorPoint
				.setBackgroundResource(R.drawable.img_guide_point_selected);
		LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT);
		img_colorPoint.setLayoutParams(lp);
		layout_frame.addView(img_colorPoint);
		layout_frame.post(new Runnable() {

			@Override
			public void run() {
				FrameLayout.LayoutParams l = (FrameLayout.LayoutParams) img_colorPoint
						.getLayoutParams();
				l.leftMargin = list_pointView.get(0).getLeft();
				img_colorPoint.setLayoutParams(l);
			}
		});

		layout_point.post(new Runnable() {

			@Override
			public void run() {
				// 获取引导的之间的间隔
				pointSpacing = layout_point.getChildAt(1).getLeft()
						- layout_point.getChildAt(0).getLeft();
			}
		});

	}

	private void initView() {
		viewPager = (ViewPager) findViewById(R.id.viewPager);
		layout_frame = (FrameLayout) findViewById(R.id.layout_frame);
		layout_point = (LinearLayout) findViewById(R.id.layout_point);
		viewPager.setOnPageChangeListener(this);
	}

	@Override
	public void onPageScrollStateChanged(int arg0) {
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		System.out.println("arg0:" + arg0 + " arg1:" + arg1 + " arg2:" + arg2);
		FrameLayout.LayoutParams l = (FrameLayout.LayoutParams) img_colorPoint
				.getLayoutParams();
		l.leftMargin = (int) (list_pointView.get(arg0).getLeft() + pointSpacing
				* arg1);
		img_colorPoint.setLayoutParams(l);
	}

	@Override
	public void onPageSelected(int arg0) {
		pageSelect = arg0;
	}

	/**
	 * 定时任务类
	 */
	class Task extends TimerTask {

		@Override
		public void run() {
			pageSelect++;
			if (pageSelect >= list_view.size()) {
				pageSelect = 0;
			}
			handler.sendEmptyMessage(pageSelect);
		}
	}

}

ViewPagerAdapter.java同上~~~

3、图片循环轮翻实现

上面的图片轮翻可自动切换,也可手动滑动切换。但是存在一个问题就是当手动切换的时候滑动到第一个Pager或最后一个Pager时,再向前或向后滑动就不能滑了,这样的体验是不太好的 。
为了解决这个问题,自己冥思苦想,加上查找资源,无奈人丑脑笨,未能合理解决,利用ViewPager去做总会存在或多或少的bug,例如白屏、Pager数量影响滑动效果等问题。最后求助朋友,得到一前人写的自定义控件(该实现并非使用Viewpager,但和ViewPager实现图片轮翻效果一致就放一块整理了),完美解决了,哈哈~
效果图:
这里写图片描述

先上布局activity_three.xml

<?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:orientation="vertical" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="180dp" >

        <com.magic.custom.MyPagerGalleryView
            android:id="@+id/mypager_galleryview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <LinearLayout
            android:id="@+id/layout_point"
            android:layout_width="match_parent"
            android:layout_height="15dp"
            android:layout_alignParentBottom="true"
            android:layout_marginBottom="20dp"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</LinearLayout>

主界面ThreeActivity.java

/**
 * Created by magic on 2016年9月29日.图片轮翻循环效果
 */
public class ThreeActivity extends Activity {

	MyPagerGalleryView mypager_galleryview;
	LinearLayout layout_point;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_three);

		mypager_galleryview = (MyPagerGalleryView) findViewById(R.id.mypager_galleryview);
		layout_point = (LinearLayout) findViewById(R.id.layout_point);

		mypager_galleryview
				.start(this, new ArrayList<String>(), new int[] { R.drawable.img_guide_one,
						R.drawable.img_guide_two, R.drawable.img_guide_three },
						1500, layout_point,
						R.drawable.img_guide_point_selected,
						R.drawable.img_guide_point);
	}

}

自定义控件:MyPagerGalleryView.java

/**
 * 无限滚动广告栏组件
 */
@SuppressWarnings("deprecation")
public class MyPagerGalleryView extends Gallery implements
		android.widget.AdapterView.OnItemClickListener,
		android.widget.AdapterView.OnItemSelectedListener, OnTouchListener {
	/** 显示的Activity */
	private Context mContext;
	/** 条目单击事件接口 */
	private MyOnItemClickListener mMyOnItemClickListener;
	/** 图片切换时间 */
	private int mSwitchTime;
	/** 自动滚动的定时器 */
	private Timer mTimer;
	/** 圆点容器 */
	private LinearLayout mOvalLayout;
	/** 当前选中的数组索引 */
	private int curIndex = 0;
	/** 上次选中的数组索引 */
	private int oldIndex = 0;
	/** 圆点选中时的背景ID */
	private int mFocusedId;
	/** 圆点正常时的背景ID */
	private int mNormalId;
	/** 图片资源ID组 */
	private int[] mAdsId;
	/** 图片网络路径数组 */
	private List<String> list;
	/** ImageView组 */
	private List<ImageView> listImgs;
	/** 广告条上面textView控件 */
	private TextView adgallerytxt;
	/** 广告条上的每一条文字的数组 */
	private String[] txtViewpager;

	private ImageLoader il;

	public MyPagerGalleryView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public MyPagerGalleryView(Context context) {
		super(context);
	}

	public MyPagerGalleryView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	/**
	 * 对外开放方法
	 * 
	 * @param context
	 *            显示的Activity ,不能为null
	 * @param mris
	 *            图片的网络路径数组 ,为空时 加载 adsId
	 * @param adsId
	 *            图片组资源ID ,测试用
	 * @param switchTime
	 *            图片切换时间 写0 为不自动切换
	 * @param ovalLayout
	 *            圆点容器 ,可为空
	 * @param focusedId
	 *            圆点选中时的背景ID,圆点容器可为空写0
	 * @param normalId
	 *            圆点正常时的背景ID,圆点容器为空写0
	 * @param adgallerytxt
	 *            广告条上面textView控件
	 * @param txtViewpager
	 *            广告条上的每一条文字的数组
	 * 
	 */
	public void start(Context context, List<String> list, int[] adsId,
			int switchTime, LinearLayout ovalLayout, int focusedId, int normalId) {
		this.mContext = context;
		this.list = list;
		this.mAdsId = adsId;
		this.mSwitchTime = switchTime;
		this.mOvalLayout = ovalLayout;
		this.mFocusedId = focusedId;
		this.mNormalId = normalId;

		ininImages();// 初始化图片组
		setAdapter(new AdAdapter());
		this.setOnItemClickListener(this);
		this.setOnTouchListener(this);
		this.setOnItemSelectedListener(this);
		this.setSoundEffectsEnabled(false);
		this.setAnimationDuration(700); // 动画时间
		this.setUnselectedAlpha(1); // 未选中项目的透明度
		// 不包含spacing会导致onKeyDown()失效!!! 失效onKeyDown()前先调用onScroll(null,1,0)可处理
		setSpacing(0);
		// 取靠近中间 图片数组的整倍数
		setSelection((getCount() / 2 / listImgs.size()) * listImgs.size()); // 默认选中中间位置为起始位置
		setFocusableInTouchMode(true);
		initOvalLayout();// 初始化圆点
		startTimer();// 开始自动滚动任务
	}

	/** 初始化图片组 */
	private void ininImages() {
		listImgs = new ArrayList<ImageView>(); // 图片组
		int len = list.size() != 0 ? list.size() : mAdsId.length;
		for (int i = 0; i < len; i++) {
			ImageView imageview = new ImageView(mContext); // 实例化ImageView的对象
			imageview.setScaleType(ImageView.ScaleType.FIT_XY); // 设置缩放方式
			imageview.setLayoutParams(new Gallery.LayoutParams(
					Gallery.LayoutParams.MATCH_PARENT,
					Gallery.LayoutParams.MATCH_PARENT));
			if (list.size() == 0) {// 本地加载图片
				imageview.setImageResource(mAdsId[i]); // 为ImageView设置要显示的图片
			} else { // 网络加载图片
				il = ImageLoader.getInstance();
				il.init(ImageLoaderConfiguration.createDefault(mContext));
				il.displayImage(list.get(i), imageview);
			}
			listImgs.add(imageview);
		}

	}

	/** 初始化圆点 */
	private void initOvalLayout() {

		if (mOvalLayout != null && listImgs.size() < 2) {// 如果只有一第图时不显示圆点容器
			mOvalLayout.removeAllViews();
			mOvalLayout.getLayoutParams().height = 0;
		} else if (mOvalLayout != null) {
			mOvalLayout.removeAllViews();
			// 圆点的大小是 圆点窗口的 70%;
			int Ovalheight = (int) (mOvalLayout.getLayoutParams().height * 0.7);
			// 圆点的左右外边距是 圆点窗口的 20%;
			int Ovalmargin = (int) (mOvalLayout.getLayoutParams().height * 0.2);
			android.widget.LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
					Ovalheight, Ovalheight);
			layoutParams.setMargins(Ovalmargin, 0, Ovalmargin, 0);
			for (int i = 0; i < listImgs.size(); i++) {
				View v = new View(mContext); // 员点
				v.setLayoutParams(layoutParams);
				v.setBackgroundResource(mNormalId);
				mOvalLayout.addView(v);
			}
			// 选中第一个
			mOvalLayout.getChildAt(0).setBackgroundResource(mFocusedId);
		}
	}

	/** 无限循环适配器 */
	class AdAdapter extends BaseAdapter {
		@Override
		public int getCount() {
			if (listImgs.size() < 2)// 如果只有一张图时不滚动
				return listImgs.size();
			return Integer.MAX_VALUE;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			return listImgs.get(position % listImgs.size()); // 返回ImageView
		}

		@Override
		public Object getItem(int position) {
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}
	}

	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
			float velocityY) {
		int kEvent;
		if (isScrollingLeft(e1, e2)) { // 检查是否往左滑动
			kEvent = KeyEvent.KEYCODE_DPAD_LEFT;
		} else { // 检查是否往右滑动
			kEvent = KeyEvent.KEYCODE_DPAD_RIGHT;
		}
		onKeyDown(kEvent, null);
		return true;

	}

	/** 检查是否往左滑动 */
	private boolean isScrollingLeft(MotionEvent e1, MotionEvent e2) {
		return e2.getX() > (e1.getX() + 50);
	}

	@Override
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
			float distanceY) {
		return super.onScroll(e1, e2, distanceX, distanceY);
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		if (MotionEvent.ACTION_UP == event.getAction()
				|| MotionEvent.ACTION_CANCEL == event.getAction()) {
			startTimer();// 开始自动滚动任务
		} else {
			stopTimer();// 停止自动滚动任务
		}
		return false;
	}

	/** 图片切换事件 */
	@Override
	public void onItemSelected(AdapterView<?> arg0, View arg1, int position,
			long arg3) {
		curIndex = position % listImgs.size();
		if (mOvalLayout != null && listImgs.size() > 1) { // 切换圆点
			mOvalLayout.getChildAt(oldIndex).setBackgroundResource(mNormalId); // 圆点取消
			mOvalLayout.getChildAt(curIndex).setBackgroundResource(mFocusedId);// 圆点选中
			oldIndex = curIndex;
		}
		// adgallerytxt.setText("" + curIndex);
	}

	@Override
	public void onNothingSelected(AdapterView<?> arg0) {
	}

	/** 项目点击事件 */
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position,
			long arg3) {
		if (mMyOnItemClickListener != null) {
			mMyOnItemClickListener.onItemClick(curIndex);
		}
	}

	/** 设置项目点击事件监听器 */
	public void setMyOnItemClickListener(MyOnItemClickListener listener) {
		mMyOnItemClickListener = listener;
	}

	/** 项目点击事件监听器接口 */
	public interface MyOnItemClickListener {
		/**
		 * @param curIndex
		 *            //当前条目在数组中的下标
		 */
		void onItemClick(int curIndex);
	}

	/** 停止自动滚动任务 */
	public void stopTimer() {
		if (mTimer != null) {
			mTimer.cancel();
			mTimer = null;
		}
	}

	/** 开始自动滚动任务 图片大于1张才滚动 */
	public void startTimer() {
		if (mTimer == null && listImgs.size() > 1 && mSwitchTime > 0) {
			mTimer = new Timer();
			mTimer.schedule(new TimerTask() {
				public void run() {
					handler.sendMessage(handler.obtainMessage(1));
				}
			}, mSwitchTime, mSwitchTime);
		}
	}

	/** 处理定时滚动任务 */
	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			// 不包含spacing会导致onKeyDown()失效!!!
			// 失效onKeyDown()前先调用onScroll(null,1,0)可处理
			onScroll(null, null, 1, 0);
			onKeyDown(KeyEvent.KEYCODE_DPAD_RIGHT, null);
		}
	};
}

在此感谢MyPagerGalleryView控件的作者,让我们少做轮子~虽然我觉得造轮子是技术提升的一个重要手段。

4、Tab+Fragment+ViewPager的封装

未完待续…

曾经沧海难为水,除却巫山不是云。

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
MagicIndicator是一个强大的指示器库,可以帮助我们轻松地实现各种样式的ViewPager指示器。本文将介绍如何使用MagicIndicator打造千变万化的ViewPager指示器。 1. 引入依赖库 在app的build.gradle文件中添加以下依赖: ``` dependencies { implementation 'com.github.hackware1993:MagicIndicator:1.7.0' } ``` 2. 在布局文件中添加MagicIndicator 我们可以在布局文件中添加一个MagicIndicator作为ViewPager的指示器,例如: ``` <com.github.chenglei1986.navigationbarlib.MagicIndicator android:id="@+id/magic_indicator" android:layout_width="match_parent" android:layout_height="48dp"/> ``` 3. 创建ViewPager 我们需要创建一个ViewPager,并将其与MagicIndicator进行绑定。例如: ``` ViewPager viewPager = findViewById(R.id.view_pager); viewPager.setAdapter(adapter); MagicIndicator magicIndicator = findViewById(R.id.magic_indicator); magicIndicator.setNavigator(navigator); ViewPagerHelper.bind(magicIndicator, viewPager); ``` 在上面的代码中,我们创建了一个ViewPager,并将其与适配器进行绑定。然后,我们创建了一个MagicIndicator,并将其与ViewPager进行绑定。我们还使用ViewPagerHelper类来将MagicIndicator和ViewPager绑定在一起。 4. 创建导航器 导航器是用来控制ViewPager指示器的样式和行为的。我们可以使用CommonNavigator类来创建一个导航器,例如: ``` CommonNavigator navigator = new CommonNavigator(this); navigator.setAdapter(new CommonNavigatorAdapter() { @Override public int getCount() { return titles.length; } @Override public IPagerTitleView getTitleView(Context context, int index) { ColorTransitionPagerTitleView titleView = new ColorTransitionPagerTitleView(context); titleView.setNormalColor(Color.GRAY); titleView.setSelectedColor(Color.WHITE); titleView.setText(titles[index]); titleView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewPager.setCurrentItem(index); } }); return titleView; } @Override public IPagerIndicator getIndicator(Context context) { LinePagerIndicator indicator = new LinePagerIndicator(context); indicator.setColors(Color.WHITE); return indicator; } }); ``` 在上面的代码中,我们创建了一个CommonNavigator,并设置了它的适配器。适配器中,我们需要实现getCount方法返回指示器的数量,getTitleView方法返回每个指示器的视图,getIndicator方法返回指示器的样式。 在本例中,我们使用ColorTransitionPagerTitleView来创建指示器的视图,它可以在切换选中状态时自动进行颜色过渡。我们还使用LinePagerIndicator来创建指示器的样式,它是一条横线,颜色为白色。 5. 运行程序 现在,我们已经完成了MagicIndicator的设置,可以运行程序并查看效果。您可以尝试更改导航器的样式,例如更改指示器的颜色、大小和形状等,以实现不同的效果。 总结 在本文中,我们介绍了如何使用MagicIndicator打造千变万化的ViewPager指示器。通过使用MagicIndicator,我们可以轻松地创建不同样式的ViewPager指示器,从而提高用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值