大佬教程收集整理的这篇文章主要介绍了Android组件banner实现左右滑屏效果,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
什么是bAnner组件?在许多Android应用上,比如爱奇艺客户端、百度美拍、应用宝等上面,都有一个可以手动滑动的小广告条,这就是bAnner,实际应用中的bAnner,其信息(图片和点击行为)是后台可配置的,是需要通过网络从后台拉取的。网上有许多手动滑屏的例子,但是一般只是个demo,无法在实际中使用,因为其一般没有考虑如下几类问题:图片缓存、OOM问题、是否可灵活配置、是否预留外部接口以及是否封装良好。没有良好的封装,手动滑屏加在代码中,会使得代码变得很烂很脆弱。
1.原理
参见下图。整个组件是一个FrameLayout,里面有两个view,第一个是LinearLayout,承载了4个(或多个)可以滑动的view,见图中绿色背景的部分;第二个是一个RelativeLayout,在其底部放置了一个LinearLayout,在LinearLayout的内部放置了若干个小圆点,用来指示当前屏幕的索引。手势检测用了GestureDetector,并实现了OnGestureListener接口。为了能控制滑动速度,采用了Scroller弹性滑动对象。
为什么组件继承FrameLayout,是因为用于指示的小圆点是出现在view上面的,一个view叠在另一个view上面,这就是FrameLayout的特性
2.功能、效果
bAnner属性可动态设置,默认数量为4,可以调整默认的数量
bAnner信息从后台获取,bAnner的条数就是屏幕的数量
可自动滑动也能手动滑动
图片下载为多线程,并采用常见的三级cache策略(内存、文件、网络),节省流量,并处理了OOM异常
内部处理点击事件,同时预留出了接口函数
bAnner封装成一个ViewGroup类,使用起来简单,最少只需要两行代码
3.代码
代码注释写的比较详细,应该很好理解。分为2个文件,一个是bAnner的类,另一个是接口声明。
ScrollBAnner.java
/** * ScrollBAnner 支持滑屏效果的FrameLayout子类,可设置屏幕数量,尺寸。<br/> * 典型的用法:<br/> * ScrollBAnner scrollBAnner = new ScrollBAnner(this,mScreenWidth,100,this);<br/> * linearLayout.addView(scrollBAnner);<br/> *注意事项:<br/> *1.如果重新设置ScrollBAnner的LayoutParams,则参数中的宽和高属性将被忽略,仍然采用对象实例化的宽和高<br/> *2.点击事件的回调如果设为null,则采用默认的事件回调<br/> *3.通过setOverScrollmode来设置 bAnner是否能够滑出屏幕的边界<br/> *4通过xml方式加载bAnner,需要进行如下调用:<br/> * setResolution(width,height);<br/> setOnBAnnerClickListener(bAnnerClickListener);<br/> showBAnner()<br/> * @author singwhatiwAnna * @version 2013.3.4 * */ public class ScrollBAnner extends FrameLayout implements ComponentCallBACk.onBAnnerClickListener,ResponseHandler.bAnnerInfoHandler { private static final String TAG = "ScrollBAnner"; private @L_673_43@Ex m@L_673_43@Ex; //ScrollBAnner的子view private LinearLayout linearLayoutScrolLayout; //linearLayoutScrolLayout的子view,用于放置若干个小圆点 private LinearLayout linearLayoutForDot; private Scroller mScroller; private Context mContext; private OnBAnnerClickListener mBAnnerClickListener; //屏幕及其bitmap private List<View> mLinearLayoutScreens = new ArrayList<View>(); private List<Bitmap> mBAnnerBitmaps = new ArrayList<Bitmap>(); //bAnner信息 private List<BAnnerItem> mBAnnerItemsList = new ArrayList<BAnnerItem>(); //小圆点 private List<ImageView> mImageViewList = new ArrayList<ImageView>(); private Drawable mPageInDicator; private Drawable mPageInDicatorFocused; //bAnner默认图片 private Bitmap mDefaultBitmap; privatE int mScreenWidth; privatE int mScreenHeight; privatE int mScrollX; //current screen index privatE int mWhich = 0; public static final int messaGE_AUTO_SCROLL = 1; public static final int messaGE_FETCH_BAnnER_succesS = 2; public static final int MARGIN_BOTTOM = 2; //480*150 bAnner的图片尺寸 150.0/480=0.3125f public static final float ratio = 0.3125f; //bAnner的位置 privatE int mLOCATIOn = -1; //bAnner分为几屏 privatE int PAGE_COUNT = 4; //滑动方向 是否向右滑动 private Boolean mScrollToRight = true; //是否自动滑屏 private Boolean mTimerResume = true; //标志用户是否手动滑动了屏幕 private Boolean mByUserAction = false; //标志bAnner是否可以滑出边界 private Boolean mOverScrollmode = false; //标志bAnner可以滑出边界多少像素 privatE int mOverScrollDistance = 0; //定时器 用于bAnner的自动播放 final Timer timer = new Timer(); //定时器的时间间隔 单位:ms public static final int TIMER_DURATION = 5000; private TimerTask mTimerTask = new TimerTask() { @Override public void run() { if (mTimerResume && !mByUserAction) { mHandler.sendEmptymessage(messaGE_AUTO_SCROLL); } mByUserAction = false; } }; //ScrollBAnner私有handler 用于处理内部逻辑 private Handler mHandler = new Handler() { public void handlemessage(message msg) { //表示已经执行了onDetachedFromWindow,bAnner已经被销毁了 if( mBAnnerBitmaps == null || mLinearLayoutScreens == null || mImageViewList == null || mBAnnerItemsList == null || mContext == null ) return; switch (msg.what) { case messaGE_AUTO_SCROLL: if (mWhich == PAGE_COUNT - 1) mScrollToRight = false; else if(mWhich == 0) { mScrollToRight = true; } if (mScrollToRight) mWhich++; else { mWhich--; } m@L_673_43@Ex.switchView(mWhich); break; case messaGE_FETCH_BAnnER_succesS: int more = 0; if(mBAnnerItemsList != null) more = mBAnnerItemsList.size() - PAGE_COUNT; if(mBAnnerItemsList.size() > 0) { //如果有bAnner 显示它 ScrollBAnner.this.show(true); } //如果后台返回的bAnneritem的数量大于预设值4 if(more > 0) { for (int i = 0; i < more; i++) addBAnnerItem(); } fetchBAnnerImages(); break; default: break; } }; }; //用于获取bitmap private Handler mBitmapHandler = new Handler() { public void handlemessage(message msg) { //表示已经执行了onDetachedFromWindow,bAnner已经被销毁了 if( mBAnnerBitmaps == null || mLinearLayoutScreens == null || mImageViewList == null || mBAnnerItemsList == null || mContext == null ) return; Bitmap bitmap = (Bitmap)msg.obj; String urlString = msg.getData().getString("url"); Logger.d(tag,"url=" + urlString); if (urlString == null || bitmap == null || mBAnnerItemsList == null) { Logger.w(tag,"bitmap=null imgurl=" + urlString); return; } for( int i = 0; i < mBAnnerItemsList.size(); i++ ) { BAnnerItem item = mBAnnerItemsList.get(i); if(item != null && urlString.equals(item.imgurl) ) { Logger.d(tag,"find " + i + urlString); if( mBAnnerBitmaps != null ) { mBAnnerBitmaps.set( i,bitmap ); setBAnnerImages(i); } break; } } }; }; public ScrollBAnner(Context context) { this(context,null); } public ScrollBAnner(Context context,AttributeSet attrs) { super(context,attrs); mContext = context; } public ScrollBAnner(Context context,AttributeSet attrs,int defStylE) { super(context,attrs,defStylE); mContext = context; } /** * * @param context activity实例 * @param width bAnner的宽度 单位px * @param height bAnner的高度 单位dip,-1表示根据图片比例自适应高度 * @param bAnnerClickListener 单击bAnner的回调接口 */ public ScrollBAnner(Context context,final int width,final int height,OnBAnnerClickListener bAnnerClickListener) { this(context,null); int activityId = ( (BaseActivity)context ).activityId(); if(activityId == BaseActivity.account_ID)//位置3 mLOCATIOn = 3; else if(activityId == BaseActivity.GAMEZONE_ID)//位置2 { mLOCATIOn = 2; } //初始化时不显示bAnner this.show(false); setResolution(width,height); setOnBAnnerClickListener(bAnnerClickListener); setDefaultBAnnerImages(); fetchBAnnerInfo(); } /** * 通过xml方式加载bAnner,必须调用此方法才能显示 */ public void showBAnner() { int activityId = ( (BaseActivity)mContext ).activityId(); if(activityId == BaseActivity.account_ID)//位置3 mLOCATIOn = 3; else if(activityId == BaseActivity.GAMEZONE_ID)//位置2 { mLOCATIOn = 2; } setDefaultBAnnerImages(); fetchBAnnerInfo(); } /** * 暂停滚动 */ public void pauseScroll() { mTimerResume = false; } /** * 恢复滚动 */ public void resumeScroll() { mTimerResume = true; } /** * 设置回调接口 * @param callBACk 单击bAnner的回调接口 */ public void setOnBAnnerClickListener(OnBAnnerClickListener bAnnerClickListener) { mBAnnerClickListener = (bAnnerClickListener != null ? bAnnerClickListener : ScrollBAnner.this); } /** * 设置bAnner的解析度 * @param width bAnner的宽度 * @param height bAnner的高度 */ public void setResolution(final int width,final int height) { int heighTinPx = height; if(height == -1) heighTinPx = (int)(ratio * width) ; else { resources resources = getresources(); heighTinPx = Math.round( TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,height,resources.getDisplaymetrics()) ); } mScreenWidth = width; mScreenHeight = heighTinPx; setLayoutParams(new LayoutParams(width,heighTinPX)); initScrollView(); } /** * 获取bAnner的高度 * @return bAnner的高度 单位:px */ public int getHeightPixels() { return mScreenHeight; } /** * 设置bAnner是否可以弹性滑出边界 * @param canOverScroll true表示可以滑出边界,false不能 */ public void setOverScrollmode(Boolean canOverScroll) { mOverScrollmode = canOverScroll; if(canOverScroll == falsE) mOverScrollDistance = 0; } /** * 向后台获取bAnner的各种信息 */ private void fetchBAnnerInfo() { NetworkManager netManager = (NetworkManager) AppENGIne.geTinstance().getManager( IManager.NETWORK_ID); netManager.getBAnnerInfo( String.valueOf(mLOCATIOn),ScrollBAnner.this ); } /** * 获取bAnner的滑屏图像 */ private void setDefaultBAnnerImages() { //为bAnner设置默认bitmap BitmapFactory.options bitmapFactoryOptions = new BitmapFactory.options(); bitmapFactoryOptions.inJustDecodeBounds = false; bitmapFactoryOptions.inSampleSize = 2; resources res=mContext.getresources(); mDefaultBitmap = BitmapFactory.decoderesource(res,R.drawable.bAnner_image_default,bitmapFactoryOptions); for(int i = 0; i < PAGE_COUNT; i++) mBAnnerBitmaps.add(i,mDefaultBitmap); //初始化BAnnerItem对象 for (int i = 0; i < PAGE_COUNT; i++) mBAnnerItemsList.add(i,null); setBAnnerImages(-1); } private void fetchBAnnerImages() { //表示已经执行了onDetachedFromWindow,bAnner已经被销毁了 if( mBAnnerItemsList == null ) return; //ImageManager 根据url向其获取bitmap ImageManager imageManager = (ImageManager)AppENGIne.geTinstance(). getManager(IManager.IMAGE_ID); BAnnerItem item = null; for(int i = 0; i < PAGE_COUNT; i++) { try { item = mBAnnerItemsList.get(i); } catch (indexoutofboundsexception E) { Logger.e(tag,"fetchBAnnerImages error: " + E); } catch (Exception E) { Logger.e(tag,"fetchBAnnerImages error: " + E); } //ImageManager为多线程,采用常见的三级cache策略(内存、文件、网络) if( item != null && item.imgurl != null ) imageManager.loadBitmap( item.imgurl,mBitmapHandler ); } } /** * 设置bAnner的滑屏图像 * @param position 如果position=-1,则表示设置全部bitmap */ private void setBAnnerImages(final int position) { int size = mBAnnerBitmaps.size(); if (size < PAGE_COUNT || mLinearLayoutScreens == null) { return; } if(position >=0 && position < PAGE_COUNT ) { Drawable drawable = mLinearLayoutScreens.get(position).getBACkground(); mLinearLayoutScreens.get(position).setBACkgroundDrawable (new BitmapDrawable( mBAnnerBitmaps.get(position) ) ); drawable.setCallBACk(null); drawable = null; return; } for(int i = 0; i < PAGE_COUNT; i++) { mLinearLayoutScreens.get(i).setBACkgroundDrawable(new BitmapDrawable(mBAnnerBitmaps.get(i))); } } /** * 是否显示bAnner * @param isShow true显示 false不显示 */ public void show(Boolean isShow) { if(isShow) { this.setVisibility(View.VISIBLE); mTimerResume = true; } else { this.setVisibility(View.GONE); mTimerResume = false; } } /** * 切换到指定屏幕 * @param which 屏幕索引 */ public void switchToScreen(final int which) { m@L_673_43@Ex.switchView(which); } /** * 设置屏幕的数量 (此函数暂不开放) * @param count 屏幕数量 */ protected void setScreenCount(final int count) { PAGE_COUNT = count; } /** * 设置偏移的距离 如果mOverScrollmode为false,则此设置无效 (此函数暂不开放) * @param distance */ protected void setOverScrollDistance(int distancE) { if(distance < 0) distance = 0; mOverScrollDistance = mOverScrollmode ? distance : 0; } /** * 切换小圆点 * @param position current screen index */ private void switchScreenPosition(final int position) { if( mPageInDicator == null || mPageInDicatorFocused == null ) return; int length = 0; if(mImageViewList != null) length = mImageViewList.size(); if (position >= length || position < 0 || length <= 0) { return; } for(int i = 0; i < length; i++) { mImageViewList.get(i).setImageDrawable(mPageInDicator); } mImageViewList.get(position).setImageDrawable(mPageInDicatorFocused); } /** * 初始化整个FrameLayout视图组 */ private void initScrollView() { setLayoutParams(new LayoutParams(mScreenWidth,mScreenHeight )); linearLayoutScrolLayout = new LinearLayout(mContext); linearLayoutScrolLayout.setBACkgroundColor(Color.WHITE); linearLayoutScrolLayout.setOrientation(LinearLayout.HORIZONTAL); int mVersionCode = 8; try { mVersionCode = Integer.valueOf(android.os.build.VERSION.SDK); Logger.d(tag,"sdk version=" + mVersionCodE); } catch (Exception E) { e.printStackTrace(); } //针对android1.6及以下的特殊处理 此为android的低版本bug if(mVersionCode <= 5) { linearLayoutScrolLayout.setBaselineAligned(false); } //初始化四个滑动view for(int i = 0; i < PAGE_COUNT; i++) { LinearLayout linearLayoutScreen = new LinearLayout(mContext); linearLayoutScreen.setOrientation(LinearLayout.VERTICAL); linearLayoutScrolLayout.addView(linearLayoutScreen,new LayoutParams( mScreenWidth,LayoutParams.FILL_PARENT)); mLinearLayoutScreens.add(i,linearLayoutScreen); } //初始化小圆点视图 RelativeLayout relativeLayout = new RelativeLayout(mContext); relativeLayout.setLayoutParams(new LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); //linearLayoutForDot为小圆点视图 linearLayoutForDot =new LinearLayout(mContext); android.widget.RelativeLayout.LayoutParams layoutParams = new android.widget.RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); //小圆点距底部的距离 单位:px layoutParams.bottomMargin = MARGIN_BOTTOM; layoutParams.rightMargin = MARGIN_BOTTOM; layoutParams.addRule(android.widget.RelativeLayout.ALIGN_PARENT_BOTTOM); layoutParams.addRule(android.widget.RelativeLayout.CENTER_HORIZONTAL); linearLayoutForDot.setLayoutParams(layoutParams); linearLayoutForDot.setOrientation(LinearLayout.HORIZONTAL); linearLayoutForDot.setHorizontalGravity(Gravity.CENTER); linearLayoutForDot.setVerticalGravity(Gravity.CENTER); //下面两句实现圆角半透明效果 不采用 // linearLayoutForDot.setBACkgroundresource(R.drawable.round_corner_bg); // linearLayoutForDot.getBACkground().setAlpha(100); //初始化4个小圆点 mPageInDicator = getresources().getDrawable(R.drawable.page_inDicator); mPageInDicatorFocused = getresources().getDrawable(R.drawable.page_inDicator_focused); for(int i = 0; i < PAGE_COUNT; i++) { ImageView imageView = new ImageView(mContext); imageView.setImageDrawable(mPageInDicator); mImageViewList.add(i,imageView); LinearLayout.LayoutParams layoutParamsForDot = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); layoutParamsForDot.rightMargin = 5; linearLayoutForDot.addView(imageView,layoutParamsForDot); } mImageViewList.get(0).setImageDrawable(mPageInDicatorFocused); relativeLayout.addView(linearLayoutForDot); m@L_673_43@Ex = new @L_673_43@Ex(mContext,null,mBAnnerClickListener); m@L_673_43@Ex.setLayoutParams(new LayoutParams( mScreenWidth * PAGE_COUNT,LayoutParams.FILL_PARENT)); m@L_673_43@Ex.addView(linearLayoutScrolLayout,new LayoutParams( LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); m@L_673_43@Ex.setHorizontalScrollBarEnabled(false); m@L_673_43@Ex.setHorizontalFadingEdgeEnabled(false); addView(m@L_673_43@EX); addView(relativeLayout); //自动滑屏 5秒一次 timer.schedule(mTimerTask,5000,TIMER_DURATION); } /** * 加一个bAnner页面 TODO此函数写的不好 */ private void addBAnnerItem() { //表示已经执行了onDetachedFromWindow,bAnner已经被销毁了 if( mBAnnerBitmaps == null || mLinearLayoutScreens == null || mImageViewList == null || mContext == null ) return; //调整屏幕数量和总宽度 PAGE_COUNT += 1; m@L_673_43@Ex.getLayoutParams().width = mScreenWidth * PAGE_COUNT; //加载默认图片资源 if(mDefaultBitmap == null) { BitmapFactory.options bitmapFactoryOptions = new BitmapFactory.options(); bitmapFactoryOptions.inJustDecodeBounds = false; bitmapFactoryOptions.inSampleSize = 2; resources res=mContext.getresources(); mDefaultBitmap = BitmapFactory.decoderesource(res,bitmapFactoryOptions); } mBAnnerBitmaps.add(mDefaultBitmap); mBAnnerItemsList.add(null); //加一个屏幕 LinearLayout linearLayoutScreen = new LinearLayout(mContext); linearLayoutScreen.setOrientation(LinearLayout.VERTICAL); linearLayoutScreen.setBACkgroundDrawable(new BitmapDrawable( mBAnnerBitmaps.get(PAGE_COUNT - 1) )); linearLayoutScrolLayout.addView(linearLayoutScreen,new LayoutParams( mScreenWidth,LayoutParams.FILL_PARENT)); mLinearLayoutScreens.add(linearLayoutScreen); //加一个小圆点 ImageView imageView = new ImageView(mContext); imageView.setImageDrawable(mPageInDicator); mImageViewList.add(imageView); LinearLayout.LayoutParams layoutParamsForDot = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); layoutParamsForDot.rightMargin = 5; linearLayoutForDot.addView(imageView,layoutParamsForDot); } private class @L_673_43@Ex extends ViewGroup implements OnGestureListener { private GestureDetector mGestureDetector; privatE int mWhichScreen; public @L_673_43@Ex(Context context,OnBAnnerClickListener bAnnerClickListener) { super(context,attrs); mGestureDetector = new GestureDetector(this); //解决长按屏幕后无法拖动的现象 mGestureDetector.setIsLongpressEnabled(false); //构造弹性滑动对象 mScroller = new Scroller(context); } /** * 切换到指定屏幕 * @param whichScreen 屏幕index */ public void switchView(int whichScreen) { if(mLinearLayoutScreens == null) return; // 防止非法参数 if (whichScreen < 0) whichScreen = 0; else if(whichScreen >= PAGE_COUNT) whichScreen = PAGE_COUNT - 1; Logger.i(tag,"switch view to " + whichScreen); int delta = whichScreen * mScreenWidth - @L_673_43@Ex.this.getScrollX(); //缓慢滚动到指定位置 mScroller.startScroll(getScrollX(),delta,Math.abs(delta) * 3); // refresh invalidate(); //delta>0 stands for user scroll view to right if (delta > 0) mScrollToRight = true; else { mScrollToRight = false; } mWhichScreen = whichScreen; mWhich = whichScreen; //切换小圆点 switchScreenPosition(mWhichScreen); } /** * 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发 */ @Override public Boolean onDown(MotionEvent E) { Logger.i("MyGesture","onDown"); mScrollX = @L_673_43@Ex.this.getScrollX(); return true; } /** * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发 * 注意和onDown()的区别,强调的是没有松开或者拖动的状态 */ public void onShowPress(MotionEvent E) { Logger.i("MyGesture","onShowPress"); } /** * 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发 */ public Boolean onSingleTapUp(MotionEvent E) { Logger.i("MyGesture","onSingleTapUp"); if(mBAnnerItemsList == null || mBAnnerItemsList.size() <= mWhichScreen) return false; BAnnerItem bAnnerItem = mBAnnerItemsList.get(mWhichScreen); if(bAnnerItem != null) { BAnnerMotionEvent bAnnerMotionEvent = new BAnnerMotionEvent(mWhichScreen,bAnnerItem.action,bAnnerItem.url,bAnnerItem.gamEID,bAnnerItem.gameType,bAnnerItem.title); mBAnnerClicklistener.onBAnnerClick(bAnnerMotionEvent); } return false; } /** 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN,多个ACTION_MOVE,* 1个ACTION_UP触发 */ public Boolean onFling(MotionEvent e1,MotionEvent e2,float veLocityX,float veLocityY) { Logger.i("MyGesture","onFling veLocityX=" + veLocityX); mWhichScreen = veLocityX > 0 ? mWhichScreen - 1 : mWhichScreen + 1; switchView(mWhichScreen); return true; } /** * 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN,多个ACTION_MOVE触发 */ public Boolean onScroll(MotionEvent e1,float distanceX,float distanceY) { Logger.i("MyGesture","onScroll"); //禁止弹性滚动 if (mOverScrollmode == falsE) { float x1 = e1.getX(); float x2 = e2.getX(); if(mWhichScreen == 0 && x1 < x2) return false; else if(mWhichScreen == PAGE_COUNT - 1 && x1 > x2) return false; } // int distance = Math.abs(getScrollX() - mWhichScreen * mScreenWidth); // if ((mWhichScreen ==0 || mWhichScreen == PAGE_COUNT -1) && distance > mOverScrollDistancE) // return false; this.scrollBy((int)distanceX,0); return true; } /** * 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发 */ public void onLongPress(MotionEvent E) { Logger.i("MyGesture","onLongPress"); } @Override public Boolean onTouchEvent(MotionEvent event) { if(event.getAction() == MotionEvent.ACTION_DOWN) { mTimerResume = false; if ( !mScroller.isFinished() ) mScroller.abortAnimation(); } else if(event.getAction() == MotionEvent.ACTION_Up) { //开始自动滑屏 mTimerResume = true; mByUserAction = true; } Boolean consume = mGestureDetector.onTouchEvent(event); if (consume == false && event.getAction() == MotionEvent.ACTION_Up) { int curscrollX = @L_673_43@Ex.this.getScrollX(); int mWhichScreen = (curscrollX + mScreenWidth / 2) /mScreenWidth; switchView(mWhichScreen); } return consume; } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); posTinvalidate(); } } @Override protected void onLayout(Boolean changed,int l,int t,int r,int b) { if (changed) { int childLeft = 0; final int childCount = getChildCount(); for (int i=0; i<childCount; i++) { final View childView = getChildAt(i); if (childView.getVisibility() != View.GONE) { final int childWidth = childView.getMeasuredWidth(); childView.layout(childLeft,childLeft+childWidth,childView.getMeasuredHeight()); childLeft += childWidth; } } } } @Override protected void onMeasure(int widthMeasureSpec,int heightMeasureSpeC) { super.onMeasure(widthMeasureSpec,heightMeasureSpec); final int width = MeasureSpec.getSize(widthMeasureSpec); final int count = getChildCount(); for (int i = 0; i < count; i++) { getChildAt(i).measure(widthMeasureSpec,heightMeasureSpec); } scrollTo(mWhich * mScreenWidth,0); } } /** * override此函数,防止其修改构造方法所定义的宽和高<br/> * 注意:在这里,设置宽和高将不起作用 */ @Override public void setLayoutParams(android.view.ViewGroup.LayoutParams params) { params.width = mScreenWidth; params.height = mScreenHeight; super.setLayoutParams(params); } //标志view AttachedToWindow @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mTimerResume = true; } //标志view已经脱离window,典型的情形是view被销毁了,此时取消timer @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); Logger.d(tag,"onDetachedFromWindow"); mTimerResume = false; int activityId = ( (BaseActivity)mContext ).activityId(); //如果是账号管理页面 则释放内存 if(activityId == BaseActivity.account_ID) { destroy(); } } /** * 销毁bAnner */ public void destroy() { mTimerTask.cancel(); timer.cancel(); //去除各种bitmap对activity的引用关系 destoryBitmaps(); System.gc(); } /** * 去除各种bitmap对activity的引用关系 */ private void destoryBitmaps() { for (View view : mLinearLayoutScreens) { Drawable drawable = view.getBACkground(); BitmapDrawable bitmapDrawable = null; if(drawable instanceof BitmapDrawablE) bitmapDrawable = (BitmapDrawablE)drawable; if(bitmapDrawable != null) { //解除drawable对view的引用 bitmapDrawable.setCallBACk(null); bitmapDrawable = null; } } for (ImageView imageView : mImageViewList) { Drawable drawable = imageView.getDrawable(); if(drawable != null) { drawable.setCallBACk(null); drawable = null; } } mPageInDicator.setCallBACk(null); mPageInDicator = null; mPageInDicatorFocused.setCallBACk(null); mPageInDicatorFocused = null; mLinearLayoutScreens.clear(); mLinearLayoutScreens = null; mBAnnerBitmaps.clear(); mBAnnerBitmaps = null; mImageViewList.clear(); mImageViewList = null; mBAnnerItemsList.clear(); mBAnnerItemsList = null; } //单击事件 @Override public void onBAnnerClick( BAnnerMotionEvent bAnnerMotionEvent ) { final int position = bAnnerMotionEvent.index; if(mContext == null) return; NotificationInfo notificationInfo = new NotificationInfo(); notificationInfo.msgType = bAnnerMotionEvent.getAction(); int action = bAnnerMotionEvent.getAction(); if(action == NotificationInfo.NOTIFICATION_SINGLEGAME_MSG) //单个游戏消息,直接启动该游戏 { try { notificationInfo.gamEID = Integer.parseInt( bAnnerMotionEvent.getGamEID() ); notificationInfo.gameType = Integer.parseInt( bAnnerMotionEvent.getGameType() ); } catch (numberFormatException E) { Logger.e(tag,e.toString()); return; } } else if(action == NotificationInfo.NOTIFICATION_GAMEPAGE_MSG) //游戏主页消息,通过客户端展示游戏主页 { try { notificationInfo.gamEID = Integer.parseInt( bAnnerMotionEvent.getGamEID() ); } catch (numberFormatException E) { Logger.e(tag,e.toString()); return; } notificationInfo.issuetitle = bAnnerMotionEvent.gettitle(); } else if(action == NotificationInfo.NOTIFICATION_SHOW_WEBVIEW_MSG) //交叉推广消息,通过一个webview展示 { notificationInfo.issuetitle = bAnnerMotionEvent.gettitle(); notificationInfo.openUrl = bAnnerMotionEvent.getResponseUrl(); } else //reserved { return; } Intent intent = notificationInfo.generateIntent(mContext); if(intent != null) mContext.startActivity(intent); } /** * ScrollBAnner所关联的bAnner项 可以为多个 一个为一屏 */ public static class BAnnerItem extends Object { public static final String ACTION = "action"; public static final String URL = "url"; public static final String imgurL = "imgurl"; public static final String GAMEID = "gamEID"; public static final String GAMETYPE = "gametype"; public static final String titlE = "title"; public int index = -1; public int action = -1; public String url = ""; public String imgurl = ""; public String gamEID = ""; public String gameType = ""; public String title = ""; public BAnnerItem(){} } /** * BAnnerMotionEvent:单击bAnner所产生的事件对象<br/> *getAction()来获取动作类别<br/> *getResponseUrl()来获取响应url<br/> *... */ public static class BAnnerMotionEvent extends Object { /** * ACTION_PLAY_FLASH: 播放游戏 */ public static final int aCTION_PLAY = 2; /** * ACTION_HOMEPAGE:打开官网 */ public static final int aCTION_HOMEPAGE = 3; /** * ACTION_OPEN_URL:打开指定url */ public static final int aCTION_OPEN_URL = 4; //bAnner中屏幕的index privatE int index = -1; //响应url private String responseUrl = ""; //动作种类 private int action = -1; //gamEID private String gamEID = ""; //gametype flash游戏(0) or h5游戏(1) private String gameType = ""; //webview的标题 private String title = ""; public BAnnerMotionEvent(int index,int action,String responseUrl,String gamEID,String gameType,String titlE) { BAnnerMotionEvent.this.index = index; BAnnerMotionEvent.this.action = action; BAnnerMotionEvent.this.responseUrl = responseUrl; BAnnerMotionEvent.this.gamEID = gamEID; BAnnerMotionEvent.this.gameType = gameType; BAnnerMotionEvent.this.title = title; } /** * 获取当前BAnnerMotionEvent事件对象的动作种类 * @return 动作种类:ACTION_PLAY等 */ public int getAction() { return action; } /** * 获取当前BAnnerMotionEvent事件对象的title * @return title webview的标题 */ public String gettitle() { return title; } /** * 获取当前BAnnerMotionEvent事件对象的gamEID * @return gamEID */ public String getGamEID() { return gamEID; } /** * 获取当前BAnnerMotionEvent事件对象的gameType * @return gameType 0 or 1 */ public String getGameType() { return gameType; } /** * 获取当前BAnnerMotionEvent事件对象的响应url * @return 响应url */ public String getResponseUrl() { return responseUrl; } @SuppressLint("DefaultLocale") @Override public String toString() { return String.format("BAnnerMotionEvent { index=%d,action=%d,responseUrl=%s,gamEID=%s,gameType=%s,title=%s }",index,action,responseUrl,gamEID,gameType,titlE); } } @Override public void onBAnnerInfosuccess(List<BAnnerItem> items) { Logger.d(tag,"onBAnnerInfosuccess"); mBAnnerItemsList = items; mHandler.sendEmptymessage(messaGE_FETCH_BAnnER_succesS); } @Override public void onBAnnerInfoFailed() { Logger.e(tag,"onBAnnerInfoFailed"); } }
ComponentCallBACk.java
public interface ComponentCallBACk { public static interface OnBAnnerClickListener { /** * bAnner单击事件 * @param bAnnerMotionEvent 单击事件对象,包含所需的响应信息 * 参见 {@link BAnnerMotionEvent} */ public abstract void onBAnnerClick( BAnnerMotionEvent bAnnerMotionEvent ); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是大佬教程为你收集整理的Android组件banner实现左右滑屏效果全部内容,希望文章能够帮你解决Android组件banner实现左右滑屏效果所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。