35. 【Android教程】视频页面:ViewPager

ViewPager 是一种可以让用户通过左右滑动来切换页面的控件,通过它我们可以展示超过屏幕尺寸大小的内容,在某种程度上它可以说是实现多页面的最佳方式,同时 ViewPager 还支持任意动态的添加/删除页面。比如我们可以将不同的类别的内容分别放在不同页面当中,然后通过滑动切换不同的类别从而给用户展示不同的页面,这个在类似百度App等新闻类App中非常适用。在 ViewPager 中插入“娱乐”、“国际”、“体育”、“星座”等等新闻类别,然后在不同的 View 中展示不同的新闻内容,还可以根据用户的喜好动态增加/删除某些页面,接下来就一起来看看如何完成多页视图。

1. ViewPager 的特性

大家在使用 Android 手机的时候一定都见过下图的效果:

图片描述

没错,这个就是今天的主角——ViewPager 了。在实际开发过程中,我们大多数时候会采用 Fragment 来展示一个页面而不会直接采用 View,在后面的章节学完 Fragment 之后就会知道,Fragment 可以封装 UI 和逻辑,并且会维护自己的生命周期,所以通过 Fragment 我们可以实现更丰富生动的效果,当然对于 ViewPager 的使用而言其实二者几乎没什么差别,我们现在还是把重点放在 ViewPager 上,在后面学完 Fragment 之后只需要做一些简单的改动即可将 View 替换成 Fragment。ViewPager 和前面所学的 ListView/GridView 类似,也需要一个适配器来完成数据的适配,不同的是 ViewPager 有一个专门的适配器——PagerAdapter,所以我们很多的工作也是围绕着 PagerAdapter 展开。

2. PagerAdapter 的使用方法

类似前面所讲的 BaseAdapter 的四个回调接口(不记得的同学可以返回前面章节回顾一下),PagerAdapter 同样也有类似的回调接口,如下:

  • public Object instantiateItem(ViewGroup container, int position):
    根据传入的 position 创建一个 Page,适配器需要在这个回调里网 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("Mybj Android");container.addView(itemView);return itemView;}
  • public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object):
    根据传入的 position 移除一个 Page
public void destroyItem(ViewGroup container, int position, Object object) {container.removeView((View)object);
}
  • gpublic int getCount():
    返回当前 ViewPager 中可用 View 的数量
public int getCount() {return mList.length;
}
  • public boolean isViewFromObject(@NonNull View view, @NonNull Object object):
    通过instantiateItem()返回的对象可以看做是一个 key,这个方法用来判断传入的 View 是否是之前创建的 key,如下:
public boolean isViewFromObject(View view, Object object) {return view == object;
}

常用的一般就是以上四种回调方法,理解起来都比较简单,其中要注意的是getCountisViewFromObject这两个是必须实现的,而instantiateItem()destroyItem()是可选的,不过大多数场景还是推荐大家实现 4 个回调方法。

3. ViewPager 完整示例

本节将通过一个简单的例子学习 ViewPager 的使用,每一个 Page 将会通过一个 View 来实现(在学习了 Fragment 之后,可以尝试将 View 替换成 Fragment)。例子中的每一个 Page 表示一种类别,在切换过程中我们会接收切换的状态回调,同步更新类别标题。

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.ViewPagerandroid:id="@+id/view_pager"android:layout_width="match_parent"android:layout_height="match_parent"/><TextViewandroid: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 当中,所以我们需要为不同结构的 Page 编写不同的页面,由于本例中每个 Page 的页面结构都一样,所以可以直接复用一套,直接在里面放置一个 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 适配器的编写

适配这一块主要就是对四个回调接口的实现,其实在第 2 小节的描述中已经展示了各个方法的实现方式。

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@Overridepublic Object instantiateItem(@NonNull ViewGroup container, int position) {container.addView(mView.get(position));return mView.get(position);}@Overridepublic void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {container.removeView(mView.get(position));}@Overridepublic int getCount() {return mView.size();}@Overridepublic boolean isViewFromObject(@NonNull View view, @NonNull Object object) {return view == object;}
}

