ViewPager实现导航页

2023-11-19

我们在首次安装app时,往往会发现会有导航页。
导航页一般用于介绍功能和引导使用,那我们其实可以用ViewPager实现。
ViewPager用于实现多页面的滑动切换效果,使用时需要引入“android.support.v4”包。
好了,我们现在开始就来做一个简单的导航页引导。
首先我们新建一个Android Application Project,我们把自动生成的MainActivity作为应用程序的主界面:
其布局文件我们简单设置下:
activity_main.xml:
<span style="font-size:14px;"><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"
    android:paddingBottom= "@dimen/activity_vertical_margin"
    android:paddingLeft= "@dimen/activity_horizontal_margin"
    android:paddingRight= "@dimen/activity_horizontal_margin"
    android:paddingTop= "@dimen/activity_vertical_margin"
    tools:context="com.example.guidepage.MainActivity" >

    <TextView
        android:layout_width= "wrap_content"
        android:layout_height ="wrap_content"
        android:text ="主界面"
        android:textSize ="22dp"
        android:layout_centerInParent ="true"
        />

</RelativeLayout>
</span>

我们在Layout下新建一个guide.xml作为导航页的布局:
guide.xml:
<span style="font-size:14px;"><?xml version= "1.0" encoding ="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width= "match_parent"
    android:layout_height= "match_parent"
    android:orientation= "vertical" >
   
    <FrameLayout
        android:layout_width= "match_parent"
        android:layout_height="match_parent"
        android:background= "#ff1874CD"
        >
       
        <android.support.v4.view.ViewPager
            android:id= "@+id/guide_viewpager"
            android:layout_width= "match_parent"
            android:layout_height="match_parent"
            />
       
        <!-- 假设导航页有5页 -->
        <!-- 下面这里是设置五个导航点指示 -->
       
        <LinearLayout
            android:layout_width= "wrap_content"
            android:layout_height="wrap_content"
            android:orientation= "horizontal"
            android:layout_gravity="center|bottom"
            android:gravity= "center"
            >
            <ImageView
                android:id= "@+id/dot_01"
                android:layout_width= "0dp"
                android:layout_height="wrap_content"
                      android:layout_weight="1.0"
                android:src= "@drawable/dot_img_selected"
                android:layout_margin="2dp"
                />
            <ImageView
                android:id= "@+id/dot_02"
                android:layout_width= "0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src= "@drawable/dot_img"
                android:layout_margin="2dp"
                />
            <ImageView
                android:id= "@+id/dot_03"
                android:layout_width= "0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src= "@drawable/dot_img"
                android:layout_margin="2dp"
                />
            <ImageView
                android:id= "@+id/dot_04"
                android:layout_width= "0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src= "@drawable/dot_img"
                android:layout_margin="2dp"
                />
            <ImageView
                android:id= "@+id/dot_05"
                android:layout_width= "0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1.0"
                android:src= "@drawable/dot_img"
                android:layout_margin="2dp"
                />
        </LinearLayout >
    </FrameLayout >
</LinearLayout>
</span>
注意:ViewPager组件用的时候一定要写成<android.support.v4.view.ViewPager/>,这个组件中放置的是切换的页面,我们这里还要使用FrameLayout布局,以便于把导航点放置在上面,“导航点”图片dot_img和dot_img_selected分别如下图所示,这个可以自己随便制作一下:
好了,到了这里导航页的布局算是写完了,很简单吧~ O(∩_∩)O
既然需要页面切换,所以我们还需要有五个页面进行介绍。
所以我们再新建五个布局,用于承载五个导航介绍页面,新建scene1.xml:
<span style="font-size:14px;"><?xml version= "1.0" encoding ="utf-8"?>
<LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
    android:layout_width= "match_parent"
    android:layout_height= "match_parent"
    android:orientation= "vertical"
    android:gravity="center"
    >
    <TextView
        android:layout_width= "wrap_content"
        android:layout_height ="0dp"
        android:gravity= "center"
        android:text ="一款手机操作系统"
        android:textColor= "#ffffffff"
        android:textSize= "22sp"
        android:layout_weight ="1.0"
        />
   
    <LinearLayout
        android:layout_width= "match_parent"
        android:layout_height ="0dp"
        android:layout_weight ="5.0"
        android:gravity= "center"
        >
        <ImageView
        android:layout_width= "wrap_content"
        android:layout_height ="wrap_content"
        android:background= "@drawable/android_logo"
        />
    </LinearLayout >
