用ViewPager實現(xiàn)無縫循環(huán)廣告位

Android上的縫循環(huán)廣告位實現(xiàn)方法似乎有很多種方法吨悍,還有的大神用RecyclerView實現(xiàn)了。但是,我試了一下用ViewPager瞧毙,好像這個更簡便一點。
先看一下效果圖:


ViewPagerAD.gif

demo中用到了:

  1. Gson 一個谷歌的Json解析庫寄症,速度快宙彪,很好用。
  2. Glide 用于加載圖片的第三方庫有巧,如絲般順暢释漆。
  3. Volley 網(wǎng)絡(luò)請求的第三方庫,比較早就有了篮迎,現(xiàn)在仍很多人用男图。

如果對以上這三個庫不了解的話示姿,建議先去看看。

初始化那些什么的就不說了逊笆,我們直接說重點的栈戳。

布局

很簡單,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>
實現(xiàn)過程

既然用到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()之間循環(huán)
            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請求網(wǎng)絡(luò),拿到數(shù)據(jù):

        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
        StringRequest request = new StringRequest(URL, new Response.Listener<String>() {
            @Override
            public void onResponse(String s) {
                //拿到網(wǎng)絡(luò)請求的數(shù)據(jù)
                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為小圓點。設(shè)置適配器韵卤,啟動線程:

    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);

    }

用于循環(huán)播放的線程:

    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();
                }
                //遞歸循環(huán)骗污,圖片切換速度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()方法里面把循環(huán)線程停掉,不然你退出程序它還在運行:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        isCyclical = false; //Activity退出后沈条,圖片循環(huán)線程停止
    }

主要實現(xiàn)過程就醬紫~

附上全部代碼:

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; //初始值可以設(shè)置大一點,防止左劃到盡頭诅炉。
    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();
                }
                //遞歸循環(huán)蜡歹,圖片切換速度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) {
                //拿到網(wǎng)絡(luò)請求的數(shù)據(jù)
                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()之間循環(huán)
            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退出后月而,圖片循環(huán)線程停止
    }
}

源碼已上傳:Github
有什么錯誤或者建議可以在評論下面留言。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末议纯,一起剝皮案震驚了整個濱河市父款,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瞻凤,老刑警劉巖憨攒,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異阀参,居然都是意外死亡肝集,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門蛛壳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來杏瞻,“玉大人所刀,你說我怎么就攤上這事±袒樱” “怎么了浮创?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砌函。 經(jīng)常有香客問我舰始,道長,這世上最難降的妖魔是什么冗酿? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任寄锐,我火速辦了婚禮,結(jié)果婚禮上劣像,老公的妹妹穿的比我還像新娘乡话。我一直安慰自己,他們只是感情好耳奕,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布绑青。 她就那樣靜靜地躺著,像睡著了一般屋群。 火紅的嫁衣襯著肌膚如雪闸婴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天芍躏,我揣著相機與錄音邪乍,去河邊找鬼。 笑死对竣,一個胖子當著我的面吹牛庇楞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播否纬,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼吕晌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了临燃?” 一聲冷哼從身側(cè)響起睛驳,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎膜廊,沒想到半個月后乏沸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡溃论,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年屎蜓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钥勋。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡炬转,死狀恐怖辆苔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情扼劈,我是刑警寧澤驻啤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站荐吵,受9級特大地震影響骑冗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜先煎,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一贼涩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薯蝎,春花似錦遥倦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至消略,卻和暖如春堡称,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艺演。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工却紧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胎撤。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓啄寡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哩照。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,178評論 25 707
  • 效果圖 一懒浮、ViewPager填充圖片 1.1 布局中申明 由于是顯示廣告條飘弧,所以高度要固定住 1.2 代碼中設(shè)置...
    笑說余生閱讀 9,865評論 9 44
  • 我只是找個地方寫信給自己稽穆,有些話只想說給自己聽冠王,我把那個自己叫做小凡, 小凡有時候是男生舌镶,有時候是女生柱彻,有時候是個...
    令狐書生閱讀 293評論 0 0
  • 家:每次回到大海都像是回家豪娜,接受給我的挑戰(zhàn),不斷蛻變哟楷,在大海面前毫無保留的做真實的自己瘤载,每次離家都是為了更好的回家...
    Moana雪閱讀 715評論 14 4
  • 他的靈魂涂抹在素白瓷器上 門前的柳很早就死了 說一句 “終于可以臥下” 黑色的泥土搗成鵝黃的葉 干了加水,薄了加光...
    我是不是蝎大人閱讀 120評論 4 1