3.4 MainActivity 主逻辑编写

主逻辑主要的任务就是将前面的布局都用上,并通过 Adapter 将数据和布局串联起来,所以我们需要获取到 ViewPager 中每个 View 的实例,设置类别之后传递给 Adpater,绑定的任务就交由Adpater完成。接下来再监听 ViewPager 的滑动状态从而判断当前切换的位置,从而实现同步更新类别标题,整体代码如下:


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<>();@Overrideprotected 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() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {tv.setText(mTitle[position]);}@Overridepublic 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 实现了一个简单的页面切换效果。

4. 小节

本节介绍了 ViewPager 的特点及使用场景,并讲解了 ViewPager 的专属适配器——PagerAdapter 的几个回调函数的使用方法,最后采用 ViewPager 实现了一个简单的例子用于切换不同的页面从而展示不同的类别。这一节中是直接采用 View 来承载每一个 Page,而在实际开发中大多数场景会采用 Fragemnt 来承载 Page,不过对于 ViewPager 的使用到同小异,针对 Fragment 系统提供了两种 Adapter:FragmentPageAdapterFragmentStatePagerAdapter,在学完 Fragement之后大家可以自行修改本节的例子,通过 Fragment 来实现本例的效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 创建和请求sse服务

主要依赖 <!--spring-boot父工程--><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.2.RELEASE</version></parent><dependency><gro…

AOP基础

一、AOP概述 AOP&#xff1a;Aspect Oriented Programming&#xff08;面向切面编程、面向方面编程&#xff09;&#xff0c;其实就是面向特定方法编程。 使用场景&#xff1a;①记录操作日志&#xff1b;②权限控制&#xff1b;③事务管理等。 优势&#xff1a;①代码无侵入…

学校管网的仿写

工字形布局完成 效果 代码部分 在这里插入代码片 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…

密码学 | Random Oracle 随机预言机

​ &#x1f951;原文&#xff1a;究竟什么才是随机预言机呢&#xff1f; - 玄星的回答 &#x1f951;答主指出&#xff1a; 英文维基明明对 随机预言机 给出了两个完全不同的理解&#xff0c;但这两个理解之间的连接词却是 “Stated differently”&#xff0c;即 “换句话说…

Unity ECS

一&#xff1a;前言 ECS与OOP不同&#xff0c;ECS是组合编程&#xff0c;而OOP的理念是继承 E表示Entity&#xff0c;每个Entity都是一个有唯一id的实体。C表示Component&#xff0c;内部只有属性&#xff0c;例如位置、速度、生命值等。S表示System&#xff0c;驱动实体的行为…

npm i 依赖下载失败

git config --global url."https://".insteadOf git://解决npm install 报错 npm ERR code 128 Permission denied_please make sure you have the correct access right-CSDN博客

怎么把相机储存卡里的照片导出来?介绍两种方法

随着摄影技术的不断发展和普及&#xff0c;相机已成为我们记录生活、捕捉美好瞬间的设备。然而&#xff0c;对于许多摄影爱好者来说&#xff0c;如何将相机储存卡里的照片安全、高效地导出到电脑或其他设备中&#xff0c;却成为了一个令人头疼的问题。本文将为您详细介绍从相机…

