Android之ViewPager 第二課

来源:http://www.cnblogs.com/xiaotaoqi/archive/2016/10/26/5998845.html
-Advertisement-
Play Games

在這裡只粘貼部分代碼 在第一課中,只有View滑動完畢,才觸發動畫效果,令滑塊移動,在第二課中,將實現滑塊與View同步運行。 SecondActivity.java 下麵詳細介紹ViewPager.OnPageChangeListener監聽器的三個重寫方法: 當從手指按下,到頁面滑動停止的過程: ...


在這裡只粘貼部分代碼

  在第一課中,只有View滑動完畢,才觸發動畫效果,令滑塊移動,在第二課中,將實現滑塊與View同步運行。

  SecondActivity.java

package com.android3;


import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;

import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;


public class SecondActivity extends AppCompatActivity implements View.OnClickListener, ViewPager.OnPageChangeListener {
    private ArrayList<View> viewList;
    private ImageView cursor;
    private float offset = 0;
    private float screenW = 0;
    private float eCurrentX = 0;
    private Matrix matrix;
    private float fScreenW = 0;
    private int currentIndex = 0;
    private int temp = 1;
    private float sCurrentX;
    private int len;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        initToolbar();
        initViewPager();
    }

    /**
     * ViewPager 保證 緩存中存在三個視圖,即 左邊 右邊 和中間 隔一個的灰被destroy,
     */
    @SuppressLint("InflateParams")
    private void initViewPager() {
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        LinearLayout titleBar = (LinearLayout) findViewById(R.id.titleBar);
        LayoutInflater inflater = getLayoutInflater();
        //創建四個View
        View view1 = inflater.inflate(R.layout.viewpage_01, null);
        View view2 = inflater.inflate(R.layout.viewpage_02, null);
        View view3 = inflater.inflate(R.layout.viewpage_03, null);
        View view4 = inflater.inflate(R.layout.viewpage_04, null);

        viewList = new ArrayList<>();// 將要分頁顯示的View裝入數組中
        viewList.add(view1);
        viewList.add(view2);
        viewList.add(view3);
        viewList.add(view4);
        len = viewList.size();
        MyPagerAdapter adapter = new MyPagerAdapter(viewList);
        List<String> titleList = new ArrayList<>();
        titleList.add("第一頁面");
        titleList.add("第二頁面");
        titleList.add("第三頁面");
        titleList.add("第四頁面");
        for (int i = 0; i < titleList.size(); i++) {
            TextView textView = new TextView(this);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
            params.weight = 1;
            params.setMargins(5, 3, 5, 3);
            textView.setLayoutParams(params);
            textView.setText(titleList.get(i));
            textView.setTextSize(15);
            textView.setGravity(Gravity.CENTER);
            titleBar.addView(textView);
        }

        initCursorPos();   //初始化指示器位置

        viewPager.setAdapter(adapter);//綁定適配器
        viewPager.addOnPageChangeListener(this); //註 : setOnPageChangeListener 過時
    }

    /**
     * 單位px
     */
    public void initCursorPos() {
        // 初始化動畫
        cursor = (ImageView) findViewById(R.id.cursor);
        float cursorW = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor).getWidth();
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        screenW = dm.widthPixels;// 獲取解析度寬度
        fScreenW = screenW / viewList.size();
        offset = (fScreenW - cursorW) / 2;// 計算偏移量
        matrix = new Matrix();
        matrix.postTranslate(offset, 0);
        cursor.setImageMatrix(matrix);// 設置動畫初始位置   ###原始位置
    }

    private void initToolbar() {
        Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
        mToolbar.setTitle("");
        mToolbar.setNavigationIcon(R.mipmap.back);
        setSupportActionBar(mToolbar);
        mToolbar.setNavigationOnClickListener(this);
    }


    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case -1:
                finish();
                break;
        }
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        sCurrentX = positionOffset * fScreenW;
         if(position!=currentIndex){
             temp=1;
             currentIndex=position;
             return;
         }
            if (temp == 0) {
                matrix.postTranslate((sCurrentX - eCurrentX), 0);
                cursor.setImageMatrix(matrix);
                eCurrentX = sCurrentX;

            } else {
                if (positionOffset > 0.5) {
                    eCurrentX = fScreenW;
                } else {
                    eCurrentX = 0;
                }
                temp--;
            }
        currentIndex=position;

    }
    
    @Override
    public void onPageSelected(int position) {
     }

    @Override
    public void onPageScrollStateChanged(int state) {

    }
}

 

下麵詳細介紹ViewPager.OnPageChangeListener監聽器的三個重寫方法:

      當從手指按下,到頁面滑動停止的過程:

首先系統調用onPageScrollStateChanged(int state)方法,其中state=1,表示開始滑動;

然後系統調用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

   position是當前頁面的編號,positionOffset滑動百分比,取值範圍[0,1],positionOffsetPixels滑動長度,取值[0,手機寬度(px)]

