[安卓]新闻客户端(二)引导页

引导页是第一次进APP才有的,他的效果是左右滑动几张图片,展现一些功能之类的,最后一张图片应该有个button,点击后计入主页面,同时在页面下部有红点

这要用到viewPager,安卓自己带有这个包,只需在布局里使用全名就能引用到

<?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"/>
</RelativeLayout>

然后回activity找到他,他要把几张图展现出来就需要adapter,adapter内要4个重载方法,第一个方法需要引用图片位置,所以建一个数组存放,而后需要初始化这个图片库,需要一个arraylist

public class GuideActivity extends Activity {
	ViewPager vpGuide;
	
	//第二步(1) 导入图片后,将位置信息放到一个数组里方便后面引用
	private static final int[] mImageIds = new int[] { R.drawable.guide_1,
		R.drawable.guide_2, R.drawable.guide_3 };
	
	//第三步(2) 初始化图片库,需要一个ArrayList
	private ArrayList<ImageView> mImageViewList;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题
		setContentView(R.layout.activity_guide);
		
		//第一步(1) 找到vp初始化
		vpGuide = (ViewPager) findViewById(R.id.vp_guide);
		//第三步(1) 初始化图片以及小圆点
		initViews();
		
		//第一步(2) 设置adapter
		vpGuide.setAdapter(new GuideAdapter());
	}
	//第三步(3) 初始化
	private void initViews() {
		mImageViewList = new ArrayList<ImageView>();

		//第三步(4) 初始化引导页的3个页面
		for (int i = 0; i < mImageIds.length; i++) {
			ImageView image = new ImageView(this);
			image.setBackgroundResource(mImageIds[i]);// 设置引导页背景
			mImageViewList.add(image);
		}
	}
        //第一步(3) 需要adapter填充
	class GuideAdapter extends PagerAdapter {
      
		@Override
		public int getCount() {
			 //第二步(2) 位置信息  或者是list的size也可以
			return mImageIds.length;
		}
		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			//第三步(6) 表明传回的object就是这个view,直接return true也可
			return arg0 == arg1;
		}

		@Override
		public Object instantiateItem(ViewGroup container, int position) {
			//第三步(5) 初始化好后,根据位置信息来填充
			container.addView(mImageViewList.get(position));
			return mImageViewList.get(position);//super.instantiateItem(container, position);
		}

		@Override
		public void destroyItem(ViewGroup container, int position, Object object) {
			//第三步(7) 划出去的要手动销毁  ((View) object)也可以
			container.removeView(mImageViewList.get(position));
		}
		
	}
}

再来实现下面的灰点和红点

这两类点都在整体的布局上,所以整体的布局是relativeLayout;而后这个红点也是相对于灰点位移而来,所以这里也是一个relativeLayout。

两类点都是在drawable文件夹下使用shape节点来实现,oval表示圆,solid表示实心


<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <solid android:color="#f00" />
</shape>

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >
    <solid android:color="@android:color/darker_gray" />
</shape>

灰点当成LinearLayout的view,随着滑动页面的增加而增加,无需定义死个数,给个ID直接在代码里直接初始化就好;而红点当成是一个imageview,需要跟随滑动,要在Viewpager的一个重载函数里实现。

<RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp" >
        <LinearLayout
            android:id="@+id/ll_point_group"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >
        </LinearLayout>
        <View
            android:id="@+id/view_red_point"
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:background="@drawable/shape_point_red" />
    </RelativeLayout>

去activity里找到这些点

//第四步(1) 圆点的实现
	private LinearLayout llPointGroup;// 灰点
	private int mPointWidth;// 圆点间的距离
	private View viewRedPoint;// 小红点
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	
		requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题
		setContentView(R.layout.activity_guide);
		//第四步(2) 两类圆点
		llPointGroup = (LinearLayout) findViewById(R.id.ll_point_group);
		viewRedPoint = findViewById(R.id.view_red_point);

小灰点的初始化,小灰点本身就是一个布局,他的个数随着滑动页面的增加而增加,小灰点之间的距离需要通过代码设置属性

//第四步(3) 初始化小灰点   这里根据我们滑动图片的张数来增加小灰点的个数,无需手动定义
		for (int i = 0; i < mImageIds.length; i++) {
			//1.imageView亦可
			View point = new View(this);
			//2.根据前面的XML定义,设置引导页默认圆点
			point.setBackgroundResource(R.drawable.shape_point_gray);
            //4.给灰点这个布局设置属性,宽高
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
					10, 10);
			if (i > 0) {
				params.leftMargin = 10;//5.设置圆点间隔,第一个点不需要
			}
			point.setLayoutParams(params);// 设置圆点的大小
			llPointGroup.addView(point);//3.将圆点添加给线性布局
		}

