自定義View(二)ViewPage廣告輪播

来源:http://www.cnblogs.com/chenyangqi/archive/2016/08/18/5784938.html
-Advertisement-
Play Games

自定義View的第二個學習案例,使用ViewPage實現廣告輪播,通過組合現有的View實現效果如下: 有關ViewPage使用可以學習谷歌官方API,和訓練案例: 1.使用ViewPage實現屏幕滑動:https://developer.android.com/training/animation ...


自定義View的第二個學習案例,使用ViewPage實現廣告輪播,通過組合現有的View實現效果如下:

有關ViewPage使用可以學習谷歌官方API,和訓練案例:

1.使用ViewPage實現屏幕滑動:https://developer.android.com/training/animation/screen-slide.html

2.API:https://developer.android.com/reference/android/support/v4/view/ViewPager.html

viewPage試用範圍較廣 比如tab切換,和引導頁面等。學習過程中遇到一個問題,使用setCurrentItem(posetion)實現頁面定位時會報錯誤,需要重新設定Adapter

viewPage.setAdapter(new MyViewPageAdapter());
viewPage.setCurrentItem(posetion, true);

 

Monition分下如下,性能方面應該不存在bug

 

1:佈局和資源文件如下是:

主頁面佈局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.demo.cyq.MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toobar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

    </android.support.v7.widget.Toolbar>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPage"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_below="@+id/toobar">

    </android.support.v4.view.ViewPager>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@id/viewPage"
        android:background="#44000000"
        android:gravity="center_horizontal"
        android:orientation="vertical">

        <TextView
            android:id="@+id/imgDescription"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:text=""
            android:textColor="#FFFFFF"
            android:textSize="20sp" />

        <LinearLayout
            android:id="@+id/ll_point_group"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal"
            android:orientation="horizontal">

        </LinearLayout>
    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="viePage實現輪播"
        android:textSize="26sp" />
</RelativeLayout>

下標圓點:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/point_press" android:state_enabled="false" />
    <item android:drawable="@drawable/point_normal" android:state_enabled="true"/>
</selector>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:width="8dp"
        android:height="8dp"/>
    <solid android:color="#ff0000"/>

</shape>
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">

    <size android:width="8dp"
        android:height="8dp"/>
    <solid android:color="#FFFFFF"/>

</shape>

MainActivity.class類

 

package com.demo.cyq;

