android中左右滑屏的实现(广告位banner组件)

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               
  1. 原理

参见下图。整个组件是一个FrameLayout,里面有两个view,第一个是LinearLayout,承载了4个(或多个)可以滑动的view,见图中绿色背景的部分;第二个是一个RelativeLayout,在其底部放置了一个LinearLayout,在LinearLayout的内部放置了若干个小圆点,用来指示当前屏幕的索引。手势检测用了GestureDetector,并实现了OnGestureListener接口。为了能控制滑动速度,采用了Scroller弹性滑动对象。

为什么组件继承FrameLayout,是因为用于指示的小圆点是出现在view上面的,一个view叠在另一个view上面,这就是FrameLayout的特性

什么是banner组件?在许多android应用上,比如爱奇艺客户端、百度美拍、应用宝等上面,都有一个可以手动滑动的小广告条,这就是banner,实际应用中的banner,其信息(图片和点击行为)是后台可配置的,是需要通过网络从后台拉取的。网上有许多手动滑屏的例子,但是一般只是个demo,无法在实际中使用,因为其一般没有考虑如下几类问题:图片缓存、OOM问题、是否可灵活配置、是否预留外部接口以及是否封装良好。没有良好的封装,手动滑屏加在代码中,会使得代码变得很烂很脆弱。

        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.BannerInfoHandlerprivate static final String TAG = "ScrollBanner"private HorizontalScrollViewEx mHorizontalScrollViewEx;  //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 = 0public static final int MESSAGE_AUTO_SCROLL = 1public static final int MESSAGE_FETCH_BANNER_SUCCESS = 2public 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 = 5000private 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--;    }    mHorizontalScrollViewEx.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) {  mHorizontalScrollViewEx.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);  mHorizontalScrollViewEx = new HorizontalScrollViewEx(mContext, null, mBannerClickListener);  mHorizontalScrollViewEx.setLayoutParams(new LayoutParams(    mScreenWidth * PAGE_COUNT,     LayoutParams.FILL_PARENT));  mHorizontalScrollViewEx.addView(linearLayoutScrolLayout, new LayoutParams(    LayoutParams.FILL_PARENT,     LayoutParams.FILL_PARENT));  mHorizontalScrollViewEx.setHorizontalScrollBarEnabled(false);  mHorizontalScrollViewEx.setHorizontalFadingEdgeEnabled(false);  addView(mHorizontalScrollViewEx);  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;  mHorizontalScrollViewEx.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, R.drawable.banner_image_default, 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 HorizontalScrollViewEx extends ViewGroup implements  OnGestureListener {  private GestureDetector mGestureDetector;  private int mWhichScreen;  public HorizontalScrollViewEx(Context context, AttributeSet attrs, 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 - HorizontalScrollViewEx.this.getScrollX();   //缓慢滚动到指定位置   mScroller.startScroll(getScrollX(), 0, delta, 0, 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 = HorizontalScrollViewEx.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, MotionEvent e2, 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 = HorizontalScrollViewEx.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, 0,         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 ); } }
           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_43661383/article/details/84068727
今日推荐