接着来实现红点,viewpager里面的OnPageChangeListener

//第五步(1),需要一个OnPageChangeListener来实现红点的移动
		vpGuide.setOnPageChangeListener(new GuidePageListener());

//第五步(2) 实现OnPageChangeListener,三个callback
	class GuidePageListener implements OnPageChangeListener {

		@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
			
		}
		@Override
		public void onPageSelected(int arg0) {
			// TODO Auto-generated method stub
			
		}		
	}

需要关联源码

右击工程名-properties-Libraies-Java buildpath-将第三个包remove-在add进来


这时候再去点击某个类,会让你添加源码


Attach folder 选择sdk/extras/android/support/v4

删除原来的重载方法,重新加入,都有了参数,OK


注意,要打钩



第一个方法,onPageScrolled,当view滑动时被调用

第一个参数 Position 表示当前处于哪个view

第二个参数 positionOffset 表示当前滑出的比例

第三个参数 表示划出的像素

从一个灰点的位置移到另一个灰点,移动的距离应该是2倍的灰点键距离,也就是20.,不过这里用代码实现

其中要获取两个小灰点间的距离,如图


小灰点的这个布局在实现过程中可以获取到相关属性,所以要在初始化中去获取这个距离

/*
		 * 第五步(3) 红点的移动需要获取小灰点间的距离
		 * 故而需要在初始化中监听灰点的构建,addOnGlobalLayoutListener
		 * view的过程:measure,layout,draw
		 */
		llPointGroup.getViewTreeObserver().addOnGlobalLayoutListener(
				new OnGlobalLayoutListener() {
			//当layout执行结束后回调此方法
			@Override
			public void onGlobalLayout() {
				System.out.println("layout 结束");
				llPointGroup.getViewTreeObserver().removeGlobalOnLayoutListener(this);
				mPointWidth = llPointGroup.getChildAt(1).getLeft()
						- llPointGroup.getChildAt(0).getLeft();
				System.out.println("圆点距离:" + mPointWidth);
			}
		});

再来看小红点移动的距离:

两点间的距离   灰点间距离 乘以 view移动的百分比 

跨点时,灰点距离 乘以 灰点的位置信息

@Override
		public void onPageScrolled(int position, float positionOffset,
				int positionOffsetPixels) {
			System.out.println("当前位置:" + position + ";百分比:" + positionOffset
					+ ";移动距离:" + positionOffsetPixels);
			//第五步(4) 由灰点间距离和view移动的百分比来测算红点应该移动的距离
			int len = (int) (mPointWidth * positionOffset) + position
					* mPointWidth;
			RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) viewRedPoint
					.getLayoutParams();// 获取当前红点的布局参数
			params.leftMargin = len;// 设置左边距,相对于父控件RelativeLayout来说的
			viewRedPoint.setLayoutParams(params);// 重新给小红点设置布局参数
		}

OK,实现在最后一个页面点击button跳转到主页面

布局,这里按键后颜色和背景都改变,需要定义selector


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_red_pressed" android:state_pressed="true"/>
    <item android:drawable="@drawable/button_red_normal"/>
</selector>

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@android:color/black"/>
    <item android:color="@android:color/white"/>
</selector>

<pre name="code" class="html"><Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:background="@drawable/btn_guide_selector"
        android:padding="5dp"
        android:text="开始体验"
        android:visibility="invisible"
        android:textColor="@drawable/btn_guide_text_selector"/>

 这个按钮找到后,在onPageSelected内,只有最后一面显示这个button,别的都隐藏 

@Override
		public void onPageSelected(int position) {
			// 第六步(2) button点击跳转
			if (position == mImageIds.length - 1) {// 最后一个页面
				btnStart.setVisibility(View.VISIBLE);// 显示开始体验的按钮
			} else {
				btnStart.setVisibility(View.INVISIBLE);
			}
		}

设置响应,并改变sp

//第六步(2) 找到button
		btnStart = (Button) findViewById(R.id.btn_start);
		//第六步(4) 跳转,并设置boolean,以后不再进入引导页
		btnStart.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				// 更新sp, 表示已经展示了新手引导
				PrefUtils.setBoolean(GuideActivity.this,
						"is_user_guide_showed", true);
				// 跳转主页面
				startActivity(new Intent(GuideActivity.this, MainActivity.class));
				finish();//免得用户后退又回来了,销毁他
			}
		});

OK~


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值