c++IO

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;本篇文章给大家介绍c中文件操作。 先回忆一下c语言文件操作 void Test_c_bin() {//二进制写ServerInfo info { "127.0.0.1", 8080 };FILE* fout fopen("test.bin", "wb");fwrite(&in…

18 统计网站每日的访问次数

1.将竞赛的数据上传HDFS,查看数据的格式 通过浏览器访问hdfs,查看该文档前面的部分数据 每条数据的字段值之间使用逗号隔开的 &#xff0c;最终时间是第五个自动&#xff0c;获取第五个字段值的中的年月日。 2.通过Idea创建项目mr-raceData ,基础的配置 修改pom.xml,添加依赖 …

Spring Boot集成fastdfs快速入门Demo

1.什么是fastdfs FastDFS 是一个开源的高性能分布式文件系统&#xff08;DFS&#xff09;。它的主要功能包括&#xff1a;文件存储&#xff0c;文件同步和文件访问&#xff0c;以及高容量和负载平衡。主要解决了海量数据存储问题&#xff0c;特别适合以中小文件&#xff08;建议…

从零开始搭建网站(第二天)

今天把之前的htmlcssjs项目迁移过来&#xff0c;直接使用tspiniavue3vite组合&#xff0c;搭建过程可以看从零开始搭建性能完备的网站-思路过程&#xff08;1&#xff09;_自己架设一个芯参数网站-CSDN博客。之后安装一下volar扩展。迁移过来使用Vue重构时发现之前使用的左右两…

学习-官方文档编辑方法

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

电感与磁珠

电感是什么&#xff1f; 电感会通过产生感应电动势的方式来阻碍电流的变化&#xff0c;电流变化率越大&#xff0c;产生的感应电动势越大阻碍电流效果越明显。 [一]品质因数Q: 电感的品质因数Q值定义&#xff1a;电感的Q值也叫作品质因数&#xff0c;其为无功功率除以有功功率…

API请求报错 Required request body is missing问题解决

背景 在进行调用的时候&#xff0c;加载方法&#xff0c;提示以下错误 错误信息如下&#xff1a; {"code": 10001,"msg": "Required request body is missing: XXX","data": null,"extra": null }Required request body…

ubuntu22.04下编译ffmpeg和ffplay

Ubuntu22.04 下编译安装 ffmpeg 和 ffplay 一、下载源码包 1.1 官方下载链接&#xff1a;Download FFmpeg 可以手动下载&#xff0c;也可以命令行下载&#xff1a; wget http://www.ffmpeg.org/releases/ffmpeg-7.0.tar.xz 1.2 下载完解压 tar -xvf ffmpeg-7.0.tar.xz…

《深入浅出多模态》: 多模态经典模型:BLIP

🎉AI学习星球推荐: GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料,配有全面而有深度的专栏内容,包括不限于 前沿论文解读、资料共享、行业最新动态以、实践教程、求职…

多个路由器连接的PC端进行ping通信需要做的事

实验环境&#xff1a; 三台PC三台路由器&#xff0c;并且配置好IP 拓扑图&#xff1a; 需求描述&#xff1a; 在PC0进行与PC2的ping通信&#xff1a; 需求步骤&#xff1a; 1.1首先配置ip&#xff08;略过&#xff09; 1.2我们首先查看在只配置了IP的情况下&#xff0c;P…

Flask中的JWT认证构建安全的用户身份验证系统

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Flask中的JWT认证&#xff1a;构建安全的用户身份验证系统 随着Web应用程序的发展&#xf…

详解IIC通信协议以及FPGA实现

一、IIC简介 IIC也称为I2C&#xff08;Inter-Integrated Circuit&#xff09;由飞利浦公司&#xff08;现在的恩智浦半导体&#xff09;开发&#xff0c;是一种用于短距离数字通信的串行&#xff0c;同步&#xff0c;半双工通信接口协议&#xff1b;传输在标准模式下可以达到10…

【C语言】指针详解(五)

目录 1.字符指针 1.1常量字符串 2.指针数组 3.数组指针 1.字符指针 字符指针就是指向字符的指针&#xff0c;字符指针可以存储字符变量的地址。 举例如下&#xff1a; 定义指针变量pa存a的地址&#xff0c;改变*pa的值&#xff0c;a也会随之改变 。 1.1常量字符串 &#x1f…