android 輪播圖

来源:http://www.cnblogs.com/r-decade/archive/2017/01/10/6270807.html
-Advertisement-
Play Games

輪播圖是很常用的一個效果 核心功能已經實現 沒有什麼特殊需求 自己沒事研究的 所以封裝的不太好 一些地方還比較糙 為想要研究輪播圖的同學提供個參考 目前測試圖片為mipmap中的圖片 沒有寫從網路載入圖片 可自行根據需求在getShowView()方法中修改 1.定時切換 通過handle延時發送通 ...


輪播圖是很常用的一個效果 核心功能已經實現 沒有什麼特殊需求 自己沒事研究的 所以封裝的不太好 一些地方還比較糙 為想要研究輪播圖的同學提供個參考
目前測試圖片為mipmap中的圖片 沒有寫從網路載入圖片 可自行根據需求在getShowView()方法中修改

1.定時切換

通過handle延時發送通知改變界面 然後在切換viewpage的界面之後 再次發送此延時通知 就ok咯 還可以通過timer定時器實現

2.無限輪播效果

如果我們只是在自動輪播到最後一頁 然後進行判斷讓切換到第一頁 這樣是可以實現輪播的效果
但是 有兩個問題

  1. 切換從最後一頁切換到第一頁的時候有一個很明顯的回滾效果 不是我們想要的
  2. 當我們手動滑動的時候 在第一頁和最後一頁的時候 無法繼續左右滑動 因為已經沒有下一頁了

先看張圖(偷來的)
enter image description here

不得不說這位兄弟的圖p的很形象 簡直完美

雖然看到的是三張圖 實際上是五張 數據多的時候也按照這種方式添加數據 當view4的時候自動切換到view5時 進行判斷讓到切換到view2 這樣造成的感覺就是最後一張下來是第一張
我們利用viewpage自帶的方法切換界面立即切換沒有滾動效果 當圖片一樣的時候是看不出圖片變化的
setCurrentItem(int item, boolean smoothScroll)
第二個參數設置false 界面切換的時候無滾動效果 預設true

好啦 接下來看代碼

public class BannerViewPager extends FrameLayout {

    private ViewPager viewPager;
    private TextView tvTitle;
    private LinearLayout indicatorGroup;
    private BannerAdapter adapter;
    private List<String> titles;//標題集合
    private List imageUrls;//圖片數據
    private List<View> views;//輪播圖顯示
    private ImageView [] tips;//保存顯示的小圓點
    private int count;//保存imageUrls的總數
    private int bannerTime=2500;//輪播圖的間隔時間
    private int currentItem=0;//輪播圖的當前選中項
    private long releaseTime = 0;//保存觸發時手動滑動的時間 進行判斷防止滑動之後立即輪播
    private final int START=10;
    private final int STOP=20;
    private Context context;
    private Handler handler;

    private final Runnable runnable=new Runnable() {
        @Override
        public void run() {
            long now=System.currentTimeMillis();
            if (now-releaseTime>bannerTime-500){
                handler.sendEmptyMessage(START);
            }else{
                handler.sendEmptyMessage(STOP);
            }
        }
    };


    public BannerViewPager(Context context) {
        super(context);
    }

