【领券联盟】笔记:视频32,33,34,35-实现轮播图指示器及其联动
破小布的小花狗
发表于
2020-03-31 08:36
1629
课堂笔记
课堂笔记
编写轮播图指示器
- 用一个 LinearLayout 做所有指示器点的容器
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="125dp"
android:layout_marginBottom="14dp">
<androidx.viewpager.widget.ViewPager
android:id="@+id/looper_pager"
android:layout_width="match_parent"
android:layout_height="125dp"
android:overScrollMode="never" />
<LinearLayout
android:id="@+id/looper_point_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="10dp"
android:orientation="horizontal" />
</RelativeLayout>
- 绑定(找到)布局
@BindView(R.id.looper_point_container)
public LinearLayout looperPointContainer;
- 创建和轮播图个数相等的 view ,设置相关属性后添加到 looperPointContainer 中
@Override
public void onLooperListLoaded(List<HomePagerContent.DataBean> contents) {
mLooperPagerAdapter.setData(contents);
//清楚所有view
looperPointContainer.removeAllViews();
//单位转换,把px转dp
int size = SizeUtil.dip2px(getContext(), 8);
for (int i = 0; i < contents.size(); i++) {
//创建view
View point = new View(getContext());
//创建布局
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(size, size);
//给布局设置margin属性
layoutParams.leftMargin = SizeUtil.dip2px(getContext(), 5);
layoutParams.rightMargin = SizeUtil.dip2px(getContext(), 5);
//给view设置布局
point.setLayoutParams(layoutParams);
if (i == 0) {
point.setBackgroundResource(R.drawable.shape_indicator_point_selected);
} else {
point.setBackgroundResource(R.drawable.shape_indicator_point_normal);
}
looperPointContainer.addView(point);
}
}
- 其中单位转换工具类 SizeUtil
public class SizeUtil {
public static int dip2px(Context context, float dpValue) {
float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
}
轮播图无限轮转
- 并不是真无限轮转,把轮转的次数设置成 Integer.MAX_VALUE,做出伪无限轮转
- 这时 item 的个数也是 Integer.MAX_VALUE,所以要把 item 的索引对数据个数取模,得到真正的 position ,避免索引越界
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
int realPosition = position % mData.size();
HomePagerContent.DataBean dataBean = mData.get(realPosition);
......
}
- 设置轮播图的第一张图片为轮播图数据里的第一个
@Override
public void onLooperListLoaded(List<HomePagerContent.DataBean> contents) {
mLooperPagerAdapter.setData(contents);
//取模
int currentPosition = (Integer.MAX_VALUE / 2) % contents.size();
//减模,firstPosition 为 contents.size() 的整数倍,实现索引0开始
int firstPosition = Integer.MAX_VALUE / 2 - currentPosition;
looperPager.setCurrentItem(firstPosition);
......
}
轮播图和指示器的联动
- 在 BaseFragment 中 initView 后创建 initListener,HomePagerFragment 重写方法后给 looperPager 设置 addOnPageChangeListener 方法
@Override
protected void initListener() {
looperPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//对looper数据个数取模,得到真正的索引
int targetPosition = position % mLooperPagerAdapter.getDataSize();
updateLooperIndicator(targetPosition);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
- 其中 getDataSize 是在 LooperPagerAdapter 创建返回轮播图数据个数的方法
- 方法 updateLooperIndicator(targetPosition) 的实现
private void updateLooperIndicator(int targetPosition) {
for (int i = 0; i < looperPointContainer.getChildCount(); i++) {
//获取 View point
View point = looperPointContainer.getChildAt(i);
//根据位置设置背景颜色
if (i == targetPosition) {
point.setBackgroundResource(R.drawable.shape_indicator_point_selected);
} else {
point.setBackgroundResource(R.drawable.shape_indicator_point_normal);
}
}
}