</LinearLayout>
</span>

android_logo是一张图片。
这里我们简单起见,一个scenne只放一张图和一行文字,依照这样的方法,分别又新建了scene2、scene3、scene4。
scene5我们可以加个按钮,点击可以进入应用程序的主界面。scene5.xml:

<span style="font-size:14px;"><? xml version= "1.0" encoding = "utf-8"?>
< LinearLayout xmlns:android ="http://schemas.android.com/apk/res/android"
    android:layout_width= "match_parent"
    android:layout_height= "match_parent"
    android:orientation= "vertical"
    android:gravity= "center"
    >
    <TextView
        android:layout_width= "wrap_content"
        android:layout_height ="0dp"
        android:gravity= "center"
        android:text ="欢迎您的使用"
        android:textSize= "22sp"
        android:layout_weight ="1.0"
        android:textColor= "#ffffffff"
        />
   
    <LinearLayout
        android:layout_width= "match_parent"
        android:layout_height ="0dp"
        android:layout_weight ="5.0"
        android:gravity= "center"
        >
        <ImageView
        android:layout_width= "wrap_content"
        android:layout_height ="wrap_content"
        android:background= "@drawable/android_cicle"
        />
    </LinearLayout >
   
    <LinearLayout
        android:layout_width= "wrap_content"
        android:layout_height ="0dp"
        android:layout_weight ="1.0"
        android:gravity= "center_horizontal"
        >
    <Button
        android:id= "@+id/enter_button"
        android:background= "@drawable/enter_button_bg"
        android:layout_width= "160dp"
        android:layout_height ="wrap_content"
        android:text ="马上体验"
        android:textColor= "#ffffffff"
        android:layout_marginBottom ="40dp"
        />
    </LinearLayout >
</ LinearLayout>
</span>

上面代码中的Button,我们可以看到background属性设置为“android:background="@drawable/enter_button_bg",enter_button_bg.xml是自定义的一个drawable资源文件,主要是控制Button的形状,这里我将它设置为白色边框圆角背景透明:
enter_button_bg.xml:
<? xml version= "1.0" encoding = "utf-8"?>
< shape xmlns:android ="http://schemas.android.com/apk/res/android" >
    <stroke
        android:width= "1.0dp"
        android:color= "#ffffffff"
        />
   
    <corners
        android:radius= "1.0dp"
        />
   
    <solid
        android:color= "#00000000"
        />

</ shape>


下面我们正式开始Activity部分了:
新建 GuidePageActivity,
等等,在这之前,我们先写一个适配器,ViewPager和ListView一样,同样也需要适配器,这个适配器应该继承PagerAdapter。
所以我们先新建一个ViewPagerAdapter.java:
public class ViewPagerAdapter extends PagerAdapter{

     List<View> views; //用于放置导航页
      private Context context;
     
      public ViewPagerAdapter(List<View> views, Context context) {
            super();
            this. views = views;
            this. context = context;
     }

//   获取需要滑动的控件数量
      public int getCount() {
            // TODO Auto-generated method stub
            return views.size();
     }


//   判断是否是同一个元素
      public boolean isViewFromObject(View arg0, Object arg1) {
            // TODO Auto-generated method stub
            return arg0 == arg1;
     }
     
//   超出了缓存数量,销毁
      @Override
      public void destroyItem(View container, int position, Object object) {
            // TODO Auto-generated method stub
          ((ViewPager)container).removeView( views.get(position));
     }
     
//   初始化显示加载图片
      @Override
      public Object instantiateItem(View container, int position) {
           ((ViewPager)container).addView( views.get(position));
            return views.get(position);
     }
}

写完了适配器之后,我们就新建GuidePageActivity:
public class GuidePageActivity extends Activity implements OnPageChangeListener{


