App项目之新手引导页
来源:互联网 发布:java编写的著名游戏 编辑:程序博客网 时间:2024/05/18 06:20
* 很多App第一次打开时都有一个新手引导页,这个引导页看起来很简单,但是做起来还是需要用刀不少知识的 *
ListView是非常重要的!!!!
先把布局文件写好:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/vp_guide" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始体验" android:id="@+id/btn_start" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="60dp" /> <LinearLayout android:id="@+id/ll_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="30dp" android:orientation="horizontal"></LinearLayout></RelativeLayout>
然后在GuideActivity中初始化数据.
(去掉标题:requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题,这个恶搞方法必须在setcontentview之前调用)
private ViewPager mViewPager;//怎样维护这个对象数组?private ArrayList<ImageView> mImageViewList;//imageview的集合//引导页图片id数组private int[] mImageIds = new int[]{R.mipmap.guide_1,R.mipmap.guide_2,R.mipmap.guide_3};@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题,这个恶搞方法必须在setcontentview之前调用 setContentView(R.layout.guide_activity); mViewPager = (ViewPager) findViewById(R.id.vp_guide); initData(); mViewPager.setAdapter(new GuideAdapter());//设置数据}//初始化ImageViewer对象.初始化数据private void initData(){ mImageViewList = new ArrayList<ImageView>(); for (int i=0;i<mImageIds.length;i++){ ImageView view = new ImageView(this); view.setBackgroundResource(mImageIds[i]);//通过设置背景,可以让宽高填充布局 //view.setImageResource(resId);这个方法不一定能填充满 mImageViewList.add(view); }}
然后开始设置数据
class GuideAdapter extends PagerAdapter{ @Override //返回item的个数 public int getCount() { return mImageViewList.size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override //初始化item的布局 public Object instantiateItem(ViewGroup container, int position) { ImageView view = mImageViewList.get(position);//获取这个ImageViewer,之前通过集合已经把要使用的创建好了,用的时候直接拿过来用 container.addView(view);//把这个对象塞给container容器 return view; } @Override //销毁item布局 public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View)object); }}
这时就完成了一个简单的引导.注意一定要先初始化数据!!!
接下来是页面指示器小圆点的完成,这个功能有助于用户体验.
这三个小圆点属于自定义控件,先初始化线性布局.
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#cccccc"></solid> <size android:height="10dp" android:width="10dp"></size></shape>
因为引导页需要一个小红点覆盖原来的小灰点,所以还要有个xml文件描述小红点.如下代码:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <solid android:color="#ff0000"></solid> <size android:height="10dp" android:width="10dp"></size></shape>
根据布局文件来看,需要有个相对布局包裹着一个线性布局.所以修改布局文件的代码如下:黄色部分为修改的代码
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/vp_guide" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="开始体验" android:id="@+id/btn_start" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="60dp" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_marginBottom="30dp"> <LinearLayout android:id="@+id/ll_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"></LinearLayout> <ImageView android:id="@+id/iv_red_point" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/shape_point_red"/> </RelativeLayout></RelativeLayout>
然后根据需求开始设置小红点,这里用到了自定义控件.就是关于布局绘制的一个流程.先测量,然后确定位置(layout执行完),最后再进行一个绘制.这三步之后才能把这个控件画在界面上.
计算两个小红点之间的距离
移动距离=第二个圆点left的值-第一个圆点left的值.
还要设置页面滑动的一个监听:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题,这个恶搞方法必须在setcontentview之前调用 setContentView(R.layout.guide_activity); mViewPager = (ViewPager) findViewById(R.id.vp_guide); llContainer = (LinearLayout) findViewById(R.id.ll_container); ivRedPoint = (ImageView)findViewById(R.id.iv_red_point); initData(); mViewPager.setAdapter(new GuideAdapter());//设置数据 //设置页面滑动的一个监听 mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //当页面滑动过程中的回调 System.out.println("当前位置:"+position+";移动偏移百分百:"+positionOffset); //更新小红点的距离 } @Override public void onPageSelected(int position) { //某个页面被选中 } @Override public void onPageScrollStateChanged(int state) { //页面状态发生变化的回调,暂时不用 } }); //计算两个小红点之间的距离 //移动距离=第二个圆点left的值-第一个圆点left的值 //measure->layout->draw(activity的 oncreate方法执行结束之后才走此流程,这就解释了为什么打印距离为0) /* mPointDis = llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft(); System.out.println("圆点距离:"+mPointDis); //因为打印距离是0,所以这个方法不能直接这样写*/ //监听layout方法结束的事件.结束之后位置确定好之后再获取圆点间距 //视图树? ivRedPoint.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ivRedPoint.getViewTreeObserver().removeOnGlobalLayoutListener(this);//避免重复回调 //layout方法执行结束的回调,这时可以使用这个方法 mPointDis = llContainer.getChildAt(1).getLeft()-llContainer.getChildAt(0).getLeft(); System.out.println("圆点距离:"+mPointDis); } });}
注意:根据图片可知要想得到小红点的距离,就要拿到移动间距.
//measure->layout->draw(activity的 oncreate方法执行结束之后才走此流程,这就解释了为什么打印距离为0)
直接这样使用是不行的.监听layout方法结束的事件.结束之后位置确定好之后再获取圆点间距.才可以使用
(这里讲了一个视图树的概念,可以看看.)
注意回调的概念.不要不理解啊
最后怎么更新小红点的距离呢?
//更新小红点的距离int dis = (int) (mPointDis * positionOffset);改变小红点的布局参数就可以了.就相当于更新marginleft的值System.out.println("当前位置:"+position+";移动偏移百分百:"+positionOffset);
//更新小红点的距离int leftMargin = (int) (mPointDis * positionOffset + position * mPointDis);//计算小红点当前的左边距RelativeLayout.LayoutParams params =(RelativeLayout.LayoutParams) ivRedPoint.getLayoutParams();//当前的布局参数params.leftMargin = leftMargin;//修改左边距ivRedPoint.setLayoutParams(params);//重新设置布局参数
这里就完成了基本的新手引导.具体代码可以在这里下载https://github.com/ZoeSj/SmartXinHua.git
- App项目之新手引导页
- ViewPager+app新手引导页
- app 新手引导功能设计
- App新手引导的设计
- IOS项目新手引导页图片适配方案
- 新手引导页-ViewPager
- 新手引导页
- 新手引导页
- 在app中添加新手引导视图
- 在app中添加新手引导视图
- android首次进入App新手引导
- android实现App新手引导功能
- ViewPager的应用之新手引导页的制作
- app引导页
- app引导页
- app引导页
- APP引导页Demo
- Android App引导页
- LeetCode 41 First Missing Positive
- UML类图与类的关系详解
- CTS fail issue学习
- Java的枚举类型使用方法详解
- leetcode刷题系列-Find All Anagrams in a String
- App项目之新手引导页
- 使用vs2010编译log4cxx图文教程
- linux中查找java程序 cpu占用高的代码位置。
- Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系
- index skip scan
- OpenJudge noi 310 Is It A tree(POJ1308)
- 算法基础复习-ShellSort
- openwrt 各目录分析
- 欢迎使用CSDN-markdown编辑器