第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

Android 入門教程

菜單類控件
菜單:Menu
并發(fā)編程
多線程

視頻頁面:ViewPager

ViewPager 是一種可以讓用戶通過左右滑動來切換頁面的控件,通過它我們可以展示超過屏幕尺寸大小的內(nèi)容,在某種程度上它可以說是實現(xiàn)多頁面的最佳方式,同時 ViewPager 還支持任意動態(tài)的添加/刪除頁面。比如我們可以將不同的類別的內(nèi)容分別放在不同頁面當中,然后通過滑動切換不同的類別從而給用戶展示不同的頁面,這個在類似百度App等新聞類App中非常適用。在 ViewPager 中插入“娛樂”、“國際”、“體育”、“星座”等等新聞類別,然后在不同的 View 中展示不同的新聞內(nèi)容,還可以根據(jù)用戶的喜好動態(tài)增加/刪除某些頁面,接下來就一起來看看如何完成多頁視圖。

1. ViewPager 的特性

大家在使用 Android 手機的時候一定都見過下圖的效果:

圖片描述

沒錯,這個就是今天的主角——ViewPager 了。在實際開發(fā)過程中,我們大多數(shù)時候會采用 Fragment 來展示一個頁面而不會直接采用 View,在后面的章節(jié)學完 Fragment 之后就會知道,F(xiàn)ragment 可以封裝 UI 和邏輯,并且會維護自己的生命周期,所以通過 Fragment 我們可以實現(xiàn)更豐富生動的效果,當然對于 ViewPager 的使用而言其實二者幾乎沒什么差別,我們現(xiàn)在還是把重點放在 ViewPager 上,在后面學完 Fragment 之后只需要做一些簡單的改動即可將 View 替換成 Fragment。ViewPager 和前面所學的 ListView/GridView 類似,也需要一個適配器來完成數(shù)據(jù)的適配,不同的是 ViewPager 有一個專門的適配器——PagerAdapter,所以我們很多的工作也是圍繞著 PagerAdapter 展開。

2. PagerAdapter 的使用方法

類似前面所講的 BaseAdapter 的四個回調(diào)接口(不記得的同學可以返回前面章節(jié)回顧一下),PagerAdapter 同樣也有類似的回調(diào)接口,如下:

  • public Object instantiateItem(ViewGroup container, int position):
    根據(jù)傳入的 position 創(chuàng)建一個 Page,適配器需要在這個回調(diào)里網(wǎng) container 里面添加 View,如下:
public Object instantiateItem(ViewGroup container, int position) {
    View itemView = mLayoutInflater.inflate(R.layout.view_pager, container, false);

    TextView textView = itemView.findViewById(R.id.TextView);
    textView.setText("Imooc Android");
    container.addView(itemView);

    return itemView;
 }
  • public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object):
    根據(jù)傳入的 position 移除一個 Page
public void destroyItem(ViewGroup container, int position, Object object) {
     container.removeView((View)object);
}
  • gpublic int getCount():
    返回當前 ViewPager 中可用 View 的數(shù)量
public int getCount() {
    return mList.length;
}
  • public boolean isViewFromObject(@NonNull View view, @NonNull Object object):
    通過instantiateItem()返回的對象可以看做是一個 key,這個方法用來判斷傳入的 View 是否是之前創(chuàng)建的 key,如下:
public boolean isViewFromObject(View view, Object object) {
    return view == object;
}

常用的一般就是以上四種回調(diào)方法,理解起來都比較簡單,其中要注意的是getCountisViewFromObject這兩個是必須實現(xiàn)的,而instantiateItem()destroyItem()是可選的,不過大多數(shù)場景還是推薦大家實現(xiàn) 4 個回調(diào)方法。

3. ViewPager 完整示例

本節(jié)將通過一個簡單的例子學習 ViewPager 的使用,每一個 Page 將會通過一個 View 來實現(xiàn)(在學習了 Fragment 之后,可以嘗試將 View 替換成 Fragment)。例子中的每一個 Page 表示一種類別,在切換過程中我們會接收切換的狀態(tài)回調(diào),同步更新類別標題。

3.1 整體布局

