一、动态布局

纯粹为了保持代码风格的一致性,也可以用xml布局来实现。
private View createBannerView() {LinearLayout bannerLayout = new LinearLayout(mContext);bannerLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));bannerLayout.setOrientation(LinearLayout.VERTICAL);bannerLayout.setGravity(Gravity.CENTER);BannerView bannerView = new BannerView(mContext);bannerView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, DimenUtils.dip2px(mContext, 160)));bannerLayout.addView(bannerView);return bannerLayout;}

二、实体Bean

存储Banner的相关信息:图片名、图片Url、图片TargetUrl。

public class Banner {    private String mName; // 图片名    private String mImgUrl; // 图片下载url    private String mTargetUrl; // 点击图片跳转url    public Banner(String name, String imgUrl, String targetUrl) {        this.mName = name;        this.mImgUrl = imgUrl;        this.mTargetUrl = targetUrl;    }    public String getName() {        return mName;    }    public String getImgUrl() {        return mImgUrl;    }    public String getTargetUrl() {        return mTargetUrl;    }}

三、适配器PagerAdapter

没有实现Banner的左右循环效果,感觉意义不大。

public class BannerViewAdapter extends PagerAdapter {    private Context mContext;    private ArrayList mBanners;    public BannerViewAdapter(Context context) {        this.mContext = context;    }    @Override    public int getCount() {        return mBanners == null ? 0 : mBanners.size();    }    @Override    public boolean isViewFromObject(View view, Object object) {        return view == object;    }    /**     * @param container     * @param position     * @return 对position进行求模操作     * 因为当用户向左滑时position可能出现负值,所以必须进行处理     */    @Override    public Object instantiateItem(ViewGroup container, int position) {        // 对Viewpager页号求模去除View列表中要显示的项        position %= mBanners.size();        if (position < 0) {            position = mBanners.size() + position;        }        ImageView view = new ImageView(mContext);        view.setScaleType(ImageView.ScaleType.FIT_XY);        Picasso.with(mContext).load(mBanners.get(position).getImgUrl()).placeholder(R.drawable.default_banner).error(R.drawable.default_banner).transform(new PicassoTransformation()).into(view);        view.setTag(position);        final int index = position;        view.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                if (!NetworkManager.getInstance().isNetworkConnected()) {                    Toast.makeText(mContext, "网络连接异常,请检查网络", Toast.LENGTH_SHORT).show();                } else {                    // TODO mBanners.get(index).getTargetUrl()                }            }        });        // 如果View已经在之前添加到了一个父组件,则必须先remove,否则会抛出IllegalStateException。        ViewParent viewParent = view.getParent();        if (viewParent != null) {            ViewGroup parent = (ViewGroup) viewParent;            parent.removeView(view);        }        container.addView(view);        return view;    }    /**     * 由于我们在instantiateItem()方法中已经处理了remove的逻辑,     * 因此这里并不需要处理。实际上,实验表明这里如果加上了remove的调用,     * 则会出现ViewPager的内容为空的情况。     *     * @param container     * @param position     * @param object     */    @Override    public void destroyItem(ViewGroup container, int position, Object object) {        // 警告:不要在这里调用removeView    }    public void setBanner(ArrayList banners) {        this.mBanners = banners;        notifyDataSetChanged();    }}
由于使用了Picasso异步加载图片,所以需要实现Transformation接口。

public class PicassoTransformation implements Transformation {    @Override    public Bitmap transform(Bitmap bitmap) {        return bitmap;    }    @Override    public String key() {        return null;    }}

四、BannerView控件

自定义带圆点指示器的Banner控件,实现自动轮播、拖拽暂停、手动滑动效果。
public class BannerView extends RelativeLayout implements ViewPager.OnPageChangeListener {    private static final int UPDATE_BANNER = 0x100;    private Context mContext;    private ViewPager mViewPager;    private LinearLayout mIndicatorLayout;    private boolean isPauseRun;    private int mAutoCurrIndex;    private ArrayList mDots;    private BannerViewAdapter mBannerViewAdapter;    private Handler mHandler = new Handler() {        public void handleMessage(Message msg) {            switch (msg.what) {                case UPDATE_BANNER:                    if (msg.arg1 != 0) {                        mViewPager.setCurrentItem(msg.arg1);                    } else {                        // false: 当从末页跳到首页时,不显示翻页动画效果                        mViewPager.setCurrentItem(msg.arg1, false);                    }                    break;                default:                    break;            }        }    };    public BannerView(Context context) {        super(context);        this.mContext = context;    }    public void setBannerViewAdapter(BannerViewAdapter bannerViewAdapter) {        this.mBannerViewAdapter = bannerViewAdapter;        initView();        bindCarouselTask();    }    private void initView() {        // 动态添加ViewPager        mViewPager = new ViewPager(mContext);        mViewPager.setAdapter(mBannerViewAdapter);        mViewPager.addOnPageChangeListener(this);        addView(mViewPager);        // 动态添加一个LinearLayout        mIndicatorLayout = new LinearLayout(mContext);        RelativeLayout.LayoutParams RelativeParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        RelativeParams.setMargins(DimenUtils.dip2px(mContext, 5), DimenUtils.dip2px(mContext, 5), DimenUtils.dip2px(mContext, 5), DimenUtils.dip2px(mContext, 5));        RelativeParams.addRule(ALIGN_PARENT_BOTTOM);        RelativeParams.addRule(CENTER_HORIZONTAL);        addView(mIndicatorLayout, RelativeParams);        // 动态添加指示器        LinearLayout.LayoutParams LinearParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);        LinearParams.setMargins(DimenUtils.dip2px(mContext, 2), DimenUtils.dip2px(mContext, 2), DimenUtils.dip2px(mContext, 2), DimenUtils.dip2px(mContext, 2));        mDots = new ArrayList<>();        int adapterSize = mBannerViewAdapter.getCount();        for (int i = 0; i < adapterSize; i++) {            Dot dot = new Dot(mContext);            mDots.add(dot);            mIndicatorLayout.addView(dot, LinearParams);        }        refreshDots(0);    }    /**     * 自动轮播图片,5s后第一次执行,周期是5s     */    private void bindCarouselTask() {        new Timer().schedule(new TimerTask() {            @Override            public void run() {                if (!isPauseRun) {                    Message message = new Message();                    message.what = UPDATE_BANNER;                    if (mAutoCurrIndex == mBannerViewAdapter.getCount() - 1) {                        mAutoCurrIndex = -1;                    }                    message.arg1 = mAutoCurrIndex + 1;                    mHandler.sendMessage(message);                }            }        }, 5000, 5000);    }    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Override    public void onPageSelected(int position) {        int adapterSize = mBannerViewAdapter.getCount();        if (adapterSize != 0) {            int positionInData = position % adapterSize;            refreshDots(positionInData);        }        // 设置当前图片的index        mAutoCurrIndex = position;    }    @Override    public void onPageScrollStateChanged(int state) {        switch (state) {            // 静止状态            case ViewPager.SCROLL_STATE_IDLE:                isPauseRun = false;                break;            // 拖拽中            case ViewPager.SCROLL_STATE_DRAGGING:                isPauseRun = true;                break;            // 拖拽后松手,自动回到最终位置的过程            case ViewPager.SCROLL_STATE_SETTLING:                isPauseRun = false;                break;        }    }    private void refreshDots(int positionInData) {        for (Dot dot : mDots) {            dot.setDotColor(Constants.UNSELECTED_DOT_COLOR);        }        mDots.get(positionInData).setDotColor(Constants.SELECTED_DOT_COLOR);    }    /**     * 指示当前viewpager处于哪个页面     */    private class Dot extends View {        private int mDotColor;        private int mDotSize; // 指示器的圆点大小, 单位:dp        private Paint mDotPaint;        public Dot(Context context) {            super(context);            mDotColor = Constants.UNSELECTED_DOT_COLOR;            mDotSize = DimenUtils.dip2px(context, 5);            mDotPaint = new Paint();            mDotPaint.setAntiAlias(true);            mDotPaint.setDither(true);            mDotPaint.setStyle(Paint.Style.FILL);        }        @Override        protected void onDraw(Canvas canvas) {            mDotPaint.setColor(mDotColor);            canvas.drawCircle(getWidth() / 2, getHeight() / 2, getWidth() / 2, mDotPaint);        }        /**         * 将dot的宽度和高度定死         */        @Override        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {            widthMeasureSpec = MeasureSpec.makeMeasureSpec(mDotSize, MeasureSpec.EXACTLY);            heightMeasureSpec = MeasureSpec.makeMeasureSpec(mDotSize, MeasureSpec.EXACTLY);            setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);        }        /**         * 修改dot的颜色, 并且让整个dot重绘         */        public void setDotColor(int color) {            mDotColor = color;            invalidate();        }    }}

五、触发生效

public void setBannerViewDatas(ArrayList banners) {mBannerViewAdapter.setBanner(banners);((BannerView) ((LinearLayout) createBannerView()).getChildAt(0)).setBannerViewAdapter(mBannerViewAdapter);}


更多相关文章

  1. android 删除SD卡或者手机的缓存图片和目录
  2. android 视频图片混合轮播实现
  3. android用ImageView显示网络图片
  4. android通过BitmapFactory.decodeFile获取图片bitmap报内存溢出
  5. android 运用AsyncTask 获取图片并显示
  6. android中网络图片的显示
  7. Android 图片相关
  8. android 图片点击一下就放大到全屏,再点一下就回到原界面
  9. Android图片压缩、加水印

随机推荐

  1. Android(安卓)开发学习手记(三):关于PullToR
  2. Android程序退出彻底关闭进程的方法
  3. Android(安卓)Handler 泄漏
  4. 手机rom的那些坑
  5. Android使用外部字体
  6. android 手机屏幕密度等级和屏幕逻辑尺寸
  7. TranslateAnimation动画
  8. Android中振动器(Vibrator)的使用
  9. Android(安卓)SDK Manager:failed to ins
  10. Android如何实现引导页