import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private Toolbar toolbar;
    private ViewPager viewPage;
    private TextView imgDescription;
    private ArrayList images;
    private LinearLayout ll_point_group;
    private int[] imgesId = {R.mipmap.banner1, R.mipmap.banner2, R.mipmap.banner3, R.mipmap.banner4};
    private String[] imgDescriptions = {"Facebooks Audience Network", "新一代Mac Pro發佈", "全國大學生珠三角論壇", "Maple 2016"};
    private int presentPostion = 0;
    private final int OPTION_TYPE_AUTO = 1, OPTION_TYPE_POINT = 2;
    private static int pointClickPosition = 0; //point點擊的位置
    private boolean isDraging = false;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            int option = msg.what;
            switch (option) {
                case OPTION_TYPE_AUTO: //option==1執行viewPage跳轉到下一個
                    int currentPostion = viewPage.getCurrentItem();//獲得當前的ViewPage位置
                    viewPage.setCurrentItem(++currentPostion, true);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);//回調handler 實現自動輪播
                    break;
                case OPTION_TYPE_POINT:
                    //重新設置Adapter 這個地方不設置就會報如下錯誤 很詭異:
                    // The specified child already has a parent. You must call removeView() on the child's parent first
                    int currentPostion2 = viewPage.getCurrentItem();//獲得當前的ViewPage位置
                    viewPage.setAdapter(new MyViewPageAdapter());
                    viewPage.setCurrentItem(currentPostion2 - currentPostion2 % images.size() + pointClickPosition, true);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);//回調handler 實現自動輪播
                    break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        toolbar = (Toolbar) findViewById(R.id.toobar);
        toolbar.setTitle("ViewPage實現圖片輪播");
        setSupportActionBar(toolbar);

        viewPage = (ViewPager) findViewById(R.id.viewPage);
        ll_point_group = (LinearLayout) findViewById(R.id.ll_point_group);
        imgDescription = (TextView) findViewById(R.id.imgDescription);

        images = new ArrayList<ImageView>();

        for (int i = 0; i < imgesId.length; i++) {
            ImageView image = new ImageView(this);
            image.setBackgroundResource(imgesId[i]);
            images.add(image);

            ImageView point = new ImageView(this);
            point.setBackgroundResource(R.drawable.point_selecte);
            //為Point設置佈局參數 應為point的父節點是LinerLayout,所以需要使用LinearLayout.LayoutParams
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
            params.bottomMargin = 20;
            if (i == 0)
                point.setEnabled(false);
            else {
                point.setEnabled(true);
                params.leftMargin = 20;
            }
            point.setLayoutParams(params);
            ll_point_group.addView(point);
        }
        viewPage.setAdapter(new MyViewPageAdapter());
        //初始化顯示imgDescription
        imgDescription.setText(imgDescriptions[presentPostion]);
        //設置初始啟動imageView的位置為1000的中間,避免初始為0時不能向左滑動
        viewPage.setCurrentItem(1000 / 2 - 1000 / 2 % images.size(), true);
        //設置ViewPage頁面切換的監聽事件
        viewPage.addOnPageChangeListener(new MyPageChangeListener());
        //延遲發送handler消息 用於啟動ViewPage自動輪播
        handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 2000);

        for (int i = 0; i < ll_point_group.getChildCount(); i++) {
            final View point = ll_point_group.getChildAt(i);
            final int finalI = i;
            point.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    pointClickPosition = finalI;
                    handler.removeCallbacksAndMessages(null);
                    handler.sendEmptyMessageDelayed(OPTION_TYPE_POINT, 50);
                    for (int j = 0; j < ll_point_group.getChildCount(); j++) {
                        ll_point_group.getChildAt(j).setEnabled(true);
                    }
                    point.setEnabled(false);
                }
            });


        }
    }

    /**
     * viewPage切換監聽
     */
    class MyPageChangeListener implements ViewPager.OnPageChangeListener {
        /**
         * 當頁滑動的時候 回調該方法
         *
         * @param position             當前滑動頁面的位置
         * @param positionOffset       當前頁面滑動的百分比
         * @param positionOffsetPixels 當前頁面滑動的像素
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        /**
         * 頁面被選中後已完全顯示時調用改方法
         *
         * @param position 被選中的頁面的位置
         */
        @Override
        public void onPageSelected(int position) {
            imgDescription.setText(imgDescriptions[position % imgDescriptions.length]);
            ll_point_group.getChildAt(presentPostion % images.size()).setEnabled(true);
            ll_point_group.getChildAt(position % imgDescriptions.length).setEnabled(false);
            presentPostion = position;
        }

        /**
         * 頁面滑動的狀態
         * 靜止-滑動
         * 滑動-靜止
         * 靜止-拖拽
         *
         * @param state
         */
        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == viewPage.SCROLL_STATE_DRAGGING) { //拖拽狀態
                isDraging = true;
                //如果處於拖拽狀態 就移除handler 避免拖拽過程中自動輪播、
                handler.removeCallbacksAndMessages(null);
            } else if (state == viewPage.SCROLL_STATE_SETTLING) {//滑動狀態

            } else if (state == viewPage.SCROLL_STATE_IDLE) {//休閑狀態
                isDraging = false;
                //拖拽結束後調用改方法 先移除handler 然後重新發送handler 啟動自動 輪播
                handler.removeCallbacksAndMessages(null);
                handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);
            }

        }
    }

    /**
     * pageAdaapter適配器
     */
    class MyViewPageAdapter extends PagerAdapter {

        /**
         * 返回ViewPage總數
         *
         * @return
         */
        @Override
        public int getCount() {
            return 1000;
        }

        /**
         * 返回ViewPage中的position位置處的ImageView
         *
         * @param container 代表ViewPage
         * @param position  位置
         * @return 返回ViewPage
         */
        @Override
        public Object instantiateItem(ViewGroup container, final int position) {
            ImageView imageView = (ImageView) images.get(position % images.size());
            container.addView(imageView);

            //監聽Touch事件 長按圖片時禁止viewpage滾動
            viewPage.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View view, MotionEvent motionEvent) {
                    switch (motionEvent.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            //滑鼠按下的時候移除handler
                            handler.removeCallbacksAndMessages(null);
                            break;
                        case MotionEvent.ACTION_MOVE:

                            break;
                        case MotionEvent.ACTION_UP:
                            //滑鼠抬起的時候移除handler 並且重新發送handler
                            handler.removeCallbacksAndMessages(null);
                            handler.sendEmptyMessageDelayed(OPTION_TYPE_AUTO, 3000);
                            break;
                    }
                    return false; //返回false 表示不消費觸摸操作 任然可以觸發其他操作
                }
            });

            //為當前imageView設置點擊監聽
            imageView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this, imgDescriptions[position % imgDescriptions.length], Toast.LENGTH_SHORT).show();
                }
            });

            return imageView;
        }

        /**
         * 工系統調用 判斷instantiateItem方法返回的View是否和object相同
         *
         * @param view   instantiateItem方法返回的ImageView
         * @param object
         * @return
         */
        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }

        /**
         * 供系統調用 用於銷毀ViewPage中的object
         *
         * @param container
         * @param position
         * @param object
         */
        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
        }
    }
}

 


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