     private ViewPager viewPager;
     private List<View> views; //放置需要切换的页面
     private ViewPagerAdapter vpAdater; //适配器
     private int[] layoutIds; //切换页面的布局id
     private int[] dotsIds; //导航点的id
     private ImageView[] dots; //导航点集合
     private Button enterButton;
     
     protected void onCreate (Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
           requestWindowFeature(Window. FEATURE_NO_TITLE); //隐藏标题
           setContentView(R.layout. guide);
          getWindow().setFlags(WindowManager.LayoutParams. FLAG_FULLSCREEN,
                     WindowManager.LayoutParams. FLAG_FULLSCREEN); //设置全屏
           initViews(); //初始化组件
     }
     
     void initViews(){
           LayoutInflater inflater = LayoutInflater. from(this);
            layoutIds = new int[]{R.layout. scene1, R.layout.scene2, R.layout.scene3 ,
                     R.layout. scene4, R.layout. scene5};
            dotsIds = new int[]{R.id. dot_01, R.id. dot_02, R.id.dot_03,
                     R.id. dot_04, R.id. dot_05};
           
           
//         初始化views集合
            views = new ArrayList<View>();
            for( int i=0; i< layoutIds. length; i++){
                 views.add(inflater.inflate( layoutIds[i], null));
           }
           
//         初始化dots
            dots = new ImageView[ dotsIds. length];
            for( int i=0; i< dotsIds. length; i++){
                 dots[i] = (ImageView)findViewById( dotsIds[i]);
           }
           
            viewPager = (ViewPager)findViewById(R.id.guide_viewpager );
            vpAdater = new ViewPagerAdapter( views, this);
            viewPager.setAdapter( vpAdater); //为viewPager设置适配器
           
            //同时需要监听ViewPager滑动的情况,根据滑动的状态设置导航点
            viewPager.setOnPageChangeListener( this);
           
            enterButton = (Button)( views.get( views.size() - 1)).findViewById(R.id.enter_button );
            enterButton.setOnClickListener(
                      new OnClickListener() {
                            public void onClick(View v) {
                                 // TODO Auto-generated method stub
                                Intent intent = new Intent(GuidePageActivity.this , MainActivity.class);
                                startActivity(intent);
                                finish();
                           }
                     }
                     );
     }

     @Override
     public void onPageScrollStateChanged( int arg0) {
            // TODO Auto-generated method stub
           
     }

     @Override
     public void onPageScrolled( int arg0, float arg1, int arg2) {
            // TODO Auto-generated method stub
           
     }


     //根据选定的页面状态设置导航点
     public void onPageSelected( int arg0) {
            //选定arg0位置的页面
            for( int i=0; i< views.size(); i++){
                 if(i == arg0){
                      dots[i].setImageResource(R.drawable. dot_img_selected);
                }
                 else{
                      dots[i].setImageResource(R.drawable. dot_img);
                }
           }
     }
}


注意:requestWindowFeature必须放在setContentView前面,否则会报错:
android.util.AndroidRuntimeException: requestFeature() must be called before adding content.

最后别忘了设置AndroidManifest.xml,把GuidePageActivity设为主活动,原先的MainActivity也需要注册一下。
应该来说,看着注释是不难看懂的。
最后得到的效果:
对了,如果你想要实现只有第一次安装时才导航的效果,其实也很简单,只要设置一个标志isFirst,利用SharedPreference进行存储,每次启动时判断下就行了,这里不再赘述。






