Android用户引导页实现,圆点实现动画效果
发布日期:2021-11-12 07:57:09
浏览次数:27
分类:技术文章
本文共 8713 字,大约阅读时间需要 29 分钟。
原文地址:http://www.cnblogs.com/qu-xinyang/p/5414883.html
当前市面上比较流行的应用,用户引导页已经是一个必不可缺的功能点了,简单的介绍下应用的基础功能或者版本升级功能点介绍。
那么常用的用户引导页是如何实现的呢?这篇文章就说说我个人用到的,并且觉得使用不错的效果。
1、首先定义布局文件guide_layout.xml文件,主要使用ViewPager做页面显示,使用一个圆点布局显示圆点,圆点根据图片数目动态添加。
guide_layout.xml文件的代码如下:
2、使用android中shape属性,定义圆点的背景资源。shape_point_gray.xml的代码如下:
3、activity文件中,定义引导页加载的图片数组,根据数组的长度动态添加知识圆点。根据引导页图片数组长度,动态给指示圆点的父布局(线性布局)添加圆点控件,注意圆点的像素与移动圆点的像素一致。核心代码也很简单,如下代码块即可实现:
for (int i = 0; i < mImageIds.length; i++) { Log.d("Point View", "第" + i + "个圆点"); View point = new View(this);// 设置引导页默认圆点背景 point.setBackgroundResource(R.drawable.shape_point_gray); LayoutParams params = new LayoutParams(DensityUtils.dp2px(this, 12), DensityUtils.dp2px(this, 12)); if(i > 0){ params.leftMargin = DensityUtils.dp2px(this, 10); //从第二个圆点开始设置左间距 } point.setLayoutParams(params); llPointGroup.addView(point); //将圆点添加到线性布局中 }
还需要注意一个点,需要测绘切换页面圆点移动的距离,其实就是两个圆点左边界之间的像素差,也就是切换页面时圆点需要移动的像素值。这里是把测绘过程放在所有圆点添加完成,圆点的父布局完成了布局树的测量之后计算,代码如下:
// 获取视图树, 对layout绘制结束事件进行监听 llPointGroup.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { public void onGlobalLayout() { Log.d("llPointLayout", "llPointLayout绘制结束!"); llPointGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this); if(mPointWidth == 0){ mPointWidth = llPointGroup.getChildAt(1).getLeft() - llPointGroup.getChildAt(0).getLeft(); Log.d("圆点需要移动的距离:", mPointWidth + ""); } } });
然后就是在viewpager的适配器中,重写onPageScrolled方法,就是在移动过程中,不断地给选中圆点设置左边界值,达到一个选中圆点动画效果。
实现代码块如下:
/** * position : 当前的位置 * positionOffset : 位置移动的百分比 * positionOffsetPixels: 位置移动的px像素点 */ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int len = (int) (mPointWidth * positionOffset + position * mPointWidth); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) guidePoint.getLayoutParams(); params.leftMargin = len; //设置选中圆点在父控件中的左间距 guidePoint.setLayoutParams(params); //重新给选中圆点设置布局参数 }
完整的GuideActivity代码如下:
package com.study.tracy.activity; import android.content.Intent; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.LinearLayout.LayoutParams; import android.widget.RelativeLayout; import com.study.tracy.R; import com.study.tracy.adapter.GuideAdapter; import com.study.tracy.base.BaseActivity; import com.study.tracy.constants.FlagConstants; import com.study.tracy.utils.DensityUtils; import com.study.tracy.utils.SharedPrefUtils; import java.util.ArrayList;public class GuideActivity extends BaseActivity { private ViewPager vpGuide; private LinearLayout llPointGroup; //引导圆点的父控件 private View guidePoint; //选中的圆点 private Button startBtn; //开始体验按钮 private Button skipBtn; //跳过按钮 // 引导页背景图片的id数组 private static final int[] mImageIds = new int[] {R.mipmap.user_guide01, R.mipmap.user_guide02, R.mipmap.user_guide03 , R.mipmap.user_guide04, R.mipmap.user_guide05}; private int mPointWidth = 0;// 圆点间的距离 private ArrayListmImageViewList; private String from; @Override public void initViews() { this.setContentView(R.layout.guide_layout);// 获取从哪里进来的入口 from = getIntent().getStringExtra("from"); vpGuide = (ViewPager) findViewById(R.id.vp_guide); llPointGroup = (LinearLayout) findViewById(R.id.ll_point_group); guidePoint = findViewById(R.id.view_guide_point); startBtn = (Button) findViewById(R.id.btn_start); skipBtn = (Button) findViewById(R.id.btn_skip); } @Override public void initDatas() { BaseActivity.isOpenDistanceBack = false; mImageViewList = new ArrayList ();// 初始化引导页的三个页面 ImageView imageView = null; for (int i = 0; i < mImageIds.length; i++) { imageView = new ImageView(this); imageView.setBackgroundResource(mImageIds[i]); // 设置引导页的背景图片 mImageViewList.add(imageView); } for (int i = 0; i < mImageIds.length; i++) { Log.d("Point View", "第" + i + "个圆点"); View point = new View(this);// 设置引导页默认圆点背景 point.setBackgroundResource(R.drawable.shape_point_gray); LayoutParams params = new LayoutParams(DensityUtils.dp2px(this, 12), DensityUtils.dp2px(this, 12)); if(i > 0){ params.leftMargin = DensityUtils.dp2px(this, 10); //从第二个圆点开始设置左间距 } point.setLayoutParams(params); llPointGroup.addView(point); //将圆点添加到线性布局中 } // 获取视图树, 对layout绘制结束事件进行监听 llPointGroup.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { public void onGlobalLayout() { Log.d("llPointLayout", "llPointLayout绘制结束!"); llPointGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this); if(mPointWidth == 0){ mPointWidth = llPointGroup.getChildAt(1).getLeft() - llPointGroup.getChildAt(0).getLeft(); Log.d("圆点需要移动的距离:", mPointWidth + ""); } } }); } @Override public void initListeners() { vpGuide.setAdapter(new GuideAdapter(mImageViewList)); vpGuide.setOnPageChangeListener(new GuidePageListener()); startBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { skipToActivity(); } }); skipBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { skipToActivity(); } }); } private void skipToActivity() { // 更新引导页是否显示为true,下次进入就不显示 SharedPrefUtils.getInstance().setBoolean(FlagConstants.USER_GUIDE, true); // 跳转到登录的Activity中 Intent intent = null;// if("setting".equals(from)){// intent = new Intent(GuideActivity.this, SettingActivity.class);// }else { intent = new Intent(GuideActivity.this, LoginActivity.class);// } startActivity(intent); finish(); } class GuidePageListener implements OnPageChangeListener { // 滑动状态发生变化 public void onPageScrollStateChanged(int arg0) {} /** * position : 当前的位置 * positionOffset : 位置移动的百分比 * positionOffsetPixels: 位置移动的px像素点 */ public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { int len = (int) (mPointWidth * positionOffset + position * mPointWidth); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) guidePoint.getLayoutParams(); params.leftMargin = len; //设置选中圆点在父控件中的左间距 guidePoint.setLayoutParams(params); //重新给选中圆点设置布局参数 } public void onPageSelected(int position) { if(position == mImageIds.length - 1){// 最后一个页面,设置开始体验按钮显示 startBtn.setVisibility(View.VISIBLE); }else{ startBtn.setVisibility(View.INVISIBLE); } } }}
4、viewpager的适配器adapter,给每个pager页面添加对应位置的图片资源
package com.study.tracy.adapter;import android.support.v4.view.PagerAdapter;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import java.util.ArrayList;public class GuideAdapter extends PagerAdapter { private ArrayListmImageViewList; public GuideAdapter(ArrayList mImageViewList) { this.mImageViewList = mImageViewList; } @Override public int getCount() { return mImageViewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(mImageViewList.get(position)); return mImageViewList.get(position); }}
转载地址:https://blog.csdn.net/happy_love1990/article/details/69487673 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
逛到本站,mark一下
[***.202.152.39]2024年03月29日 19时03分06秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
【剑指OFFER】44. 数字序列中某一位的数字
2019-04-26
【剑指OFFER】45. 把数组排成最小的数
2019-04-26
【区块链】使用JAV简易A模拟创建区块链及挖矿
2019-04-26
【力扣】74. 搜索二维矩阵
2019-04-26
【剑指OFFER】46. 把数字翻译成字符串
2019-04-26
【剑指OFFER】47. 礼物的最大价值
2019-04-26
【力扣】90. 子集 II
2019-04-26
【剑指OFFER】48. 最长不含重复字符的子字符串
2019-04-26
【力扣】80. 删除有序数组中的重复项 II
2019-04-26
【剑指OFFER】50. 第一个只出现一次的字符
2019-04-26
【剑指OFFER】57 - II. 和为s的连续正数序列
2019-04-26
【Java】 用PriorityQueue实现最大最小堆
2019-04-26
【剑指OFFER】49. 丑数
2019-04-26
【力扣】179. 最大数
2019-04-26
【剑指OFFER】56 - I. 数组中数字出现的次数
2019-04-26
天池新人赛-工业蒸汽量预测-排名150
2019-04-26
天池新人实战赛o2o优惠券使用预测-排名181
2019-04-26
资金流入流出预测-挑战Baseline-排名445 /122.17
2019-04-26
第四届工业大数据创新竞赛-注塑成型工艺的虚拟量测和调机优化-决赛排名22
2019-04-26
大数据时代的Serverless工作负载预测-排名80_0.313
2019-04-26