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 ArrayList
mImageViewList; 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 ArrayList
mImageViewList; 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 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android监听home键的方法
下一篇:Android自定义ScrollView分段加载大文本数据到TextView

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年03月29日 19时03分06秒