zoukankan      html  css  js  c++  java
  • 广告banner:手动滑动切换,自动切换,点击跳转,异步加载网络图片

    效果图:

    该banner功能有自动切换图片,点击图片可以自定义事件,手动滑动切换,异步加载图片

    代码说话:

    布局文件:

    <!-- 广告位 -->
    
                <FrameLayout
                    android:id="@+id/new_recommend"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content" >
    
                    <com.cyou.cmall.ui.HorizontalViewPager
                        android:id="@+id/viewpager"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent" />
    
                    <LinearLayout
                        android:id="@+id/ll_indicator"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="bottom"
                        android:orientation="horizontal"
                        android:paddingBottom="8dp"
                        android:paddingLeft="26dip" />
                </FrameLayout>


    布局文件中我自定义了一个HorizontalViewPager,它是在viewpager的基础上做了一些修改,之所以这样做是因为,项目中使用到了下拉刷新控件,该布局最外层还有一个scrollview,会导致scrollview将手势事件拦截,而viewpager得不到滑动手势

    下面是HorizontalViewPager的代码,如果不需要处理滑动手势,完全可以使用系统的viewpager控件

    /**
     * 复写该控件是因为在PullToRefreshScrollView中,viewpager无法水平滑动
     *
     * @author wangwei_cs
     */
    public class HorizontalViewPager extends ViewPager {
    
        private GestureDetector mGestureDetector;
    
        public HorizontalViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(context);
        }
    
        public HorizontalViewPager(Context context) {
            super(context);
            init(context);
        }
    
        private void init(Context context) {
            mGestureDetector = new GestureDetector(context, new YScrollDetector());
        }
    
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
            boolean dispatchTouchEvent = super.dispatchTouchEvent(ev);
            if (dispatchTouchEvent) {
                if (mGestureDetector.onTouchEvent(ev)) {
                    //请求父类放弃事件的处理
                    requestDisallowInterceptTouchEvent(true);
                }
            }
            return dispatchTouchEvent;
        }
    
        class YScrollDetector extends SimpleOnGestureListener {
    
            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2,
                    float distanceX, float distanceY) {
                // 如果我们滚动更接近水平方向,返回true,自己处理,否则,让出处理权限
                return (Math.abs(distanceX) > Math.abs(distanceY));
            }
        }
    }
    </span>


    言归正传:在程序oncreate方法中调用一下方法

        /**
         * 初始化推荐广告专区
         */
        private void initRecommendAd() {
            HorizontalViewPager mViewPager = (HorizontalViewPager) findViewById(R.id.viewpager);
            mIndicatorLayout = (LinearLayout) findViewById(R.id.ll_indicator);
            FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
                    android.widget.FrameLayout.LayoutParams.MATCH_PARENT, height * 24 / 100);
            mViewPager.setLayoutParams(params);
            AdImagePagerAdapter mPagerAdapter = new AdImagePagerAdapter(mCxt, imageUrls, new ViewPagerItemClickListener() {
    
                @Override
                public void OnViewPagerItemClick(int position) {
                    if (imageUrls.size() > 0) {
                        if (imageUrls.size() == 1) {
                            boolean enable = urlEnable(imageUrls.get(0));
                            if (enable) {
                                handleClickEvent(position);
                            }
                        } else {
                            handleClickEvent(position);
                        }
                    }
                }
            });
            List<String> lastAdUrls = getLastAdUrls();
            if (lastAdUrls == null || lastAdUrls.size() == 0) {
                // 没有记录上一次广告url信息,添加一个无效url路径
                imageUrls.add(Constants.INVALID_URL);
                LogHelper.e(TAG, "no last ad record");
            } else {
                LogHelper.e(TAG, "show last ad record");
                imageUrls.addAll(lastAdUrls);
            }
            mAdComponent = new RecommendAdComponent(mCxt, mViewPager, mPagerAdapter, imageUrls, 5000,
                    mIndicatorLayout);
            mAdComponent.startUpAdComponent();
            mPagerAdapter.notifyDataSetChanged();
        }


    下面是AdImagePagerAdapter的源码

    import java.util.List;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.support.v4.view.PagerAdapter;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemClickListener;
    import android.widget.ImageView;
    import android.widget.ProgressBar;
    import android.widget.Toast;
    
    import com.nostra13.universalimageloader.core.DisplayImageOptions;
    import com.nostra13.universalimageloader.core.ImageLoader;
    import com.nostra13.universalimageloader.core.assist.FailReason;
    import com.nostra13.universalimageloader.core.assist.ImageScaleType;
    import com.nostra13.universalimageloader.core.assist.SimpleImageLoadingListener;
    import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
    
    /**
     * 无限循环adapter
     * 
     * @author wangwei_cs
     */
    public class AdImagePagerAdapter extends PagerAdapter {
    
        protected static final String TAG = "AdImagePagerAdapter";
        private List<String> imageUrls;
        private LayoutInflater inflater;
        private Context mCxt;
        private ViewPagerItemClickListener mListener;
        protected ImageLoader imageLoader;
        private DisplayImageOptions options;
    
        public AdImagePagerAdapter(Context context, List<String> imageUrls, ViewPagerItemClickListener listener) {
            this.imageUrls = imageUrls;
            this.mCxt = context;
            inflater = LayoutInflater.from(context);
            this.mListener = listener;
            imageLoader = ImageLoader.getInstance();
    
            options = new DisplayImageOptions.Builder()
                    .showImageForEmptyUri(R.drawable.ad_default)
                    .showImageOnFail(R.drawable.ad_default)
                    .showImageOnLoading(R.drawable.ad_default)
                    .resetViewBeforeLoading(true)
                    .cacheOnDisc(true)
                    .imageScaleType(ImageScaleType.EXACTLY)
                    .bitmapConfig(Bitmap.Config.RGB_565)
                    .considerExifParams(true)
                    .displayer(new FadeInBitmapDisplayer(300))
                    .build();
        }
    
        @Override
        public int getCount() {
            if (imageUrls.size() < 2) {
                return imageUrls.size();
            }
            return Integer.MAX_VALUE;
        }
    
        @Override
        public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
        }
    
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            final int index = position % imageUrls.size();
            View view = inflater.inflate(R.layout.item_pager_image, container, false);
            assert view != null;
            ImageView imageView = (ImageView) view.findViewById(R.id.image);
            final ProgressBar spinner = (ProgressBar) view.findViewById(R.id.img_loading);
            imageLoader.displayImage(imageUrls.get(index), imageView, options,
                    new SimpleImageLoadingListener() {
                        @Override
                        public void onLoadingStarted(String imageUri, View view) {
                            spinner.setVisibility(View.VISIBLE);
                        }
    
                        @Override
                        public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                            String message = null;
                            switch (failReason.getType()) {
                                case IO_ERROR:
                                    message = "Input/Output error";
                                    break;
                                case DECODING_ERROR:
                                    message = "Image can't be decoded";
                                    break;
                                case NETWORK_DENIED:
                                    message = "Downloads are denied";
                                    break;
                                case OUT_OF_MEMORY:
                                    message = "Out Of Memory error";
                                    break;
                                case UNKNOWN:
                                    message = "Unknown error";
                                    break;
                            }
                            LogHelper.e(TAG, message);
                            spinner.setVisibility(View.GONE);
                        }
    
                        @Override
                        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
                            spinner.setVisibility(View.GONE);
                        }
                    });
    
            view.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                    if (mListener !=null) {
                        mListener.OnViewPagerItemClick(index);
                    }
                }
            });
            container.addView(view);
            return view;
        }
    
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
    

    下面是重点的RecommendAdComponent自定义的广告推荐组件

    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.os.Handler;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    import android.support.v4.view.ViewPager.PageTransformer;
    import android.view.View;
    import android.view.ViewGroup.LayoutParams;
    import android.view.animation.AnimationUtils;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    import java.util.List;
    import java.util.Timer;
    import java.util.TimerTask;
    
    /**
     * 展示广告轮转的组件
     * 
     * @author wangwei_cs
     */
    public class RecommendAdComponent {
    
        /**
         * 无效的图片切换时间,如果为0 表示不自动切换
         */
        public static final int SWITCH_TIME_INVALID = 0;
    
        private Context mCxt;
    
        // 图片url集合
        private List<String> mImgUrls;
        // 图片切换时间
        private int mSwitchTime;
        //自动滚动的定时器 
        private Timer mTimer;
        // 显示圆点指示器的布局
        private LinearLayout mIndicatorLayout;
        private ViewPager mViewPager;
        private PagerAdapter mPagerAdapter;
        private int currentIndex; // 当前页面,在0和getSize()直接
        private int pagerCurrent;//在viewpager中,的当前页面,取值在0和Integer.MAX_VALUE之间
        private boolean timeRunning;
    
        /**
         * @param context
         * @param viewpager viewPager组件
         * @param pagerAdapter
         * @param adUrls 装有图片url的集合
         * @param switchTime 图片切换时间(ms) {@link RecommendAdComponent#SWITCH_TIME_INVALID}:不自动切换
         * @param indicatorLayout 显示圆点指示器的布局
         */
        public RecommendAdComponent(Context context, ViewPager viewpager, PagerAdapter pagerAdapter, List<String> adUrls, int switchTime,
                LinearLayout indicatorLayout) {
            this.mCxt = context;
            this.mViewPager = viewpager;
            this.mPagerAdapter = pagerAdapter;
            this.mImgUrls = adUrls;
            this.mSwitchTime = switchTime;
            this.mIndicatorLayout = indicatorLayout;
            initIndicatorLayout();
            mViewPager.setOnPageChangeListener(new MyOnPageChangeListener());
    //        setViewpagerAnimator();
        }
    
        /**
         * 初始化指示器
         */
        private void initIndicatorLayout() {
            ImageView iv = null;
            if (mIndicatorLayout != null && getSize() < 2) {
                // 如果只有一第图时不显示圆点容器
                mIndicatorLayout.setVisibility(View.INVISIBLE);
            } else if (mIndicatorLayout != null) {
                mIndicatorLayout.setVisibility(View.VISIBLE);
                for (int i = 0; i < getSize(); i++) {
                    iv = new ImageView(mCxt);
                    iv.setTag(i);
                    int padding = mCxt.getResources().getDimensionPixelSize(R.dimen.indicator_padding);
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                            LayoutParams.WRAP_CONTENT);
                    params.setMargins(padding, 0, padding, 0);
                    mIndicatorLayout.addView(iv, params);
                }
            }
        }
    
        private void resetIndicatorLayout() {
            mIndicatorLayout.removeAllViews();
            initIndicatorLayout();
        }
    
        /**
         * 给viewPager设置动画
         */
        private void setViewpagerAnimator(){
            if (mViewPager !=null) {
                PageTransformer pageTransformer=new PageTransformer() {
                    
                    @Override
                    public void transformPage(View view, float arg1) {
    //                    view.setAnimation(AnimationUtils.loadAnimation(mCxt, android.R.anim.slide_out_right));
                        view.setAnimation(AnimationUtils.loadAnimation(mCxt, R.anim.right_in));
                    }
                };
                mViewPager.setPageTransformer(true, pageTransformer);
            }
        }
    
        /**
         * 获取图片集合的size
         * 
         * @return
         */
        private int getSize() {
            return (mImgUrls == null ? 0 : mImgUrls.size());
        }
    
        public boolean isEmpty() {
            return (mImgUrls == null);
        }
    
        /**
         * 开启组件
         */
        public void startUpAdComponent() {
            currentIndex = 0;
            pagerCurrent = 0;
            mViewPager.setAdapter(mPagerAdapter);
            mViewPager.setCurrentItem(currentIndex);
            updateIndicator(currentIndex);
            startTimer();
        }
    
        /**
         * 更新组件中adapter数据
         */
        public void updateAdComponent() {
            stopTimer();
            resetIndicatorLayout();
            mPagerAdapter.notifyDataSetChanged();
            startUpAdComponent();
        }
    
        /**
         * 在页面销毁的时候调用该方法
         */
        public void stopAdComponent() {
            stopTimer();
        }
    
        /**
         * 停止自动滚动的任务
         */
        public void stopTimer() {
            timeRunning = false;
            if (mTimer != null) {
                mTimer.cancel();
                mTimer = null;
            }
        }
    
        /**
         * 开始自动滚动的任务,注意,只有图片个数大于1的时候才会自动滚动
         */
        public void startTimer() {
            timeRunning = true;
            if (mTimer == null && getSize() > 1 && mSwitchTime > 0) {
                mTimer = new Timer();
                mTimer.schedule(new PagerTimerTask(), mSwitchTime, mSwitchTime);
            }
        }
    
        private class PagerTimerTask extends TimerTask {
    
            @Override
            public void run() {
                currentIndex++;
                pagerCurrent++;
                mHandler.sendEmptyMessage(0);
            }
        }
    
        private class MyOnPageChangeListener implements OnPageChangeListener {
    
            @Override
            public void onPageScrollStateChanged(int arg0) {
            }
    
            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }
    
            @Override
            public void onPageSelected(int position) {
                pagerCurrent = position;
                currentIndex = position % getSize();// 更新当前页面
                updateIndicator(currentIndex);
            }
        }
    
        /**
         * 更新圆点指示器
         */
        private void updateIndicator(int position) {
            if (!isEmpty() && position < getSize()) {
                if (getSize() > 1) {
                    resetAllIndicator(getSize());// 重置所有的指示器为为选择状态
                    View v = mIndicatorLayout.findViewWithTag(position);
                    if (v != null) {
                        v.setBackgroundResource(R.drawable.circle_indicator_selected);// 点亮
                    }
                }
            }
        }
    
        /**
         * 重置所有的指示器
         */
        private void resetAllIndicator(int size) {
            if (mIndicatorLayout != null) {
                for (int i = 0; i < size; i++) {
                    View v = mIndicatorLayout.findViewWithTag(i);
                    if (v != null) {
                        v.setBackgroundResource(R.drawable.circle_indicator_normal);
                    }
                }
            }
        }
        
        @SuppressLint("HandlerLeak")
        private Handler mHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                mViewPager.setCurrentItem(pagerCurrent);
            };
        };
    }
    
    

    当网络加载图片url列表成功之后,只需调用mAdComponent.updateAdComponent();即可

    例如我的代码

    private void updateAdSources(List<HomeBannerDTO> list) {
            imageUrls.clear();
            for (HomeBannerDTO dto : list) {
                imageUrls.add(dto.getUrl());
            }
            mBannerList.clear();
            mBannerList.addAll(list);
            //更新banner组件
            mAdComponent.updateAdComponent();
            LogHelper.d(TAG, "updateAdComponent .....");
            SettingsMgr.setLastRecommendAdList(mCxt, mBannerList);
        }
  • 相关阅读:
    游遍中国 —— 大街小巷、秘境与远方
    Batch Normalization 反向传播(backpropagation )公式的推导
    Batch Normalization 反向传播(backpropagation )公式的推导
    【社会/人文】概念的理解 —— 断舍离、饭(饭制版)
    【社会/人文】概念的理解 —— 断舍离、饭(饭制版)
    linux 线程的同步 一 (互斥量和信号量)
    linux find
    正则表达式30分钟入门教程-新
    linux sed命令详解 *****
    linux vim tutor
  • 原文地址:https://www.cnblogs.com/xgjblog/p/4226972.html
Copyright © 2011-2022 走看看