/*********************************************************************************/

   在滑動過程中有這幾個因素需要強調:

   1、從左向右滑動   positionOffset和positionOffsetPixels初始值為0,並根據滑動距離增大;

   2、從右向左滑動   positionOffset初始值為1,並根據滑動距離減小,positionOffsetPixels初始值為手機寬度,並根據滑動距離減小;

   3、當position=0時,從右向左滑動,positionOffset和positionOffsetPixels始終為0;

   4、當(position=頁面總數-1)時,從左向右滑動,positionOffset和positionOffsetPixels始終為0;

  /*********************************************************************************/
  可能在滑動過程中手指離開屏幕,這時系統再次調用onPageScrollStateChanged(int state)方法 state=2,當滑動肯定能到下一個頁面時,

positionOffset和positionOffsetPixels都到達最大值,然後再次調用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

這時position為新頁面的編號,positionOffset和positionOffsetPixels置零;

      最後再調用onPageScrollStateChanged(int state)方法 state=0;表示滑動停止;

 

      所以onPageScrolled()方法中代碼就解釋的通了,

     

 sCurrentX = positionOffset * fScreenW;

     fScreenW是滑塊從一個標題滑向另一個標題的距離,sCurrentX是滑動頁面時,滑塊相對走的距離,

     成員變數temp是區分滑動頁面時是否是第一次調用onPageScrolled();併在第一次調用該方法時,判斷是向左滑動還是向右滑動:

               if (positionOffset > 0.5) {
                    eCurrentX = fScreenW;
                } else {
                    eCurrentX = 0;
                }

      滑動停止時,重置temp為1;

      游標滑動採用 matrix.postTranslate((sCurrentX - eCurrentX), 0); cursor.setImageMatrix(matrix); 這兩句代碼,相對位移。

      謝謝

 

可能在滑動過程中手指離開屏幕,這時系統再次調用onPageScrollStateChanged(int state)方法 state=2,

當滑動肯定能到下一個頁面時,positionOffset和positionOffsetPixels都到達最大值,

然後再次調用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

這時position為新頁面的編號,positionOffset和positionOffsetPixels置零;

 

代碼下載    http://download.csdn.net/detail/qq_25059501/9664066

 

作者: 小淘氣兒

出處: http://www.cnblogs.com/xiaotaoqi/p/5998845.html/>

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出.


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

-Advertisement-
Play Games
更多相關文章
  • JS是個神奇的語言,藉助Node.js的後端環境,我們可以進行相應的爬蟲開發,如這篇 基於Node.js實現一個小小的爬蟲 但搭建後臺環境始終略為麻煩,拿到一臺新電腦,不用配環境,可不可以直接在瀏覽器客戶端直接實現呢? 可以可以,這裡就簡單地說一下在瀏覽器客戶端實現的爬蟲抓取頁面數據 一、概念理解 ...
  • 【本次開發環境: Xcode:7.2 iOS Simulator:iphone6 By:啊左 本文Demo下載鏈接:RunLoop-Demo】 基本概念 一、RunLoop簡介 RunLoop,跑圈。在iOS開發中,也就是運行迴圈。 在應用需要的時候自己跑起來運行,在用戶沒有操作的時候就停下來休息。 ...
  • Android Weekly Issue #228 筆記, 本期內容包括: Android 7.1的App Shortcuts; Searchbar的設計討論; Nougat的Direct Reply; Alarms API討論; Support Library的BottomNavigationV... ...
  • 原文地址:http://www.jianshu.com/p/930643270455 總所周知,蘋果從iOS7開始採用扁平化的界面風格,顛覆了果粉們“迷戀”的擬物化風格。對於開發者而言,全新的風格帶來新的介面,這些新的介面改動中,有些更加合理了,有些更加方便了,而有些可能讓開發者容易迷糊,下麵本人就 ...
  • finalize();(不建議使用,代價高,不確定性大) 如果你在一個類中覆寫了finalize()方法, 那麼你可以在第一次被GC的時候,輓救一個你想輓救的對象,讓其不被回收,但只能輓救一次。 ...
  • http://www.androiddevtools.cn/ ...
  • 20161024 打算轉ios開發工程師的崗位 今天看了下視頻,自己吭呲吭呲幾下開始寫UI 先把Xcode8 的界面總結下 navigator ['nævɪɡetɚ] 導航器、瀏覽器 symbol navigator 符號導航器 此導航器提供快速定位至項目中局部標識符的方法,例如組成應用程式的類、協 ...
  • 最近太忙了,一直沒時間 寫博客,項目基本搞完了,這幾天沒事多寫幾篇博客。歡迎加群交流iOS技術,QQ交流群:45992174。 剛裝的xcode8,不知道從哪來的一堆log 去除方法:Xcode8 >Product Edit Scheme... -> Run -> Arguments, 在Envir ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...