当前位置: 首页 > news >正文

【Androidstudio学习笔记】设计引导页功能

设计引导页功能

  • 主目录
    • 功能描述
    • 大致思路
    • 准备工作
    • 代码
      • Activity
      • Adapter
      • 滑动动画
    • 总结

主目录

功能描述

此功能用于新用户第一次进入应用时在部分较为复杂的功能使用前展示的操作流程,当然也可以在后续的其他功能键重新查看引导流程

  1. 展示指定数量的引导页,并且在下面有固定的小圆点记录引导进度,可通过点击圆点切换引导页面(圆点配套颜色提醒,如果圆点和当前页面的索引相同,则显示红色,不同则显示白色,有利于提醒用户当前所在引导页面的位置)
  2. 也可通过左右滑动进行页面的切换,滑动/点击圆点都会触发颜色提醒
  3. 在划至最后一页时,提示用户可退出该引导
  4. 用户第一次打开应用并使用需要引导页引导的功能时,弹出引导页
  5. 点击最后一页的按钮可退出引导功能

大致思路

  1. activity主要用来获取组件,然后传给adapter适配器做剩下的工作
  2. adapter获取到RadioGroup在该节点下创建指定数量的RadioButton组件,并给RadioButton组件添加点击事件,用于切换小圆点和引导页的状态
  3. 给RadioGroup添加监听页面切换状态的回调,用于保证在滑动时小圆点和引导页的索引保持一致

准备工作

  1. 下载/截几张图用来当测试用的引导页
  2. 组件:ViewPager、RadioGroup,Radiobutton
  3. 在res的drawable文件夹中把1.里的图放进去(最好不要用中文)
  4. 在res的layout文件夹中创建两个xml,一个是放viewpager的,一个是放引导图的
<?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"android:orientation="vertical"tools:context=".LaunchSimpleActivity"><androidx.viewpager.widget.ViewPagerandroid:id="@+id/vp_launch"android:layout_width="match_parent"android:layout_height="match_parent"></androidx.viewpager.widget.ViewPager><RadioGroupandroid:id="@+id/rg_group"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:orientation="horizontal"android:layout_marginBottom="20dp"/>
</RelativeLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 这是引导图片的图像视图 --><ImageViewandroid:id="@+id/iv_launch"android:layout_width="match_parent"android:layout_height="match_parent"android:adjustViewBounds="true"android:scaleType="fitXY" /><!-- 这是最后一页的入口按钮 --><Buttonandroid:id="@+id/btn_start"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="退出引导,进入应用"android:background="@color/white"android:textColor="#499c54"android:textSize="22sp"android:visibility="gone" />"
</RelativeLayout>

代码

Activity