本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ViewPager实现导航页 的相关文章

  • 不同 Android 设备上 box2D 中出现奇怪的“口吃”

    我正在用 C 同时开发引擎和游戏 并使用 box2D 作为物理后端 我正在不同的 Android 设备上进行测试 在三分之二的设备上 游戏运行良好 物理效果也很好 然而 在我的 Galaxy Tab 10 1 上 我偶尔会遇到某种 口吃 的
  • Android自定义控件命名空间问题

    我一直在为 Android 开发自定义控件 尽管我尝试按照建议进行操作here https stackoverflow com questions 4495511 how to pass custom component parameter
  • 在代码中旋转按钮(或其中的文本)

    我必须通过编码随机旋转按钮 或里面的文本 它是相同的 API级别低于11是否有button setRotate x 好吧 看了一下 答案是 很复杂 您可以使用旧的动画框架旋转按钮 例如像这样 Button button Button fin
  • 维护 HttpUrlConnection 调用之间的会话(Native/Webview)

    让我从我做的开始desire 我想制作一个应用程序part native and part webviews Problem 维护本机和 webview 部分之间的会话 My 处理方法 this 我打算实现一个本机登录 其中我向用户展示两个
  • 从 BroadcastReceiver 获取方法来更新 UI

    我正在尝试根据变量的变化更新用户界面BroadcastReceiver 因此 我需要调用一个扩展类的方法 以获取我提到的变量 BroadcastReceiver in MainActivity取决于但我无法以任何方式获得真正的返回值 扩展的
  • 如何在 Android 应用程序中单击按钮时打开 Gmail Compose?

    当我的 Android 应用程序中单击按钮时 我尝试打开 Gmail 撰写屏幕 我需要 Google 提供的 API 密钥吗 或者我需要在按钮 onClickListener 中做什么 任何形式的见解都非常值得赞赏 正如 JeffC 指出的
  • FLAG_ACTIVITY_REORDER_TO_FRONT 被忽略

    我有一个包含项目列表的 FragmentActivity 当应用程序处于后台时 可以推送该项目列表 发生这种情况时 我想创建一个状态栏通知并提醒用户更新 当用户单击通知时 活动应重新排序到前面并显示在屏幕上 同时在列表底部显示新项目 所以我
  • Android 8.1 中 Activity 自行旋转并恢复正常

    我的应用程序在所有 Android 版本上运行良好 但我注意到在 Android 8 1 0 Oreo 中 当我将屏幕从纵向活动转到横向活动时 以及当我按后退按钮时 它会显示异常行为 屏幕自动从横向旋转并恢复正常 看起来 Activity
  • 多语言 Android 应用程序:在电子邮件和密码字段中显示英文键盘

    我们正在开发一款多语言 Android 应用程序 针对英语和阿拉伯语 面临的问题是在登录和注册屏幕中 我们希望仅以英文文本输入用户名和密码字段 从而显示英文键盘 无论设备区域设置语言如何 已尝试在 edittext 中设置 inputtyp
  • 在后台服务中持续获取位置更新

    我正在开发需要在后台服务中持续获取位置更新的应用程序 我已经使用了它正在使用的后台粘性服务 但是 即使我添加了启动广播并在那里启动了服务 启动完成后服务也没有启动 服务启动并立即被杀死 另外 这不适用于奥利奥 服务在应用程序关闭几分钟后停止
  • 更改 Android 中的媒体音量?

    我可以更改媒体音量吗 如何 到目前为止我用过这个 setVolumeControlStream AudioManager STREAM MUSIC 但有一个搜索栏并且想要更改媒体音量 而不是铃声音量 那么有人可以告诉我如何更改媒体音量onC
  • Spotify 登录错误 INVALID_CLIENT:无效的重定向 URI android

    我正在制作一个包含 Spotify 集成的应用程序 我点击了此链接https developer spotify com technologies spotify android sdk tutorial https developer s
  • 如何在Android网格视图中设置单元格大小?

    我正在尝试为应用程序制作一个带有大图标的网格视图 但我找不到任何有关修改 Android 上网格布局上的单元格大小的教程 有人可以给我一个例子或相关链接吗 Thanks 就像另一个一样适配器视图 http developer android
  • 有没有办法在多个嵌套的 RecyclerView 之间共享同一个 LayoutManager

    我正在开发一个显示游戏列表的应用程序 在每个游戏的 itemView 内 我还有一个要显示的视频列表 预览和结构如下 我部署了一个RecyclerView作为窗口根视图 然后对于视频 我使用网格样式的RecyclerView来显示 所以这里
  • 如何更改 Android 12 启动屏幕中的图标形状?

    我想要矩形形状的启动屏幕图标 而不是 android 12 中的圆形形状 我不相信你可以 如果你看这里的第 3 点 https developer android com about versions 12 features splash
  • BitmapFactory.decodeResource() 忽略 jpg 图像的 inPreferredConfig 选项

    我尝试将jpeg资源图像加载到ARGB 8888格式的位图 BitmapFactory Options opts new BitmapFactory Options opts inPreferredConfig Bitmap Config
  • 从Android客户端登录appengine

    我正在尝试登录应用程序引擎并访问应用程序引擎中的用户服务API 基本上我希望能够看到谁登录了我的 servlet 我正在使用从 android 获取 authtoken 然后从应用程序引擎获取 ASID 或 SACID cookie 的身份
  • SDK尚未初始化,请务必先调用FacebookSdk.sdkInitialize()

    我在实现 Facebook SDK 时遇到此错误 并且我tried https stackoverflow com questions 15490399 error inflating class com facebook widget l
  • 在片段之间切换时底部导航栏会向下推

    在我的活动中 我有一个底部导航栏和框架布局来显示片段 一切正常 但问题是当我开始按顺序从 1 4 移动时 底部导航栏保持在其位置 但当我突然从 4 跳到2 然后底部导航栏就会超出屏幕 当再次单击同一项目时 它就会回到正常位置 该视频将清楚地
  • 如何在 onDraw() 方法中定义与像素无关的高度

    我扩展了 View 来构建自定义小部件 我想用独立的像素单位定义小部件的高度 我认为可以通过将像素密度乘以所需的高度来完成 但我不知道该怎么做 到目前为止我所拥有的 最小化 public class Timeline extends Vie

