viewpager实现图片轮播+小圆点跟着动

时间:2021-03-19 20:44:15

一、ViewPager简单用法

ViewPager的简单用法:

在布局文件中引入ViewPager,不记得完整的名称的话可以直接到support.v4.view包下找到ViewPager然后copy它的全路径名。

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

java代码中为ViewPager设置适配数据:设置list数据,设置adapteradapter要继承PagerAdapter,重写adaptergetCount()isViewFromObject(),instantiateItem(),destroyItem()四个方法。

private ArrayList<ImageView> guideList;
guideList=new ArrayList<ImageView>();
int imageid[]=new int []{
R.drawable.guide_1,
R.drawable.guide_2,
R.drawable.guide_3
};
ImageView iv;
for(int i=0;i<imageid.length;i++){
iv=new ImageView(this);
//设置图片资源
iv.setImageResource(imageid[i]);
//设置填充
iv.setScaleType(ScaleType.FIT_XY);
guideList.add(iv);
//给viewpager设置数据
viewpager.setAdapter(new guideAdapter());
class guideAdapter extends PagerAdapter{
@Override
public int getCount() {
if (guideList!=null) {
return guideList.size();
}
return 0;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//1.获取imageview
ImageView iv=guideList.get(position);
//2.把imageview添加到viewpager
container.addView(iv);
//3.返回imageview
return iv;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}

二、点的动画移动

1.首先从布局上分析点的动画移动:

RelativeLayout位于父组件的底部,中间。里面有一个LinearLayout子控件水平摆放用于盛放静态的点,还有一个动态的View可以在代码中动态的设置它的MarginLeft属性来实现动画效果,并且移动到某个位置要遮盖掉LinearLayout里的静态点。

页面布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<android.support.v4.view.ViewPager
android:id="@+id/guide_viewpager"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
<!-- 动态点的实现 -->
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="25dp"
>
<!-- 在底部添加静态点 的容器-->
<LinearLayout
android:id="@+id/guide_point_cont"
android:orientation="horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
></LinearLayout>
<View
android:id="@+id/point_focus"
android:layout_height="10dp"
android:layout_width="10dp"
android:background="@drawable/guide_point_focus" />
</RelativeLayout>
</RelativeLayout>

2.具体动画的实现逻辑,两个重点:测量----监听静态点容器布局是否完成,布局完成之后测量两个孩子的左边距之间的距离;监听---这里的监听是指监听ViewPageritem的滑动,根据ViewPageritem的滑动距离设置动态点的左边距。

完整代码如下:

public class GuideUI extends Activity implements OnPageChangeListener,OnClickListener{
private ViewPager viewpager;
private ArrayList<ImageView> guideList;
//静态点容器
private LinearLayout point_container;
//动态点
private View point_focus;
//两个静态点之间的距离
int point_space;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.guide);
//初始化wiew
initView();
//初始化数据
initData();

}

private void initView() {
viewpager=(ViewPager) findViewById(R.id.guide_viewpager);
point_container=(LinearLayout) findViewById(R.id.guide_point_cont);
point_focus=findViewById(R.id.point_focus);
point_container.getViewTreeObserver().//监听布局完成
addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

@Override
public void onGlobalLayout() {
point_container.getViewTreeObserver().
removeGlobalOnLayoutListener(this);
//测量两个子类组件之间的距离
point_space=point_container.getChildAt(1).getLeft()
-point_container.getChildAt(0).getLeft();

}
});
guide_start.setOnClickListener(this);
}
private void initData() {
guideList=new ArrayList<ImageView>();
int imageid[]=new int []{
R.drawable.guide_1,
R.drawable.guide_2,
R.drawable.guide_3
};
ImageView iv;
View point;
for(int i=0;i<imageid.length;i++){
iv=new ImageView(this);
//设置图片资源
iv.setImageResource(imageid[i]);
//设置填充
iv.setScaleType(ScaleType.FIT_XY);
guideList.add(iv);
//设置底部静态点
point=new View(this);
point.setBackgroundResource(R.drawable.guide_point_normal);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(30, 30);
if (i!=0) {
//这里的数值单位是px
params.leftMargin=20;
}
point_container.addView(point,params);
}
//给viewpager设置数据
viewpager.setAdapter(new guideAdapter());
//给viewpager设置监听
viewpager.setOnPageChangeListener(this);
}
class guideAdapter extends PagerAdapter{
@Override
public int getCount() {
if (guideList!=null) {
return guideList.size();
}
return 0;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
//1.获取imageview
ImageView iv=guideList.get(position);
//2.把imageview添加到viewpager
container.addView(iv);
//3.返回imageview
return iv;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {//positionOffset:滑动的百分比,滑动的距离/父容器的宽度,positionOffsetPixels:滑动的像素点
//viewpager正在滚动时调用的方法
int marginLeft=(int) (positionOffset*point_space+point_space*position+0.5f);
RelativeLayout.LayoutParams params=(android.widget.RelativeLayout.LayoutParams) point_focus.getLayoutParams();
params.leftMargin=marginLeft;
point_focus.setLayoutParams(params);
}

@Override
public void onPageSelected(int position) {
//viewpager被选中的时候调用的方法
}

@Override
public void onPageScrollStateChanged(int state) {
// 滚动状态改变的时候调用的方法

}
}

好了通过上面的的操作我们可以在滑动切换viewpager的图片的时候让下边的红色小圆点也跟着滑动(有在两个非选中点之间移动的过程)。

三、viewpager的自动轮播

轮播的逻辑:

class AutoSwitchPic extends Handler implements Runnable{
public void start() {//控制轮播的开始
stop();
//发送一个延时执行的消息
postDelayed(this, 2000);
}
public void stop() {//控制轮播的结束
//从消息队列中移除消息
removeCallbacks(this);
}
@Override
public void run() {
//获取当前的轮播位置
int position=viewpager.getCurrentItem();
if (position!=guideList.size()-1) {
//设置接下来的轮播位置
viewpager.setCurrentItem(++position);
}
else{
viewpager.setCurrentItem(0);
}
postDelayed(this, 2000);
}
}

在需要开启轮播的地方写:

private AutoSwitchPic autoSwitchPic;
if (autoSwitchPic==null) {
autoSwitchPic=new AutoSwitchPic();
autoSwitchPic.start();
}

对于轮播过程中viewpager触摸事件的处理:

viewpager.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
autoSwitchPic.stop();
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
autoSwitchPic.start();
break;
default:
break;
}
return false;
}
});