在Android开发时,广告轮播我的项目是使用的ConvenientBanner 来实现的,效果也很好。但是有一个很严格的设计师,需要完全按照她的设计来实现,突然发现ConvenientBanner 实现的指示器,不能修改bottomMargin,leftMargin
,,而且也不能设置Indicator的大小
。只能使用默认的。
实现原理:
自定义Indicator --->隐藏ConvenientBanner的默认Indicator-->通过ConvenientBanner的滚动监听方法来联动广告图片和Indicator
那么是不是我们需要更换框架,我是很不愿意的。然后查看ConvenientBanner 是不是有监听滚动的方法,一查果然有。
setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
LogUtils.e("onPageSelected==" + position);
//在这里面设置选中的Indicator
indicatorView.setSelectIndex(position%banners.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
既然有这个方法,就容易实现需求,自定义一个IndicatorView,通过ConvenientBanner滚动监听方法,不断的设置选中的指示器和未选中的指示器。
该自定义的控件需要具有设置指示器个数
和设置当前选中的指示器
的方法
同时,还需要拥有属性如下
在values/attrs下创建这些属性。
<declare-styleable name="IndictorView">
<attr name="indicator_count" format="integer|reference"/>
<attr name="indicator_s_resid" format="reference"/>
<attr name="indicator_n_resid" format="reference"/>
<attr name="indicator_width" format="dimension|reference"/>
<attr name="indicator_height" format="dimension|reference"/>
<attr name="indicator_margin_left" format="dimension|reference"/>
declare-styleable>
public class IndictorView extends LinearLayout {
private Context context;
private View view;
private LinearLayout layout;
//这些属性全部变为自定义属性
private int count = 0;//指示器的数量
private int selectIndicatorResid = R.drawable.ic_indicator_circle_s;//选中时候的图片
private int noSelectIndicatorResid = R.drawable.ic_indicator_circle_n; //未选中的时候的图片
private int indicatorWidhtDp;//指示器的宽
private int indicatorWidhtDp_default = 7; //指示器默认的宽 dp
private int indictorHeightDp;//指示器的高
private int indictorHeightDp_default = 7;//指示器默认的高 dp
private int indicatorMarginLeft; //指示器MarginLeft
private int indicatorMarginLeft_default = 3;
private int beforeSelectIndex=0;
public IndictorView(Context context) {
super(context, null);
LogUtils.e("count=" + count);
this.context = context;
}
public IndictorView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
this.context = context;
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.IndicatorView);
count = array.getInteger(count, R.styleable.IndicatorView_indicator_count);
selectIndicatorResid = array.getResourceId(R.styleable.IndicatorView_indicator_s_resid, R.drawable.ic_indicator_circle_s);
noSelectIndicatorResid = array.getResourceId(R.styleable.IndicatorView_indicator_n_resid, R.drawable.ic_indicator_circle_n);
indicatorWidhtDp = array.getDimensionPixelSize(R.styleable.IndicatorView_indicator_width, DisplayUtils.dp2px(context, inidicatorWidhtDp_default));
indictorHeightDp = array.getDimensionPixelSize(R.styleable.IndicatorView_indicator_width, DisplayUtils.dp2px(context, inidictorHeightDp_default));
indicatorMarginLeft = array.getDimensionPixelOffset(R.styleable.IndictorView_indicator_margin_left, DisplayUtils.dp2px(context, inidicatorMarginLeft_default));
array.recycle();
initViews();
}
public IndictorView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
}
private void initViews() {
view = LayoutInflater.from(context).inflate(R.layout.widget_indicator, this);
layout = (LinearLayout) view.findViewById(R.id.widget_indicator_layout);
if (count != 0) {
setIndicatorsSize(count);
}
}
public void setIndicatorsSize(int count) {
for (int i = 0; i < count; i++) {
ImageView imageView = new ImageView(context);
imageView.setImageResource(selectIndicatorResid);
layout.addView(imageView);
LinearLayout.LayoutParams params = (LayoutParams) imageView.getLayoutParams();
params.height = indicatorWidhtDp;
params.width = indictorHeightDp;
//第一个不需要margin
if (i != 0) {
params.leftMargin = indicatorMarginLeft;
imageView.setImageResource(noSelectIndicatorResid);
}
imageView.setLayoutParams(params);
}
}
/**
* 设置选中的indicator
*
* @param index
*/
public void setSelectIndex(int index) {
ImageView imageViewbefore= (ImageView) layout.getChildAt(beforeSelectIndex);
ImageView imageViewCureent= (ImageView)layout.getChildAt(index);
if (null!=imageViewbefore)
imageViewbefore.setImageResource(noSelectIndicatorResid);
if (null!=imageViewCureent)
imageViewCureent.setImageResource(selectIndicatorResid);
beforeSelectIndex=index;
}
}
"match_parent"
android:layout_height="@dimen/y300">
<com.bigkoo.convenientbanner.ConvenientBanner
android:id="@+id/acty_main_cbanner"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.aoben.qproj.widget.IndicatorView
android:id="@+id/acty_main_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
app:indicator_height="@dimen/y14"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/y20"
app:indicator_margin_left="@dimen/x7"
app:indicator_n_resid="@drawable/ic_indicator_circle_n"
app:indicator_s_resid="@drawable/ic_indicator_circle_s"
app:indicator_width="@dimen/y14" />
使用RelayoutLayout 来设置ConvenientBanner 和IndicatorView 对应的位置
这里x7、y14 这是因为屏幕适配时使用,大家可以使用对应的dp来设置。
indicatorView.setIndicatorsSize(banners.size());
cBanner.setPages(new CBViewHolderCreator() {
@Override
public NetworkImageHolderView createHolder() {
return new NetworkImageHolderView();
}
}, banners)
.setPointViewVisible(false)//设置指示器是否可见
.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(int position) {
//dosomething
}
}).setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
LogUtils.e("onPageSelected==" + position);
//在这里面设置选中的Indicator
indictorView.setSelectIndex(position%banners.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
});//设置指示器的方向(左、中、右)
if (!cBanner.isTurning()) {
cBanner.startTurning(2000);
}
这样我们就可以使用ConvenientBanner设定Indicator 的位置,大小,margin.
Demo github地址