轮播图大家用得很多了,经常使用viewpager+和几个圆点组成的布局,随意组合在一起就完成了,这样可以完成任务,但是我们是在使用服务器返回不定量图片数量的时候,就会和实际数据匹配不上了。
这里就用一个demo讲解灵活使用多张图片和对应的小圆点组成轮播的组件,以及小圆点跟着动的效果。啥都不说了,直接写代码:
布局文件:
<?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:background="#ffffff"
android:clipToPadding="false"
android:fitsSystemWindows="true"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v4.view.ViewPager
android:id="@+id/guide_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- 动态点的实现 -->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="25dp" >
<!-- 在底部添加静态点 的容器 -->
<LinearLayout
android:id="@+id/guide_point_cont"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
</LinearLayout>
<View
android:id="@+id/point_focus"
android:layout_width="10dp"
android:layout_height="10dp"
android:background="@drawable/dot_focused" />
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
主界面:
public class MainActivity extends FragmentActivity implements OnPageChangeListener {
private ViewPager viewpager;
private ArrayList<ImageView> guideList;
// 静态点容器
private LinearLayout point_container;
// 动态点
private View point_focus;
// 两个静态点之间的距离
int point_space;
private AutoSwitchPic autoSwitchPic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化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();
}
});
}
private void initData() {
guideList = new ArrayList<ImageView>();
int imageid[] = new int[] { R.drawable.img1, R.drawable.img2, R.drawable.img3, R.drawable.img4,
R.drawable.img5 };
ImageView iv;
View point;
//这里循坏用了5张图片,我所说的就是在这里要么网络请求数据获取多张图片然后循坏,添加到集合guidelist中来,对应的底部小圆点也是根据集合的数量来添加,从而灵活实现多张图片对应的小圆点活动。
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.dot_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 BannerAdapter(getApplicationContext(), guideList));
// 给viewpager设置监听
viewpager.setOnPageChangeListener(this);
// 开启轮播
if (autoSwitchPic == null) {
autoSwitchPic = new AutoSwitchPic(getApplicationContext(), viewpager, guideList);
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;
}
});
}
@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) {
// 滚动状态改变的时候调用的方法
}
}
后面是自动轮播的图片和适配器封装到两个类里面,代码看着更简洁。
package com.example.switchtabdemo;
import java.util.ArrayList;
import android.content.Context;
import android.os.Handler;
import android.support.v4.view.ViewPager;
import android.widget.ImageView;
public class AutoSwitchPic extends Handler implements Runnable {
private ArrayList<ImageView> list;
Context context;
ViewPager viewPager;
public AutoSwitchPic(Context applicationContext, ViewPager viewpager, ArrayList<ImageView> guideList) {
this.context = applicationContext;
this.viewPager = viewpager;
this.list = guideList;
}
public void start() {// 控制轮播的开始
stop();
// 发送一个延时执行的消息
postDelayed(this, 2000);
}
public void stop() {// 控制轮播的结束
// 从消息队列中移除消息
removeCallbacks(this);
}
@Override
public void run() {
// 获取当前的轮播位置
int position = viewPager.getCurrentItem();
if (position != list.size() - 1) {
// 设置接下来的轮播位置
viewPager.setCurrentItem(++position);
} else {
viewPager.setCurrentItem(0);
}
postDelayed(this, 2000);
}
}
Demo下载,点击此处