Android-迴圈廣告位組件

來源:互聯網
上載者:User

標籤:

迴圈廣告位也是一種非常常見的組件,網上有各種各樣的實現,那天看了singwhatiwanna的一種實現,非常簡單,然後結合之前見過的一種,稍微整理了一下。

轉載請標明出處:http://blog.csdn.net/goldenfish1919/article/details/46811889

先看下使用方式:

<com.xjs.demo.view.BannerViewandroid:id="@+id/bannerView"android:layout_width="match_parent"android:layout_height="150dp" android:paddingLeft="10dp"android:paddingRight="10dp"><android.support.v4.view.ViewPagerandroid:id="@+id/banner_viewpager"android:layout_width="match_parent"android:layout_height="match_parent" /><com.xjs.demo.view.DotViewandroid:id="@+id/banner_dotview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|center_horizontal"android:layout_marginBottom="10dp"app:dot_number="5"app:dot_radius="4dp"app:dot_selected_color="0xffffffff"app:dot_span="8dp"app:dot_unselected_color="0x80ffffff" /></com.xjs.demo.view.BannerView>

自訂的BannerView,內部有兩個子項目,一個是ViewPager,一個是自訂的DotView,使用的時候:

BannerView banner = (BannerView) this.findViewById(R.id.bannerView);banner.setOnBannerClickListener(new OnBannerClickListener(){@Overridepublic void OnBannerClicked(int pos) {Toast.makeText(MainActivity.this, "OnBannerClickListener:" + pos,Toast.LENGTH_SHORT).show();}});int[] imagesSrc = new int[] { R.mipmap.img1, R.mipmap.img2,R.mipmap.img3, R.mipmap.img4, R.mipmap.img5 };banner.update(imagesSrc);
可以給Banner添加點擊事件,然後傳遞圖片id,調用banner的update()方法就可以了。

下面重點來看下BannerView:


public class BannerView extends FrameLayout{private DotView mBannerDotView;private ViewPager mBannerViewPager;private BannerAdapter mBannerAdapter;/**當前的position*/private int mBannerPosition = 0;/**Banner點擊後的回調*/private OnBannerClickListener mBannerClickListener;/**自動播放相關*/    private Handler mHandler = new Handler();private Runnable task = new Runnable(){@Overridepublic void run() {              mBannerPosition = (mBannerPosition + 1) % mBannerAdapter.getCount();              mBannerViewPager.setCurrentItem(mBannerPosition);              Log.d(TAG, "tname:" + Thread.currentThread().getName());              mHandler.postDelayed(task, 3000);}};private static final String TAG = BannerView.class.getSimpleName();public BannerView(Context context) {this(context, null);}public BannerView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public BannerView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init(context);}private void init(Context context) {}@Overrideprotected void onFinishInflate() {super.onFinishInflate();//注意這裡的潛規則mBannerViewPager = (ViewPager)getChildAt(0);        mBannerDotView = (DotView)getChildAt(1);        mBannerDotView.setDotNumber(0);        mBannerAdapter = new BannerAdapter(getContext(), new int[0]);        mBannerViewPager.setAdapter(mBannerAdapter);        mBannerViewPager.setOnPageChangeListener(mBannerAdapter);}public void update(int[] imagesSrc){if(imagesSrc == null || imagesSrc.length <= 0){return;}mBannerDotView.setDotNumber(imagesSrc.length);mBannerDotView.setSelected(0);mBannerAdapter.update(imagesSrc);        mHandler.postDelayed(task, 3000);}private void setIndicator(int position) {        position %= mBannerAdapter.getSize();        mBannerDotView.setSelected(position);    }private int mDownX;    private int mDownY;    private long mDownTime;@Override    public boolean dispatchTouchEvent(MotionEvent event) {        int action = event.getAction();        if (action == MotionEvent.ACTION_DOWN) {            mHandler.removeCallbacks(task);            mDownX = (int)event.getX();            mDownY = (int)event.getY();            mDownTime = System.currentTimeMillis();        } else if (action == MotionEvent.ACTION_UP) {            if (System.currentTimeMillis() - mDownTime < 500 && Math.abs(mDownX - event.getX()) < 5 && Math.abs(mDownY - event.getY()) < 5) {                // 介面回調                if (mBannerClickListener != null) {                mBannerClickListener.OnBannerClicked(mBannerPosition%mBannerAdapter.getSize());                }            }            mHandler.postDelayed(task, 3000);        } else if(action == MotionEvent.ACTION_CANCEL){         mHandler.postDelayed(task, 3000);        } else if(action == MotionEvent.ACTION_MOVE){        // do nothing        }        return super.dispatchTouchEvent(event);    }private class BannerAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {private Context mContext;        private int[] mImagesSrc;        private int mSize;        private int mFakeSize;        public BannerAdapter(Context context, int[] imagesSrc) {            mContext = context;            update(mImagesSrc);        }        public void update(int[] imagesSrc) {        if(imagesSrc == null || imagesSrc.length <= 0){        return;        }        this.mImagesSrc = imagesSrc;        this.mSize = imagesSrc.length;            this.mFakeSize = mSize * 10;        notifyDataSetChanged();}@Override        public int getCount() {            return mFakeSize;        }        public int getSize() {            return mSize;        }                @Override        public boolean isViewFromObject(View view, Object o) {            return view == o;        }        @Override        public Object instantiateItem(ViewGroup container, int position) {            position %= mSize;            ImageView imageView = new ImageView(mContext);            imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));            imageView.setScaleType(ScaleType.CENTER_CROP);            imageView.setImageResource(mImagesSrc[position]);            container.addView(imageView);            return imageView;        }        @Override        public void destroyItem(ViewGroup container, int position, Object object) {            container.removeView((View) object);        }        @Override        public void finishUpdate(ViewGroup container) {            int position = mBannerViewPager.getCurrentItem();            Log.d(TAG, "finish update before, position=" + position);            if (position == 0) {                position = mSize;                mBannerViewPager.setCurrentItem(position, false);            } else if (position == getCount() - 1) {                position = mSize - 1;                mBannerViewPager.setCurrentItem(position, false);            }            Log.d(TAG, "finish update after, position=" + position);        }        @Override        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {        }        @Override        public void onPageSelected(int position) {            mBannerPosition = position;            setIndicator(position);        }        @Override        public void onPageScrollStateChanged(int state) {        }    }public interface OnBannerClickListener{public void OnBannerClicked(int pos);}public void setOnBannerClickListener(OnBannerClickListener bannerClickListener) {this.mBannerClickListener = bannerClickListener;}@Overridepublic void onDetachedFromWindow(){mHandler.removeCallbacksAndMessages(null);this.removeAllViews();this.mBannerClickListener = null;super.onDetachedFromWindow();}}
然後看下DotView:

public class DotView extends LinearLayout {    private int mLittleDotWidth;    private int mDotSpan = 36;    private float mDotRadius = 6f;    private int mDotNumber = 5;        private int mCurrent = 0;    private int mSelectedColor = 0xFF377BEE;    private int mUnSelectedColor = 0xFFC5CEDB;    public DotView(Context context) {        super(context);    }    public DotView(Context context, AttributeSet attrs) {        super(context, attrs);        //擷取自訂的屬性        TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.DotView, 0, 0);        if (arr != null) {            if (arr.hasValue(R.styleable.DotView_dot_radius)) {                mDotRadius = arr.getDimension(R.styleable.DotView_dot_radius, mDotRadius);            }            if (arr.hasValue(R.styleable.DotView_dot_span)) {                mDotSpan = (int) arr.getDimension(R.styleable.DotView_dot_span, mDotSpan);            }                        if(arr.hasValue(R.styleable.DotView_dot_number)){            mDotNumber = (int) arr.getInt(R.styleable.DotView_dot_number, mDotNumber);            }            mSelectedColor = arr.getColor(R.styleable.DotView_dot_selected_color, mSelectedColor);            mUnSelectedColor = arr.getColor(R.styleable.DotView_dot_unselected_color, mUnSelectedColor);            arr.recycle();        }        mLittleDotWidth = (int) (mDotSpan / 2 + mDotRadius * 2);                //把小點畫出來        addDotViews();    }    public void setDotNumber(int dotNumber){    this.mDotNumber = dotNumber;    addDotViews();    }        private void addDotViews(){        setGravity(Gravity.CENTER_HORIZONTAL);        setOrientation(HORIZONTAL);        removeAllViews();        for (int i = 0; i < mDotNumber; i++) {            LittleDot dot = new LittleDot(getContext(), i);            if (i == 0) {                dot.setColor(mSelectedColor);            } else {                dot.setColor(mUnSelectedColor);            }            dot.setLayoutParams(new LayoutParams((int) mLittleDotWidth, (int) mDotRadius * 2, 1));            addView(dot);        }    }        public final void setSelected(int index) {        if (index >= getChildCount() || index < 0 || mCurrent == index) {            return;        }        if (mCurrent < getChildCount() && mCurrent >= 0) {            ((LittleDot) getChildAt(mCurrent)).setColor(mUnSelectedColor);        }        ((LittleDot) getChildAt(index)).setColor(mSelectedColor);        mCurrent = index;    }    private class LittleDot extends View {        private int mColor;        private Paint mPaint;        public LittleDot(Context context, int index) {            super(context);            mPaint = new Paint();            mPaint.setAntiAlias(true);        }        public void setColor(int color) {            if (color == mColor){            return;            }            mColor = color;            invalidate();        }        @Override        protected void onDraw(Canvas canvas) {            super.onDraw(canvas);            mPaint.setColor(mColor);            canvas.drawCircle(mLittleDotWidth / 2, mDotRadius, mDotRadius, mPaint);        }    }    public void setSelectedColor(int color) {        if (mSelectedColor != color) {            mSelectedColor = color;            invalidate();        }    }    public void setUnSelectedColor(int color) {        if (mUnSelectedColor != color) {            mSelectedColor = color;            invalidate();        }    }        public void setColor(int selectedColor, int unSelectedColor) {        if (mSelectedColor != selectedColor || mUnSelectedColor != unSelectedColor) {            mSelectedColor = selectedColor;            mUnSelectedColor = unSelectedColor;            invalidate();        }    }}
最後是attrs_dotview.xml:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="DotView">        <attr name="dot_number" format="integer" />        <attr name="dot_radius" format="dimension" />        <attr name="dot_span" format="dimension" />        <attr name="dot_unselected_color" format="integer" />        <attr name="dot_selected_color" format="integer" />    </declare-styleable></resources>

這個控制項的優點是:使用起來非常簡單,只需要把圖片傳遞到BannerView的update方法就可以了,而且源碼修改起來也非常簡單。

另外,DotView的實現非常巧妙,非常值得借鑒!

我們不生產代碼,我們只是代碼的搬運工,感謝這些無私奉獻的人:

BannerView參考:http://blog.csdn.net/singwhatiwanna/article/details/46541225

DotView參考:https://github.com/etao-open-source/cube-sdk/tree/master/core/src/in/srain/cube/views/banner

touch攔截:http://blog.csdn.net/wuseyukui/article/details/46627961

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Android-迴圈廣告位組件

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.