由于每個頁面都在 ViewPager 中,所以整體的布局非常簡單,我們只需要放置一個 ViewPager 以及一個 TextView 用來顯示當前 Page 的標題即可。

<?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:showIn="@layout/activity_main">

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <TextView
        android:text="Num"
        android:textSize="100sp"
        android:id="@+id/text"
        android:layout_marginTop="50dp"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

3.2 Page 頁面的布局編寫

對于整體布局而言,主要的頁面都在 ViewPager 當中,所以我們需要為不同結(jié)構(gòu)的 Page 編寫不同的頁面,由于本例中每個 Page 的頁面結(jié)構(gòu)都一樣,所以可以直接復用一套,直接在里面放置一個 ImageView 用于展示類別圖片。

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

3.3 適配器的編寫

適配這一塊主要就是對四個回調(diào)接口的實現(xiàn),其實在第 2 小節(jié)的描述中已經(jīng)展示了各個方法的實現(xiàn)方式。

package com.emercy.myapplication;

import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.PagerAdapter;

import java.util.List;

public class MyAdapter extends PagerAdapter {

    private final List<View> mView;

    public MyAdapter(List<View> view) {
        mView = view;
    }

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

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

    @Override
    public int getCount() {
        return mView.size();
    }

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

3.4 MainActivity 主邏輯編寫

主邏輯主要的任務(wù)就是將前面的布局都用上,并通過 Adapter 將數(shù)據(jù)和布局串聯(lián)起來,所以我們需要獲取到 ViewPager 中每個 View 的實例,設(shè)置類別之后傳遞給 Adpater,綁定的任務(wù)就交由Adpater完成。接下來再監(jiān)聽 ViewPager 的滑動狀態(tài)從而判斷當前切換的位置,從而實現(xiàn)同步更新類別標題,整體代碼如下:


package com.emercy.myapplication;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ViewFlipper;

import androidx.viewpager.widget.ViewPager;

import org.w3c.dom.Text;

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


public class MainActivity extends Activity {

    private ViewPager mViewPager;
    private String[] mTitle = new String[]{"蘋果", "香蕉", "荔枝"};
    private List<View> mView = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final TextView tv = findViewById(R.id.text);
        mViewPager = findViewById(R.id.view_pager);
        mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                tv.setText(mTitle[position]);
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });

        ImageView view1 = (ImageView) LayoutInflater.from(this).inflate(R.layout.list_item, null);
        view1.setBackgroundColor(Color.RED);
        view1.setImageResource(R.drawable.apple);
        mView.add(view1);

        ImageView view2 = (ImageView) LayoutInflater.from(this).inflate(R.layout.list_item, null);
        view2.setBackgroundColor(Color.GREEN);
        view2.setImageResource(R.drawable.banana);
        mView.add(view2);

        ImageView view3 = (ImageView) LayoutInflater.from(this).inflate(R.layout.list_item, null);
        view3.setBackgroundColor(Color.BLUE);
        view3.setImageResource(R.drawable.lychee);
        mView.add(view3);

        mViewPager.setAdapter(new MyAdapter(mView));
        tv.setText(mTitle[0]);
    }
}

編譯之后效果如下:

圖片描述

通過左右滑動可以切換不同的頁面,每個頁面對應的一種水果類別,這樣就通過 ViewPager 實現(xiàn)了一個簡單的頁面切換效果。

4. 小節(jié)

本節(jié)介紹了 ViewPager 的特點及使用場景,并講解了 ViewPager 的專屬適配器——PagerAdapter 的幾個回調(diào)函數(shù)的使用方法,最后采用 ViewPager 實現(xiàn)了一個簡單的例子用于切換不同的頁面從而展示不同的類別。這一節(jié)中是直接采用 View 來承載每一個 Page,而在實際開發(fā)中大多數(shù)場景會采用 Fragemnt 來承載 Page,不過對于 ViewPager 的使用到同小異,針對 Fragment 系統(tǒng)提供了兩種 Adapter:FragmentPageAdapterFragmentStatePagerAdapter,在學完 Fragement之后大家可以自行修改本節(jié)的例子,通過 Fragment 來實現(xiàn)本例的效果。