项目大版本更新,设计给了新的效果图,其中banner换成了如下图所示。两头都要留一点出来。哈罗单车也有类似的banner。可以设置中间的图片比两边大。
大概构思:自定义FrameLayout,然后轮播图和指示器(就是小圆点)都用RecyclerView实现。
文字能力太差,还是上代码吧。
1.自定义属性
<declare-styleable name="BannerLayout">
<attr name="interval"/>
<attr name="showIndicator"/>
<attr name="orientation"/>
<attr name="autoPlaying"/>
<attr name="itemSpace" format="integer"/>
<attr name="centerScale" format="float"/>
<attr name="moveSpeed" format="float"/>
</declare-styleable>
interval:自动轮播的间隔时间。
showIndicator:是否显示指示器小圆点。
orientation:轮播方向(水平、竖直)。
autoPlaying:是否自动轮播。
itemSpace:两个banner之间的间距
centerScale:中间banner的倍数(设置为1.0就是一样大)。
moveSpeed:轮播图的移动速度。
2.初始化属性。
public class BannerLayout extends FrameLayout {
//省略部分代码
public BannerLayout(Context context) {
this(context, null);
}
public BannerLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BannerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context, attrs);
}
private void initView(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.BannerLayout);
showIndicator = typedArray.getBoolean(R.styleable.BannerLayout_showIndicator, true);
autoPlayDuration = typedArray.getInt(R.styleable.BannerLayout_interval, 4000);
isAutoPlaying = typedArray.getBoolean(R.styleable.BannerLayout_autoPlaying, true);
itemSpace = typedArray.getInt(R.styleable.BannerLayout_itemSpace, 30);
//设置为1.0就是两边的图跟中间的一样高度,设置1.2就是两边的图比中间的图小一点
centerScale = typedArray.getFloat(R.styleable.BannerLayout_centerScale, 1.2f);
moveSpeed = typedArray.getFloat(R.styleable.BannerLayout_moveSpeed, 1.0f);
}
}
3.绘制小圆点
if (mSelectedDrawable == null) {
//绘制默认选中状态图形
GradientDrawable selectedGradientDrawable = new GradientDrawable();
selectedGradientDrawable.setShape(GradientDrawable.OVAL);
selectedGradientDrawable.setColor(Color.RED);
selectedGradientDrawable.setSize(dp2px(5), dp2px(5));
selectedGradientDrawable.setCornerRadius(dp2px(5) / 2);
mSelectedDrawable = new LayerDrawable(new Drawable[]{selectedGradientDrawable});
}
if (mUnselectedDrawable == null) {
//绘制默认未选中状态图形
GradientDrawable unSelectedGradientDrawable = new GradientDrawable();
unSelectedGradientDrawable.setShape(GradientDrawable.OVAL);
unSelectedGradientDrawable.setColor(Color.GRAY);
unSelectedGradientDrawable.setSize(dp2px(5), dp2px(5));
unSelectedGradientDrawable.setCornerRadius(dp2px(5) / 2);
mUnselectedDrawable = new LayerDrawable(new Drawable[]{unSelectedGradientDrawable});
}
4.轮播图与指示器
//轮播图部分
mRecyclerView = new RecyclerView(context);
LayoutParams vpLayoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
addView(mRecyclerView, vpLayoutParams);
mLayoutManager = new BannerLayoutManager(getContext(), orientation);
mLayoutManager.setItemSpace(itemSpace);
mLayoutManager.setCenterScale(centerScale);
mLayoutManager.setMoveSpeed(moveSpeed);
mRecyclerView.setLayoutManager(mLayoutManager);
new CenterSnapHelper().attachToRecyclerView(mRecyclerView);
//指示器部分
indicatorContainer = new RecyclerView(context);
LinearLayoutManager indicatorLayoutManager = new LinearLayoutManager(context, orientation, false);
indicatorContainer.setLayoutManager(indicatorLayoutManager);
indicatorAdapter = new IndicatorAdapter();
indicatorContainer.setAdapter(indicatorAdapter);
LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.BOTTOM | gravity;
params.setMargins(marginLeft, 0, marginRight, marginBottom);
addView(indicatorContainer, params);
if (!showIndicator) {
indicatorContainer.setVisibility(GONE);
}
5.轮播图小圆点的适配器
protected class IndicatorAdapter extends RecyclerView.Adapter {
int currentPosition = 0;
public void setPosition(int currentPosition) {
this.currentPosition = currentPosition;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ImageView bannerPoint = new ImageView(getContext());
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
lp.setMargins(indicatorMargin, indicatorMargin, indicatorMargin, indicatorMargin);
bannerPoint.setLayoutParams(lp);
return new RecyclerView.ViewHolder(bannerPoint) {
};
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ImageView bannerPoint = (ImageView) holder.itemView;
bannerPoint.setImageDrawable(currentPosition == position ? mSelectedDrawable : mUnselectedDrawable);
}
@Override
public int getItemCount() {
return bannerSize;
}
}
6.测试的demo(后续会放到百度网盘供下载查看)
链接:https://pan.baidu.com/s/1mH8KxWCWYv8DDGgB3qfmJg 密码:2eig