美文网首页UI & Material Design
用ViewPager实现无缝循环广告位

用ViewPager实现无缝循环广告位

作者: Fi7z | 来源:发表于2016-03-15 21:33 被阅读749次

    Android上的缝循环广告位实现方法似乎有很多种方法,还有的大神用RecyclerView实现了。但是,我试了一下用ViewPager,好像这个更简便一点。
    先看一下效果图:


    ViewPagerAD.gif

    demo中用到了:

    1. Gson 一个谷歌的Json解析库,速度快,很好用。
    2. Glide 用于加载图片的第三方库,如丝般顺畅。
    3. Volley 网络请求的第三方库,比较早就有了,现在仍很多人用。

    如果对以上这三个库不了解的话,建议先去看看。

    初始化那些什么的就不说了,我们直接说重点的。

    布局

    很简单,ViewPager+LinearLayout。底下的LinearLayout是用来显示圆点的。

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:orientation="vertical"
        tools:context="com.sonnyzoom.viewpagerad.MainActivity">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="180dp" />
    
        <LinearLayout
            android:id="@+id/linearLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal" />
    
    </LinearLayout>
    
    实现过程

    既然用到ViewPager,肯定需要一个适配器PagerAdapter:

        class MyAdapter extends PagerAdapter {
    
            @Override
            public int getCount() {
                return Integer.MAX_VALUE;  //最大值,可以认为无限大,反正你划不到尽头就行了
            }
    
            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }
    
            @Override
            public Object instantiateItem(ViewGroup container, final int position) {
                //在0~imageViewList.size()之间循环
                int index = position % imageViewList.size();
    
                imageViewList.get(index).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //处理图片点击事件....
                        Log.e("点击图片:",position % imageViewList.size()+"");
                    }
                });
    
                if (imageViewList.size() > 0) {
                    View view = imageViewList.get(index);
                    if (container.equals(view.getParent())) {
                        container.removeView(view);
                    }
                    container.addView(view);
                    return view;
                }
    
    
                return null;
            }
    
            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                int index = position % imageViewList.size();
                container.removeView(imageViewList.get(index));
            }
    
        }
    

    然后用Volley请求网络,拿到数据:

            RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
            StringRequest request = new StringRequest(URL, new Response.Listener<String>() {
                @Override
                public void onResponse(String s) {
                    //拿到网络请求的数据
                    doSomething(s);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                    Log.e(TGA, "", volleyError);
                }
            });
            requestQueue.add(request);
    

    用Gson解析,得到图片的Url的List,即imgs。同时new一个ImageView,用Glide加载后添加到image的List即imageViewList,ImageView dot为小圆点。设置适配器,启动线程:

        private void doSomething(String s) {
    
            DataInfo info = gson.fromJson(s, DataInfo.class);
            DataInfo.DataEntity entity = info.getData();
            imgs = entity.getImgs();
    
            for (int i = 0; i < imgs.size(); i++) {
                ImageView imageView = new ImageView(this);
                imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                Glide.with(this)
                        .load(imgs.get(i).getPic_url_yasha())
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .into(imageView);
                imageViewList.add(imageView);
                ImageView dot = new ImageView(this);
                dot.setImageResource(R.drawable.point_normal);
                dot.setPadding(10, 5, 10, 5);
                linearLayout.addView(dot);
    
            }
    
            MyAdapter adapter = new MyAdapter();
            viewPager.setAdapter(adapter);
            viewPager.setCurrentItem(currentIndex);
            viewPager.addOnPageChangeListener(this);
    
            handler.post(r);
    
        }
    

    用于循环播放的线程:

        private Handler handler = new Handler();
        Runnable r = new Runnable() {
            @Override
            public void run() {
    
                if (isCyclical) {
                    if (System.currentTimeMillis() - lastTime > 2000) {
                        currentIndex++;
                        viewPager.setCurrentItem(currentIndex);
                        lastTime = System.currentTimeMillis();
                    }
                    //递归循环,图片切换速度3秒一张
                    handler.postDelayed(r, 3000);
                }
            }
        };
    

    伴随图片切换而切换的底部小圆点:

        private void setCurrentSelector(int index) {
            for (int i = 0; i < linearLayout.getChildCount(); i++) {
                ImageView child = (ImageView) linearLayout.getChildAt(i);
                if (i == index) {
                    child.setImageResource(R.drawable.point_selected);
                } else {
                    child.setImageResource(R.drawable.point_normal);
                }
            }
        }
    

    最后在onDestroy()方法里面把循环线程停掉,不然你退出程序它还在运行:

        @Override
        protected void onDestroy() {
            super.onDestroy();
            isCyclical = false; //Activity退出后,图片循环线程停止
        }
    

    主要实现过程就酱紫~

    附上全部代码:

    package com.sonnyzoom.viewpagerad;
    
    import android.os.Bundle;
    import android.os.Handler;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.util.Log;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.LinearLayout;
    
    import com.android.volley.RequestQueue;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import com.android.volley.toolbox.StringRequest;
    import com.android.volley.toolbox.Volley;
    import com.bumptech.glide.Glide;
    import com.bumptech.glide.load.engine.DiskCacheStrategy;
    import com.google.gson.Gson;
    import com.sonnyzoom.viewpagerad.bean.DataInfo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
    
        public static final String URL = "http://spark.api.xiami.com/sdk?v=sdk&method=mobile.sdk-image&device_id=de717e77-6330-3c13-b601-e3c6228d4f16&api_key=bbf59448b1d2a0254d033bfe3b4d8a30&call_id=1443063251736&api_sig=5c29b6c2ffed24d7f5b481d7deb0511e";
        public static final String TGA = "MainActivity";
        private ViewPager viewPager;
        private LinearLayout linearLayout;
        private List<DataInfo.DataEntity.ImgsEntity> imgs;
        private List<ImageView> imageViewList;
    
        private int currentIndex=300; //初始值可以设置大一点,防止左划到尽头。
        private long lastTime;
    
        private Gson gson;
    
        private boolean isCyclical = true;
    
        private Handler handler = new Handler();
        Runnable r = new Runnable() {
            @Override
            public void run() {
    
                if (isCyclical) {
                    if (System.currentTimeMillis() - lastTime > 2000) {
                        currentIndex++;
                        viewPager.setCurrentItem(currentIndex);
                        lastTime = System.currentTimeMillis();
                    }
                    //递归循环,图片切换速度3秒一张
                    handler.postDelayed(r, 3000);
                }
            }
        };
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
    
            viewPager = (ViewPager) findViewById(R.id.viewPager);
            linearLayout = (LinearLayout) findViewById(R.id.linearLayout);
    
            imgs = new ArrayList<>();
            imageViewList = new ArrayList<>();
            gson = new Gson();
    
            RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
            StringRequest request = new StringRequest(URL, new Response.Listener<String>() {
                @Override
                public void onResponse(String s) {
                    //拿到网络请求的数据
                    doSomething(s);
                }
            }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError volleyError) {
                    Log.e(TGA, "", volleyError);
                }
            });
            requestQueue.add(request);
    
        }
    
        private void doSomething(String s) {
    
            DataInfo info = gson.fromJson(s, DataInfo.class);
            DataInfo.DataEntity entity = info.getData();
            imgs = entity.getImgs();
    
            for (int i = 0; i < imgs.size(); i++) {
                ImageView imageView = new ImageView(this);
                imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
                Glide.with(this)
                        .load(imgs.get(i).getPic_url_yasha())
                        .diskCacheStrategy(DiskCacheStrategy.ALL)
                        .into(imageView);
                imageViewList.add(imageView);
                ImageView dot = new ImageView(this);
                dot.setImageResource(R.drawable.point_normal);
                dot.setPadding(10, 5, 10, 5);
                linearLayout.addView(dot);
    
            }
    
            MyAdapter adapter = new MyAdapter();
            viewPager.setAdapter(adapter);
            viewPager.setCurrentItem(currentIndex);
            viewPager.addOnPageChangeListener(this);
    
            handler.post(r);
    
        }
    
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    
        }
    
        @Override
        public void onPageSelected(final int position) {
            Log.e("位置:", position + "");
            currentIndex = position;
            int index = position % imageViewList.size();
            setCurrentSelector(index);
            lastTime = System.currentTimeMillis();
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
    
        private void setCurrentSelector(int index) {
            for (int i = 0; i < linearLayout.getChildCount(); i++) {
                ImageView child = (ImageView) linearLayout.getChildAt(i);
                if (i == index) {
                    child.setImageResource(R.drawable.point_selected);
                } else {
                    child.setImageResource(R.drawable.point_normal);
                }
            }
        }
    
    
        class MyAdapter extends PagerAdapter {
    
            @Override
            public int getCount() {
                return Integer.MAX_VALUE;  //最大值,可以认为无限大,反正你划不到尽头就行了
            }
    
            @Override
            public boolean isViewFromObject(View view, Object object) {
                return view == object;
            }
    
            @Override
            public Object instantiateItem(ViewGroup container, final int position) {
                //在0~imageViewList.size()之间循环
                int index = position % imageViewList.size();
    
                imageViewList.get(index).setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //处理图片点击事件....
                        Log.e("点击图片:",position % imageViewList.size()+"");
                    }
                });
    
                if (imageViewList.size() > 0) {
                    View view = imageViewList.get(index);
                    if (container.equals(view.getParent())) {
                        container.removeView(view);
                    }
                    container.addView(view);
                    return view;
                }
    
    
                return null;
            }
    
            @Override
            public void destroyItem(ViewGroup container, int position, Object object) {
                int index = position % imageViewList.size();
                container.removeView(imageViewList.get(index));
            }
    
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            isCyclical = false; //Activity退出后,图片循环线程停止
        }
    }
    

    源码已上传:Github
    有什么错误或者建议可以在评论下面留言。

    相关文章

      网友评论

      • Wark:向左划动空白

      本文标题:用ViewPager实现无缝循环广告位

      本文链接:https://www.haomeiwen.com/subject/axdqlttx.html