    public BannerViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
        titles=new ArrayList<>();
        titles.add("標題1");
        titles.add("標題2");
        titles.add("標題3");
        imageUrls=new ArrayList();
        views=new ArrayList<>();
        init(context,attrs);
    }


    private void init(final Context context, AttributeSet attrs){
        View view= LayoutInflater.from(context).inflate(R.layout.layout_banner,this);
        viewPager= (ViewPager) view.findViewById(R.id.banner_view_pager);
        tvTitle= (TextView) view.findViewById(R.id.banner_title);
        indicatorGroup= (LinearLayout) view.findViewById(R.id.banner_indicator);
        handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what){
                    case START:
                        viewPager.setCurrentItem(currentItem+1);
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(runnable,bannerTime);
                        break;
                    case STOP:
                        releaseTime=0;
                        handler.removeCallbacks(runnable);
                        handler.postDelayed(runnable,bannerTime);
                        break;
                }
            }
        };
    }

    /**
     * 初始化數據 以及拿到數據後的各種設置
     * 可以是網路地址  也可是項目圖片數據
     * @param imageUrls
     */
    public void setData(List<?> imageUrls){
        this.imageUrls.clear();
        this.count=imageUrls.size();
        this.imageUrls.add(imageUrls.get(count-1));
        this.imageUrls.addAll(imageUrls);
        this.imageUrls.add(imageUrls.get(0));

        initIndicator();
        getShowView();
        setUI();
    }

    /**
     * 設置標題
     * @param titles
     */
    public void setTitles(List<String> titles){
        this.titles.clear();
        this.titles.addAll(titles);
    }
    /**
     * 設置小圓點指示器
     */
    private void initIndicator(){
        tips=new ImageView[count];
        LinearLayout.LayoutParams layoutParams = new LinearLayout.
                LayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        layoutParams.height=10;
        layoutParams.width=10;
        layoutParams.leftMargin = 5;// 設置點點點view的左邊距
        layoutParams.rightMargin = 5;// 設置點點點view的右邊距
        for (int i=0;i<count;i++){
            ImageView imageView=new ImageView(context);
            if (i == 0) {
                imageView.setBackgroundResource(R.drawable.shape_circle_red);
            } else {
                imageView.setBackgroundResource(R.drawable.shape_circle_white);
            }

            tips[i] = imageView;
            indicatorGroup.addView(imageView, layoutParams);
        }
    }

    /**
     * 獲取顯示圖片view
     */
    private void getShowView(){
        for (int i=0;i<imageUrls.size();i++){
            ImageView imageView=new ImageView(context);
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            if (imageUrls.get(i) instanceof String){

            }else{
                imageView.setImageResource((Integer) imageUrls.get(i));
            }
            views.add(imageView);
        }
    }

    /**
     * 設置UI
     */
    private void setUI(){
        adapter=new BannerAdapter();
        viewPager.setAdapter(adapter);
        viewPager.addOnPageChangeListener(onPageChangeLis);
        viewPager.setCurrentItem(1);
        handler.postDelayed(runnable,bannerTime);
    }

    /**
     * viewPage改變監聽
     */
    private ViewPager.OnPageChangeListener onPageChangeLis=new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageSelected(int position) {
            //計算當前頁的下標
            int max = views.size() - 1;
            int temp = position;
            currentItem = position;
            if (position == 0) {
                currentItem = max - 1;
            } else if (position == max) {
                currentItem = 1;
            }
            temp = currentItem - 1;
            setIndicatorAndTitle(temp);
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            currentItem=viewPager.getCurrentItem();
            switch (state) {
                case 0:
                    //Log.e("aaa","=====靜止狀態======");
                    if (currentItem == 0) {
                        viewPager.setCurrentItem(count, false);
                    } else if (currentItem == count + 1) {
                        viewPager.setCurrentItem(1, false);
                    }
                    break;
                case 1:
//                Log.e("aaa","=======手動拖拽滑動時調用====");
                    releaseTime = System.currentTimeMillis();
                    if (currentItem == count + 1) {
                        viewPager.setCurrentItem(1, false);
                    } else if (currentItem == 0) {
                        viewPager.setCurrentItem(count, false);
                    }
                    break;
                case 2:
//                Log.e("aaa","=======自動滑動時調用====");
                    break;
            }
        }
    };



    /**
     * 設置指示器和標題切換
     * @param position
     */
    private void setIndicatorAndTitle(int position){
        tvTitle.setText(titles.get(position));

        for (int i=0;i<tips.length;i++){
            if (i==position){
                tips[i].setBackgroundResource(R.drawable.shape_circle_red);
            }else{
                tips[i].setBackgroundResource(R.drawable.shape_circle_white);
            }
        }
    }

    /**
     * 適配器
     */
    class BannerAdapter extends PagerAdapter{
        @Override
        public int getCount() {
            return views.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(views.get(position));
            return views.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}

Activity代碼

BannerViewPager banner= (BannerViewPager) findViewById(R.id.banner);
        List<Integer> imageUrl=new ArrayList<>();
        imageUrl.add(R.mipmap.aiyo);
        imageUrl.add(R.mipmap.dipang1);
        imageUrl.add(R.mipmap.ic_launcher);
        banner.setData(imageUrl);
最後提供兩個github上大神封裝好的輪播圖

建議不太會的同學先搞清楚基本的邏輯在使用第三方庫

https://github.com/youth5201314/banner
https://github.com/bingoogolapple/BGABanner-Android



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前面的話   CSS倒影目前只有chrome和safari瀏覽器支持,且需要添加 webkit 首碼。本文將詳細介紹CSS倒影box reflect   語法 webkit box reflect 初始值: none 應用於: 塊級元素(包括inline block) ...
  • [1]語法 [2]灰度 [3]飽和度 [4]褐色 [5]色相 [6]反色 [7]透明度 [8]亮度 [9]對比度 [10]模糊 [11]陰影 ...
  • 新人,小白一枚,剛剛參加工作,所以會在這裡記錄一些遇到的問題。 最近要做的東西,是對一個表格動態的添加行,刪除行,並且對錶格中內容進行非空驗證。 ...
  • 本文對Jquery中$.get(),$.post(),$.ajax(),$.getJSON()的用法進行了詳細的總結,需要的朋友可以參考下,希望對大家有所幫助。 詳細解讀Jquery各Ajax函數: $.get(),$.post(),$.ajax(),$.getJSON() 一,$.get(url, ...
  • http://www.cssauthor.com/best-responsive-admin-templates/#Free ...
  • JavaScript課程 兩日大綱 ● JavaScript基本語法 ● JavaScript函數 ● JavaScript基於對象編程 ● JavaScript BOM對象編程 ● JavaScript DOM對象編程 ● JavaScript JSON格式簡介 *****************... ...
  • 一、官方文檔的說明 in the face of "evil features" such as eval or with, the YUI Compressor takes a defensive approach by not obfuscating any of the scopes cont ...
  • 之前的博文中有介紹關於圖片輪播的實現方式,分別為(含超鏈接): 1、《Android中使用ViewFlipper實現屏幕切換》 2、《Android中使用ViewPager實現屏幕頁面切換和頁面輪播效果》 3、《Android中使用ImageViewSwitcher實現圖片切換輪播導航效果》 今天通 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...