效果如下:
实现的大致原理:
- 根据轮播图的数量,动态添加小黑点。
- 小红点移动的距离,根据轮播图的移动距离实时改变
- 通过改变小红点的左边距达到移动的效果。
布局如下:
<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"
tools:context="com.itheima.carousel.MainActivity">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<!--底部小黑点和小红点-->
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp">
<!--小黑点的容器,动态添加-->
<LinearLayout
android:id="@+id/ll_dot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
<!--底部小红点-->
<ImageView
android:id="@+id/iv_red"
android:layout_width="@dimen/dot_size"
android:layout_height="@dimen/dot_size"
android:src="@drawable/dot_red" />
</RelativeLayout>
</RelativeLayout>
代码如下:
public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
int [] mIcons = {
R.drawable.guide_1,
R.drawable.guide_2,
R.drawable.guide_3
};
@Bind(R.id.viewpager)
ViewPager mViewpager;
@Bind(R.id.ll_dot)
LinearLayout mLlDot;
@Bind(R.id.iv_red)
ImageView mIvRed;
private List<ImageView> mList;
private int mPitch;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initData();
initListener();
}
private void initData() {
//初始化小圆点
initDot();
//初始化ViewPager的view集合
initPager();
MyPagerAdapter adapter = new MyPagerAdapter(mList);
mViewpager.setAdapter(adapter);
}
/**
* 处理监听事件
*/
private void initListener() {
//ViewPager的滑动监听
mViewpager.addOnPageChangeListener(this);
}
private List<ImageView> initPager() {
mList = new ArrayList<>();
for (int i = 0; i < mIcons.length; i++) {
ImageView iv = new ImageView(this);
iv.setImageResource(mIcons[i]);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
mList.add(iv);
}
return mList;
}
private void initDot() {
//屏幕适配,将dp值转换成Pixel值
int size = getResources().getDimensionPixelSize(R.dimen.dot_size);
//根据轮播图的数量添加小黑点
for (int i = 0; i < mIcons.length; i++) {
ImageView image = new ImageView(this);
image.setImageResource(R.drawable.dot_normal);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(size,size);
if (i!=0) {
//小黑点的间距
params.leftMargin = size;
}
image.setLayoutParams(params);
mLlDot.addView(image);
//当添加到第二个小黑点时,计算两个小黑点间的距离,为小红点的移动做准备
if (mLlDot.getChildCount()==2) {
mLlDot.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mPitch = mLlDot.getChildAt(1).getLeft()-mLlDot.getChildAt(0).getLeft();
mLlDot.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
}
}
}
/**
*通过轮播图移动的距离,来测算小红点移动的距离,并进行移动
*
* @param position 当前是第几个条目
* @param positionOffset 移动的距离的比值
* @param positionOffsetPixels 实际移动的像素点
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
int pixel = Math.round(mPitch*positionOffset)+position*mPitch;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mIvRed.getLayoutParams();
//通过改变小红点左边距,来移动小红点
params.leftMargin = pixel;
mIvRed.setLayoutParams(params);
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
}