用ViewPager实现无缝循环广告位

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


用ViewPager实现无缝循环广告位_第1张图片
ViewPagerAD.gif

demo中用到了:

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

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

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

布局

很简单,ViewPager+LinearLayout。底下的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() {
            @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 imgs;
    private List 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() {
            @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
有什么错误或者建议可以在评论下面留言。

你可能感兴趣的:(用ViewPager实现无缝循环广告位)