Android自定义View七很low的bannerView.docx
《Android自定义View七很low的bannerView.docx》由会员分享,可在线阅读,更多相关《Android自定义View七很low的bannerView.docx(15页珍藏版)》请在冰豆网上搜索。
![Android自定义View七很low的bannerView.docx](https://file1.bdocx.com/fileroot1/2023-5/29/114a895c-426e-4eb3-a2c7-b178fe76a3cc/114a895c-426e-4eb3-a2c7-b178fe76a3cc1.gif)
Android自定义View七很low的bannerView
Android自定义View(七)--很low的bannerView
作为一个长期“拷贝”的程序猿,偶尔还是有点小失落的,偶尔也会有大神梦,即使那么遥不可及。
。
。
于是乎,在一个月黑风高的夜晚,有史以来最low的广告banner诞生了。
先谈谈整体的思路吧,看到有些大神用AdapterView实现的,而我这种渣,首先想到的就是viewpager,虽然viewpager没有那么完美,不过能勉强将就也还是极好的。
当然只有viewpager是不够的,还有viewpager上面的那几个小点点,这个我就更简单粗暴的用一个Layout装载了结果imageview,然后viewpager改变item的时候,改变小点点的图片就可以啦。
还有一个问题就是循环播放啦,这个就要从viewpager的adapter入手了,上网查了很多,得到的结论就是在adapter的getCount方法上做手脚,即返回一个很大的数,使viewpager的item数量大于你看到的实际数量,而多的item中显示与前面item相同的内容,这样看起来就是循环的啦。
剩下的要解决自动循环就更简单啦,管你用timer还是handler还是thread都可以简单搞定。
最后要解决的就是使这个东西用起来比较简单,所以我就简单的对它进行了一层小包装。
主要的视图类
packagecom.drivingassisstantHouse.library.widget.bannerview;
importandroid.content.Context;
importandroid.content.res.TypedArray;
importandroid.support.annotation.NonNull;
importandroid.support.v4.view.PagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.util.AttributeSet;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.animation.AccelerateInterpolator;
importandroid.view.animation.Interpolator;
importandroid.widget.ImageView;
importandroid.widget.LinearLayout;
importandroid.widget.RelativeLayout;
importandroid.widget.Scroller;
importcom.drivingassisstantHouse.library.R;
importcom.drivingassisstantHouse.library.tools.SLog;
importcom.drivingassisstantHouse.library.tools.ToolUnit;
importjava.lang.reflect.Field;
importjava.util.ArrayList;
/**
*包名:
com.drivingassisstantHouse.library.widget.bannerview
*描述:
广告banner
*创建者:
yankebin
*日期:
2016/2/27
*/
publicclassBannerViewextendsRelativeLayout{
publicstaticfinalintBANNER_TYPE_GUIDE=1;
publicstaticfinalintBANNER_TYPE_ADVERT=BANNER_TYPE_GUIDE+1;
protectedinttype=BANNER_TYPE_GUIDE;
privateBaseBannerViewpagerviewPager;
privateLinearLayoutindicator;
privatebooleanisAutoLoop=false;
privatelongloopDelayTime=4000;
privatelongscrollDuration=1200;
privateArrayListdots=newArrayList<>();
publicBannerView(Contextcontext){
super(context);
init();
}
publicBannerView(Contextcontext,AttributeSetattrs){
super(context,attrs);
TypedArraytypedArray=getContext().obtainStyledAttributes(attrs,R.styleable.BannerView);
type=typedArray.getInt(R.styleable.BannerView_bannerType,BANNER_TYPE_GUIDE);
isAutoLoop=typedArray.getBoolean(R.styleable.BannerView_autoPlay,false);
loopDelayTime=typedArray.getInt(R.styleable.BannerView_loopTime,4000);
scrollDuration=typedArray.getInt(R.styleable.BannerView_scrollDuration,1200);
if(null!
=typedArray){
typedArray.recycle();
}
init();
}
@Override
protectedvoidonVisibilityChanged(@NonNullViewchangedView,intvisibility){
super.onVisibilityChanged(changedView,visibility);
if(visibility!
=VISIBLE){
removeCallbacks(autoRunner);
}else{
if(isAutoLoop){
startAutoPlay();
}
}
}
privateRunnableautoRunner=newRunnable(){
@Override
publicvoidrun(){
if(!
isAutoLoop){
return;
}
intposition=viewPager.getCurrentItem();
viewPager.setCurrentItem(++position,true);
postDelayed(this,loopDelayTime);
}
};
privateRunnableindicatorRunner=newRunnable(){
@Override
publicvoidrun(){
intcurrentPosition=viewPager.getCurrentItem();
for(inti=0;iImageViewimageView=dots.get(i);
if(currentPosition%dots.size()==i){
imageView.setImageResource(R.drawable.banner_dot_shape_selected);
}else{
imageView.setImageResource(R.drawable.banner_dot_shape_normal);
}
}
}
};
publicvoidsetIsAutoLoop(booleanisLoop){
this.isAutoLoop=isLoop;
}
publicbooleanisAutoLoop(){
returnisAutoLoop;
}
publicvoidsetBannerAdapter(PagerAdapteradapter){
viewPager.setAdapter(adapter);
}
privatevoidinit(){
viewPager=newBaseBannerViewpager(getContext());
viewPager.setLayoutParams(newLayoutParams(-1,-1));
indicator=newLinearLayout(getContext());
LayoutParamsparams=newLayoutParams(-2,-2);
params.addRule(ALIGN_PARENT_BOTTOM);
params.addRule(CENTER_HORIZONTAL);
params.bottomMargin=10;
indicator.setLayoutParams(params);
indicator.setOrientation(LinearLayout.HORIZONTAL);
addView(viewPager);
addView(indicator);
initPagerListener();
}
privatevoidinitPagerListener(){
viewPager.addOnPageChangeListener(newViewPager.OnPageChangeListener(){
@Override
publicvoidonPageScrolled(intposition,floatpositionOffset,intpositionOffsetPixels){
}
@Override
publicvoidonPageSelected(intposition){
changeDotsColors();
}
@Override
publicvoidonPageScrollStateChanged(intstate){
}
});
}
privatevoidinitDots(intsize){
if(size<=0){
thrownewIllegalArgumentException("size必须大于0");
}
removeCallbacks(autoRunner);
dots.clear();
LinearLayout.LayoutParamspointViewParams=newLinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
pointViewParams.setMargins(ToolUnit.dipTopx(8),0,
ToolUnit.dipTopx(8),ToolUnit.dipTopx(8));
for(inti=0;iImageViewpointView=newImageView(getContext());
pointView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
pointView.setLayoutParams(pointViewParams);
dots.add(pointView);
indicator.addView(pointView);
}
changeDotsColors();
if(isAutoLoop){
startAutoPlay();
}
}
privatevoidstartAutoPlay(){
removeCallbacks(autoRunner);
postDelayed(autoRunner,loopDelayTime);
}
publicvoidchangeDotsColors(){
postDelayed(indicatorRunner,scrollDuration+500);
}
privateclassBaseBannerViewpagerextendsViewPager{
privateintchildId;
publicclassFixedSpeedScrollerextendsScroller{
privateintmDuration=(int)scrollDuration;
publicFixedSpeedScroller(Contextcontext){
super(context);
}
publicFixedSpeedScroller(Contextcontext,Interpolatorinterpolator){
super(context,interpolator);
}
@Override
publicvoidstartScroll(intstartX,intstartY,intdx,intdy,intduration){
//Ignorereceivedduration,usefixedoneinstead
super.startScroll(startX,startY,dx,dy,mDuration);
}
@Override
publicvoidstartScroll(intstartX,intstartY,intdx,intdy){
//Ignorereceivedduration,usefixedoneinstead
super.startScroll(startX,startY,dx,dy,mDuration);
}
publicvoidsetmDuration(inttime){
mDuration=time;
}
publicintgetmDuration(){
returnmDuration;
}
}
publicBaseBannerViewpager(Contextcontext){
super(context);
resetScroller(context);
}
publicBaseBannerViewpager(Contextcontext,AttributeSetattrs){
super(context,attrs);
resetScroller(context);
}
privatevoidresetScroller(Contextcontext){
try{
Fieldfield=ViewPager.class.getDeclaredField("mScroller");
field.setAccessible(rue);
FixedSpeedScrollerscroller=newFixedSpeedScroller(context,
newAccelerateInterpolator());
field.set(this,scroller);
}catch(Exceptione){
SLog.e(e);
}
}
@Override
publicbooleanonInterceptTouchEvent(MotionEventevent){
if(childId>0){
ViewPagerpager=(ViewPager)findViewById(childId);
if(pager!
=null){
pager.requestDisallowInterceptTouchEvent(true);
}
}
returnsuper.onInterceptTouchEvent(event);
}
publicvoidsetAllowChildMovement(intid){
this.childId=id;
}
@Override
publicvoidsetAdapter(PagerAdapteradapter){
initDots(((BaseBannerPagerAdapter)adapter).getRealCount());
super.setAdapter(adapter);
}
}
}
viewpager的adapter
packagecom.drivingassisstantHouse.library.widget.bannerview;
importandroid.util.SparseArray;
importandroid.view.View;
importandroid.view.ViewGroup;
importjava.util.ArrayList;
/**
*包名:
com.simpletour.client.activity
*描述:
banner适配器
*创建者:
yankebin
*日期:
2016/2/27
*/
publicabstractclassBaseBannerPagerAdapterextendsandroid.support.v4.view.PagerAdapter{
protectedSparseArrayviews=newSparseArray<>();
privatebooleanisLoop;
protectedArrayListdatas;
publicBaseBannerPagerAdapter(){
datas=newArrayList<>();
}
publicBaseBannerPagerAdapter(ArrayListdatas){
this.datas=datas;
}
@Override
publicfinalintgetCount(){
returnisLoop?
Integer.MAX_VALUE:
datas.size();
}
@Override
publicObjectinstantiateItem(ViewGroupcontainer,intposition){
position=position%datas.size();
Viewview=views.get(position);
if(view==null){
view=newView(position%getCount());
views.put(position,view);
}
container.addView(view);
returnview;
}
publicvoidnotifyUpdateView(intposition){
Viewview=updateView(views.get(position),position);
views.put(ition,view);
notifyDataSetChanged();
}
publicViewupdateView(Viewview,intposition){
returnview;
}
publicabstractViewnewView(intposition);
publicfinalintgetRealCount(){
returndatas.size();
}
publicvoidsubscribe(BannerViewbannerView){
isLoop=bannerView.isAutoLoop()||bannerView.type==BannerView.BANNER_TYPE_ADVERT;
bannerView.setBannerAdapter(this);
}
}
一些自定义属性
代码里调用
首先定义好xml文件
android:
orientation="vertical"
android:
layout_width="match_parent"
android:
layout_height="match_parent">
android:
layout_weight="1"
banner:
autoPlay="true"
banner:
loopTime="3000"
banner:
bannerType="typeAdvert"
banner:
scrollDuration="800"
android:
id="@+id/bannerView"
android:
layout_width="match_parent"
android:
layout_height="0dp">