随机推荐

  • Flutter BottomNavigationBar组件(底部导航栏)

    Flutter BottomNavigationBar 组件 BottomNavigationBar 常见的属性 属性名 说明 items List 底部导航条按钮集合 页面集合 iconSize icon currentIndex 默认选
  • 单相逆变器第二课、DC/AC电路基础理论学习

    这周是真心忙 到现在才把DC AC单相部分的理论知识看完 但由于是第一次接触电力电子 写的不好的地方 大家轻喷 DC AC变换电路成为逆变 也就是直流电压 电流 向交流电压 电流 变化 先来看下电压型逆变器 电压型逆变器主要有三类 电阻负载
  • 90 后学霸博士 8 年进击战:用机器学习为化工研究叠 BUFF

    本文首发自微信公众号 HyperAI超神经 内容一览 ScienceAI 作为近两年的技术热点 引起了业界广泛关注和讨论 本文将围绕 ScienceAdvances 的一篇论文 介绍如何利用机器学习 对燃煤电厂的胺排放量进行预测 关键词 A
  • 简短的 mouseover 显示与隐藏层的办法

    简短的 mouseover 显示与隐藏层的办法 在制作 mouseover 和 mouseout 显示 隐藏层的时候 有时总会出现 mouseover 层里面的对象时 层消失的情况 这是因为mouseover 层内 对象时 会对前层产生两个
  • 从零开始学习OpenWrt完美教程

    Cisco Linksys在2003年发布了WRT54G这款无线路由器 同年有人发现它的IOS是基于Linux的 然而Linux是基于GPL许可证发布的 按照该许可证Cisco应该把WRT54G 的IOS的源代码公开 2003年3月 Cis
  • ASP.NET Core项目无法使用命令行执行ef命令

    在项目目录下 打开命令行窗口 执行dotnet ef help 提示以下信息 报错信息 无法执行 因为找不到指定的命令或文件 可能的原因包括 你拼错了内置的 dotnet 命令 你打算执行 NET Core 程序 但 dotnet ef 不
  • mv:重命名和移动文件、文件夹

    在Linux中 mv命令可以用于重命名和移动文件 也可以用于重命名和移动文件夹 注意 如果目标目录已经存在同名的文件或文件夹 mv命令将覆盖目标文件或合并目标文件夹 请注意 在使用mv命令时要小心 确保提供正确的文件名和路径 以免误操作造成
  • 这样的程序员年薪可以达到多少呢?

    转载于 https www cnblogs com Rainbow890722 p 10456640 html
  • 美媒体称谷歌卫星技术可实时定位全球军舰

    5月17日 美国 AOL防务 网站刊登文章 称谷歌公司将推出一款新软件 可让用户对任何一艘海上船只进行实时追踪定位并了解水深数据 包括美海军军舰 做了美军做不到的事 据悉 谷歌公司耗资数百万美元发展能够精确定位船只方位并搜集水深数据的卫星技
  • Redis 跳跃表

    跳跃表 跳跃表基础知识 跳跃表 网易公开课 gt 跳跃表 总结 效率堪比各种平衡树结构 如红黑树 B树 B 树 实现起来简单 仅用到链表的知识 基于概率论 有个随机过程 但表现不错
  • 神经网络优化(损失函数:自定义损失函数、交叉熵、softmax())

    参考 神经网络优化 损失函数 自定义损失函数 交叉熵 softmax 云 社区 腾讯云 1 前向传播 搭建网络结构 反向传播 训练网络参数 2 激活函数 提高了模型的表达里 使模型更具有表达力 3 神经网络的层数 通常用神经网络的层数和神经
  • 区块链应用技术学习(一)

    众所周知 区块链技术的特性就在于其去中心化与不可篡改性 由于这俩点的特性的存在 使得区块链技术的发展颇有看头 于是小编我也踏上了区块链学习的过程 文章目录 前言 一 区块链是什么 二 区块链作用 1 企业 2 个人 总结 前言 在学习区块链
  • Android资源管理中的SharedLibrary和Dynamic Reference-------之资源共享库(一)

    一 引言 共享库的概念 相信大家都有所了解 它有有许多优点 可以设想 在一个系统上要跑100个应用 并且它们都使用到了同一个库 如果这个库做成静态库 那么每个应用中都要打包一次这个库 100个应用就是100次 这无疑是重复的 我们可不可以在
  • FIFO读写控制

    如果在两个模块之间传输数据 两个模块之间的处理速率不同 会导致采集数据的遗漏或错误 在他们之间加一个数据缓存器 所有数据先经过缓存器缓存 再输入数据接送模块 创建两个模块 一个 作为发送模块 一个作为接受模块 发送模块检测到 fifo为空开
  • Python3,2行代码,多种方法,直接把网页内容转换成PDF文档和图片。

    网页转换成PDF 1 引言 2 代码实战 2 1 模块介绍 2 1 1 pdfkit 2 2 安装 2 3 代码实例 2 3 1 URL 对应网页转 PDF 2 3 2 HTML 文件转 PDF 2 3 3 字符串转 PDF 2 4 拓展
  • C++中protected访问权限问题

    今天发现有这样两句话 1 基类的保护成员对于派生类的成员是可访问的 2 派生类的成员只能通过派生类对象访问基类的保护成员 派生类对一个基类对象中的受保护成员没有访问权限 这两句话看的太头晕了 其实作者应该是想表达 只有在派生类中才可以通过派
  • Spring-boot+Dubbo(直连模式)

    Spring boot Dubbo 直连模式 Demo 这里应该有很多人会问 直连模式 什么鬼啊 一般情况下我们进行微服务开发时 都是通过zookeeper等注册中心来实现服务的提供和引用的 那直连模式没啥用啊 其实不然 直连模式大有用处
  • 基于51单片机汽车胎压温度监测报警系统(程序+仿真+原理图+元件清单)

    功能介绍 采用51单片机作为主控单片机 通过采集传感器的胎压和DS18b20的温度 显示到LCD1602上面 并且可以通过按键设置温度和压力的阈值 超过此值蜂鸣器进行报警 可以及时的提醒驾驶员胎压或者温度异常 程序采用keil编写 并且有中
  • 【翻译】容器解决方案加入了绿色软件基金会

    8月 Container Solution加入了绿色软件基金会 主要由微软设立 因为坦率地说他们有大笔资金 以帮助促进和支持我们迫切需要的气候意识的软件开发方法 Container Solution的技术伦理学家Anne Currie将是我
  • ViewPager实现导航页

    我们在首次安装app时 往往会发现会有导航页 导航页一般用于介绍功能和引导使用 那我们其实可以用ViewPager实现 ViewPager用于实现多页面的滑动切换效果 使用时需要引入 android support v4 包 好了 我们现在