-Advertisement-
Play Games
更多相關文章
  • Swift - 用UIScrollView實現視差動畫效果 效果 源碼 https://github.com/YouXianMing/Swift-Animations ...
  • 3 RenderScript運行時層與反射層 3.1 RenderScript運行時層 RenderScript運行時層是指.rs代碼運行時所在的層級。當對安卓項目進行編譯的時候,.rs或者.rsh中編寫的代碼都會被llvm編譯器編譯成位元組碼。當該安卓應用在設備上運行的時候,這些位元組碼將會被設備上另 ...
  • 簡單敘述了在開發過程中遇到的 autoresizing 及 autoresizingMask 相關的問題 ...
  • 1、前言 瞭解了簡單圖文混排 (屬性字元串的使用)及 正則表達式的部分知識,為了加深印象,寫了個簡單表情鍵盤demo 展示文字用的是 UITextView 由於時間匆忙,存在一些bug,以及不完善的地方,僅作為小demo 練習一下 圖文混排可以用 TextKit ,下次有時間學習下 環境 xcode ...
  • 菜單事件包括,剪切、拷貝、全選、分享...,此 demo 只有 copy、share 1.定義 field 繼承與 UITextField 2.ViewController 載入 3.分享的實現,以微信為例,準備工作在這裡 完成demo 在 githud,點我查看 ...
  • title: EditText 基本用法 tags: EditText,編輯框,輸入框 EditText介紹: EditText 在開發中也是經常用到的控制項,也是一個比較必要的組件,可以說它是用戶跟Android應用進行數據傳輸的窗戶,比如實現一個登陸界面,需要用戶輸入賬號密碼,然後我們獲取用戶輸入 ...
  • 一、封裝 封裝:隱藏對象的屬性和實現細節,僅對外公開介面,控製程序中屬性的讀和修改的訪問級別。 person.h: person.m: 優點: 1. 隱藏內部實現細節,設置訪問許可權,提高了數據的安全性。 2. 任何出入的數據都要流經介面,通過重寫set方法可以起到過濾數據的作用。 二、繼承 繼承:指 ...
  • Android Weekly Issue #218, 筆記. ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...