public class LaunchSimpleActivity extends AppCompatActivity {// 声明引导页面的图片数组private int[] lanuchImageArray = {R.drawable.guide_bg1,R.drawable.guide_bg2, R.drawable.guide_bg3, R.drawable.guide_bg4};@Overridepublic void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_launch_simple);// 从布局视图中获取名叫vp_launch的翻页视图ViewPager vp_launch = findViewById(R.id.vp_launch);RadioGroup radioGroup = findViewById(R.id.rg_group);// 构建一个引导页面的翻页适配器LaunchSimpleAdapter adapter = new LaunchSimpleAdapter(vp_launch,radioGroup, this, lanuchImageArray);vp_launch.setAdapter(adapter); // 设置翻页视图的适配器vp_launch.setCurrentItem(0); // 设置翻页视图显示第一页}}

Adapter

public class LaunchSimpleAdapter extends PagerAdapter {List<View> mViewList = new ArrayList<View>(); // 声明一个引导页的视图列表ViewPager viewPager; //装载引导页的viewpager容器RadioGroup radioGroup; // 装载底部小圆点的容器Context mContext; // activity,用于创建新的组件int[] introImages; // 需要展示的引导图的数组// 引导页适配器的构造方法,传入上下文与图片数组public LaunchSimpleAdapter(ViewPager vp_launch,RadioGroup radioGroup, final Context context, int[] imageArray) {this.viewPager = vp_launch;this.introImages = imageArray;this.mContext = context;this.radioGroup = radioGroup;// 根据布局文件item_launch.xml生成视图对象initViewPager();for (int i = 0; i < imageArray.length; i++) {View tem_intro_view = LayoutInflater.from(context).inflate(R.layout.item_launch, null);ImageView iv_launch = tem_intro_view.findViewById(R.id.iv_launch);
//            RadioGroup rg_indicate = intro_view.findViewById(R.id.rg_indicate);Button btn_start = tem_intro_view.findViewById(R.id.btn_start);iv_launch.setImageResource(imageArray[i]); // 设置引导页的全屏图片// 如果是最后一个引导页,则显示入口按钮,以便用户点击按钮进入主页if (i == imageArray.length - 1) {btn_start.setVisibility(View.VISIBLE);btn_start.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// 这里要跳到应用主页Toast.makeText(context, "欢迎您开启美好生活",Toast.LENGTH_SHORT).show();}});}mViewList.add(tem_intro_view); // 把该图片对应的页面添加到引导页的视图列表}initPots();switchPotStatus(0);}// 获取页面项的个数public int getCount() {return mViewList.size();}// 判断当前视图是否来自指定对象public boolean isViewFromObject(View view, Object object) {return view == object;}// 从容器中销毁指定位置的页面public void destroyItem(ViewGroup container, int position, Object object) {container.removeView(mViewList.get(position));}// 实例化指定位置的页面,并将其添加到容器中public Object instantiateItem(ViewGroup container, int position) {container.addView(mViewList.get(position));return mViewList.get(position);}private void initViewPager() {//初始化viewpager的页面变化监听事件viewPager.addOnPageChangeListener(onPageChangeListener);viewPager.setPageTransformer(true,new ZoomOutPageTransformer());}private ViewPager.OnPageChangeListener onPageChangeListener = new ViewPager.OnPageChangeListener() {@Overridepublic void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}@Overridepublic void onPageSelected(int position) {switchPotStatus(position);}@Overridepublic void onPageScrollStateChanged(int state) {}};private void initPots(){for (int i = 0; i < introImages.length; i++) {//需要依次排序RadioButton radio = new RadioButton(mContext); // 创建一个单选按钮radio.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));radio.setButtonDrawable(R.mipmap.unselected_pot); // 设置单选按钮的图标radio.setPadding(10, 0, 10, 0); // 设置单选按钮的四周间距radioGroup.addView(radio); // 把单选按钮添加到页面底部的单选组int index = i;radio.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {viewPager.setCurrentItem(index);switchPotStatus(index);}});}}private void switchPotStatus(int position){int count = radioGroup.getChildCount();for (int i = 0; i < count; i++) {((RadioButton)radioGroup.getChildAt(i)).setButtonDrawable(R.mipmap.unselected_pot);}((RadioButton)radioGroup.getChildAt(position)).setButtonDrawable(R.mipmap.selected_pot);radioGroup.invalidate();}}

我在网上查找对应的功能脚本时,发现没有我想要的小圆点保持悬浮状态在屏幕下方的功能,因此我的代码添加了一些细节

滑动动画

import android.annotation.SuppressLint;import android.util.Log;import android.view.View;import androidx.viewpager.widget.ViewPager;public class ZoomOutPageTransformer implements ViewPager.PageTransformer {private static final float MIN_SCALE = 0.85f;private static final float MIN_ALPHA = 0.5f;@SuppressLint("NewApi")public void transformPage(View view, float position) {int pageWidth = view.getWidth();int pageHeight = view.getHeight();if (position < -1) { // [-Infinity,-1)// This page is way off-screen to the left.view.setAlpha(0);} else if (position <= 1) //a页滑动至b页 ; a页从 0.0 -1 ;b页从1 ~ 0.0{ // [-1,1]// Modify the default slide transition to shrink the page as wellfloat scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));float vertMargin = pageHeight * (1 - scaleFactor) / 2;float horzMargin = pageWidth * (1 - scaleFactor) / 2;if (position < 0) {view.setTranslationX(horzMargin - vertMargin / 2);} else {view.setTranslationX(-horzMargin + vertMargin / 2);}// Scale the page down (between MIN_SCALE and 1)view.setScaleX(scaleFactor);view.setScaleY(scaleFactor);// Fade the page relative to its size.view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE)/ (1 - MIN_SCALE) * (1 - MIN_ALPHA));} else { // (1,+Infinity]// This page is way off-screen to the right.view.setAlpha(0);}}
}

总结

代码量不大,逻辑也不复杂,当前还只是demo阶段,放在正式环境下的话还需要商讨引导页的获取是通过本地直接获取还是从服务器下拉资源。后者的话则还需要添加接入网络部分的代码
xml文件里有的可能会报错,记得自己改一下内容
希望可以帮到需要帮助的兄弟们

相关文章:

【Androidstudio学习笔记】设计引导页功能

设计引导页功能 主目录功能描述大致思路准备工作代码ActivityAdapter滑动动画 总结 主目录 功能描述 此功能用于新用户第一次进入应用时在部分较为复杂的功能使用前展示的操作流程&#xff0c;当然也可以在后续的其他功能键重新查看引导流程 展示指定数量的引导页&#xff0…...

【python】中位数(暴力+最大最小堆)

题目&#xff1a; """ 对给定长度为N的非负整数序列A&#xff0c;计算前奇数项的中位数。 输入&#xff1a;首行表示序列长度N。次行为N个正整数A1至AN。 输出&#xff1a;输出共(N1)/2行&#xff08;向下取整&#xff09;&#xff0c;第i行表示到第A1...2i-1项…...

Avro 如何生成java Bean

作为一种很犀利的序列化的格式&#xff0c;avro在大数据量传输的时候很有优势。记录下。 1&#xff1a; .avsc 文件 {"namespace": "com.avro.bean","type": "record","name": "UserBehavior3","fields&qu…...

EG4003-一颗为微波、红外信号放大及处理输出的数模混合芯片

产品描述&#xff1a; EG4003是一款特意为微波、红外信号放大及处理输出的数模混合芯片&#xff0c;内部集成了运算放大器、双门限电压比较器、参考电压源、延时时间定时器和封锁时间定时器及状态控制器等&#xff0c;专用于防盗报警系统、人体门控制装置、照明控制开关等场合。…...

kafka生产者源码精华总结

kafka的源码阅读起来思路很清晰&#xff0c;命名也很规范。 KafkaProducer值得学习的地方&#xff1a; Kafka的网络部分的设计绝对是一个亮点&#xff0c;Kafka基于NIO封装了一套自己的网络架构&#xff0c;支持一个客户端与多个Broker建立连接。处理拆包和粘包的思路和代码&…...

边界缩小维护最值——倒序枚举/中部切开:1101T2

http://cplusoj.com/d/senior/p/CPNOIPB 发现维护边界缩小类最值很难做&#xff0c;有两种常见方法&#xff1a; 倒序进行&#xff0c;边界就变成扩大了在 m i d mid mid 处切开&#xff0c;复杂度可以均摊...

vue实现购物车案例

要求 可以进行购物车水果删除可以进行水果数量增减可以进行总价计算、购物车商品计算选中所有水果也会一同勾选全选框&#xff0c;全选框勾选也能选中所有水果可以记录购物车状态&#xff0c;当页面关闭后重新打开可以看到原先的购物车数据 功能代码 <!DOCTYPE html>…...

工业4G路由器桥接多网络,提升工业环境网络覆盖

一款专为工业环境应用所设计的物联网通讯设备“工业4G路由器”&#xff0c;它具有多种功能和特性。其中之一就是桥接功能&#xff0c;在工业领域中被广泛应用并起着重要的通信作用。 桥接功能是指工业4G路由器通过无线网络的方式&#xff0c;为不同的工业设备提供网络并将其连…...

docker 存储目录迁移

参考&#xff1a;【Docker专题】WSL镜像包盘符迁移详细笔记 - 掘金 docker迁移 一 默认目录 Windows版本&#xff08;Windows 10 wsl 2&#xff09;docker 默认程序安装到c盘&#xff0c;数据存放于 C:\Users\当前用户名\AppData\Local\Docker\wsl\data\ext4.vhdx 这样会导致…...

Yolo-Z:改进的YOLOv5用于小目标检测

目录 一、前言 二、背景 三、新思路 四、实验分析 论文地址&#xff1a;2112.11798.pdf (arxiv.org) 一、前言 随着自动驾驶汽车和自动驾驶赛车越来越受欢迎&#xff0c;对更快、更准确的检测器的需求也在增加。 虽然我们的肉眼几乎可以立即提取上下文信息&#xff0c;即…...

系列八、Spring IOC有哪些扩展点,在什么时候调用

一、概述 Spring IOC的扩展点是指IOC在加载过程中&#xff0c;如何对即将要创建的bean进行扩展。 二、扩展点 2.1、实现BeanDefinitionRegistryPostProcessor 调用invokeBeanFactoryPostProcessors时&#xff0c;通过实现BeanDefinitionRegistryPostProcessor接口进行扩展。 …...

《AI时代架构师修炼之道:ChatGPT让架构师插上翅膀》

本专注于帮助架构师在AI时代 实现晋级、提高效率的图书 书中介绍了如何使用 ChatGPT 来完成架构设计的各个环节 并通过实战案例展示了ChatGPT在实际架构设计中的应用方法 关键点 1.架构设计新模式&#xff1a;让架构设计更高效、更快捷、更完美。 2.全流程解析&#xff1a;涵盖…...

git命令清单

一、设置和配置 1.初始化一个新的仓库&#xff1a; git init2.克隆&#xff08;Clone&#xff09;一个远程仓库到本地&#xff1a; git clone <repository_url>3.配置用户信息&#xff1a; git config --global user.name "Your Name" git config --global…...

使用Nokogiri和OpenURI库进行HTTP爬虫

目录 一、Nokogiri库 二、OpenURI库 三、结合Nokogiri和OpenURI进行爬虫编程 四、高级爬虫编程 1、并发爬取 2、错误处理和异常处理 3、深度爬取 总结 在当今的数字化时代&#xff0c;网络爬虫已经成为收集和处理大量信息的重要工具。其中&#xff0c;Nokogiri和OpenUR…...

arcpy.message实现探索

arcpy 位置D:\Program Files\GeoScene\Pro\Resources\ArcPy\arcpy\__init__.py ”““AddMessage(消息) 创建可以使用任何GetMessages函数访问的地理处理信息消息(Severity0)。 message(字符串):要添加的消息。”“ arcpy.geoprocessing D:\Program Files\GeoScene\Pro\Re…...

centos卸载自带的Python3.6.8 安装指定的版本号

#卸载python3 rpm -qa|grep python3|xargs rpm -ev --allmatches --nodeps #删除所有残余文件 whereis python3 |xargs rm -frv#查看现有安装的python&#xff0c;验证是否删除干净 whereis python # 安装依赖 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-de…...

《TCP/IP详解 卷一:协议》第5章的IPv4数据报的IHL字段解释

首先说明一下&#xff0c;这里并不解释整个IPv4数据报各个字段的含义&#xff0c;仅仅针对IHL字段作解释。 我们先看下IPv4数据报格式 对于IHL字段&#xff0c; 《TCP/IP详解 卷一&#xff1a;协议》这么解释&#xff1a; IPv4数据报。头部大小可变&#xff0c;4位的IHL字段…...

想去银行的背完这些软件测试面试题,你就稳了...

前言 最近呢有很多的小伙伴问我有没有什么软件测试的面试题&#xff0c;由于我之前一直在忙工作上的事情&#xff0c;没有时间整理面试题&#xff0c;刚好最近休息了一下&#xff0c;顺便整理了一些面试题&#xff0c;现在就把整理的面试题分享给大家&#xff0c;废话就不多说…...

目标检测(Object Detection): 你需要知道的一些概念

文章目录 NMS 非极大值抑制目的步骤 mAP&#xff08;Mean Average Precision&#xff09;步骤 Feature Pyramid Network 特征金字塔结构一阶段检测器Single-Stage Detectors"Anchor-based"的代表RetinaNetAnchor-free 的代表FCOS NMS 非极大值抑制 目的 去除网络输…...

〔001〕虚幻 UE5 发送 get、post 请求、读取 json 文件

✨ 目录 🎈 安装 varest 扩展🎈 开启 varest 扩展🎈 发送 get 请求🎈 发送 post 请求🎈 读取 json 文件🎈 安装 varest 扩展 打开 虚幻商城,搜索 varest 关键字进行检索, varest 是一个 api 调用插件,支持 http/https 请求,也支持 json 文件的读取,最关键是该…...

Android 11开发避坑:为什么你的App获取的Wifi MAC地址总是变?手把手教你配置固定MAC

Android 11开发实战&#xff1a;彻底解决Wifi MAC地址随机化问题最近在开发一个设备管理系统时&#xff0c;遇到了一个棘手的问题&#xff1a;我们的App在Android 11设备上获取的Wifi MAC地址每次都不一样&#xff0c;导致基于MAC地址的设备识别功能完全失效。经过一周的深入研…...

3步解锁专业级MMD创作:Blender插件如何重塑二次元动画工作流

3步解锁专业级MMD创作&#xff1a;Blender插件如何重塑二次元动画工作流 【免费下载链接】blender_mmd_tools MMD Tools is a blender addon for importing/exporting Models and Motions of MikuMikuDance. 项目地址: https://gitcode.com/gh_mirrors/bl/blender_mmd_tools …...

OpenClaw用户如何快速接入Taotoken并开始Agent工作流

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 OpenClaw用户如何快速接入Taotoken并开始Agent工作流 对于使用OpenClaw框架构建AI智能体的开发者而言&#xff0c;快速接入稳定、多…...

PCB虚焊/走线断裂/焊盘脱落工程师易漏判

PCB 故障中&#xff0c;30% 并非元件损坏&#xff0c;而是 PCB 本身的隐性故障—— 虚焊、走线断裂、焊盘脱落、过孔开路。这类故障外观隐蔽、时好时坏、排查难度大&#xff0c;很多工程师反复更换元件仍无法解决&#xff0c;最终误判为 “板报废”。​一、PCB 隐性故障核心成因…...

为什么92%的团队用DeepSeek生成方案仍需人工重写?揭秘缺失的2个元认知层与1套校验协议

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;为什么92%的团队用DeepSeek生成方案仍需人工重写&#xff1f;揭秘缺失的2个元认知层与1套校验协议 当团队将DeepSeek-R1或DeepSeek-VL模型用于技术方案生成时&#xff0c;表面看响应迅速、逻辑连贯&…...

【与我学 ClaudeCode】协作篇 之 Worktree + Task Isolation :目录隔离的并行执行通道

作者&#xff1a;逆境不可逃 技术永无止境 希望我的内容可以帮助到你&#xff01;&#xff01;&#xff01;&#xff01; 大家吼 ! 我是 逆境不可逃 今天给大家带来文章《【与我学 ClaudeCode】协作篇 之 Worktree Task Isolation &#xff1a;目录隔离的并行执行通道》. Le…...

<背包问题>

背包问题是一类组合优化问题&#xff0c;其基本形式是给定一组物品&#xff0c;每个物品都有一个重量和一个价值&#xff0c;以及一个有限的背包容量&#xff0c;目标是在不超过背包容量的前提下&#xff0c;选择物品使得背包中的物品价值最大化。动态规划是解决背包问题的常用…...

【DeepSeek漏洞扫描辅助实战指南】:20年安全专家亲授3大避坑法则与5步提效流程

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek漏洞扫描辅助的核心价值与适用边界 DeepSeek漏洞扫描辅助并非通用型渗透测试引擎&#xff0c;而是一个聚焦于大语言模型&#xff08;LLM&#xff09;应用层安全的轻量级分析工具。其核心价值在…...

3大技术突破:重新定义Switch游戏安装性能极限

3大技术突破&#xff1a;重新定义Switch游戏安装性能极限 【免费下载链接】Awoo-Installer A No-Bullshit NSP, NSZ, XCI, and XCZ Installer for Nintendo Switch 项目地址: https://gitcode.com/gh_mirrors/aw/Awoo-Installer Awoo Installer是一款专为破解版Nintendo…...

实战教程:5步构建基于YOLOv5的FPS游戏智能瞄准系统

实战教程&#xff1a;5步构建基于YOLOv5的FPS游戏智能瞄准系统 【免费下载链接】FPSAutomaticAiming 基于yolov5的FPS游戏AI。 项目地址: https://gitcode.com/gh_mirrors/fp/FPSAutomaticAiming FPSAutomaticAiming是一个基于YOLOv5深度学习算法的FPS游戏自动瞄准系统&…...