Android学习小Demo(10)ToDoList的改进版之ViewPager显示多个图片

在TodoList增强版的增加界面上,为了显示图片,我是挖了两块地方,放了两个ImageButton,来显示图片,而且限制了最多只能放两张图片。当两个View都放置图片之后,我就会把“Gallery”和"Camera"的两个按钮给隐藏掉,如下图红框显示中,已经没了:


但是这样,一方面不好看,也不人性呀(=_=!! 一切需求都是从人自身出发的。),在上一章的末尾,我当时建议说可以放一个3D画廊,来展示图片,这样的话,就可以放多张图片了,还好看一点,也不用说去隐藏那两个按钮了,对吧。

所以昨天晚上呢,回来之后就改了一下,利用ViewPager来实现多张图片展现的效果,如下:

从上面的gif图片中, 我们可以看到,但添加多张图片的时候,能够在下方形成一个画廊的效果,我们左右拉动图片来看我们添加进去的图片,效果是不是好了很多呢?

下面我们就从代码里面来讲讲是怎么做的吧。

首先,我们来看布局:

    <LinearLayout
        android:id="@+id/flGalleryContainer"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="4"
        android:layout_marginBottom="5dp"
        android:gravity="center"  
        android:clipChildren="false"
        android:layerType="software"
        android:orientation="horizontal" >

        <android.support.v4.view.ViewPager
            android:id="@+id/vpGallery"
            android:layout_width="150dp"
            android:layout_height="match_parent"           
            android:clipChildren="false" />
    </LinearLayout>

我们在这个位置放一个Layout(什么样的Layout都可以,我原来是用一个FrameLayout的,但代码中有点问题,我以为是它的问题,就改成LinearLayout,然后就忘了改回去了。)

Layout里面会放一个ViewPager(这是v4 支持包里面提供的,在2.x的机器上是没有这个控件的)。

1)在这里,其实我们是利用到了view的clipChildren属性,我们在这里要把它设置为false,如下,为什么呢?

        android:clipChildren="false"

因为如果clipChildren属性设置为true,就表明我们要将children给clip掉,就是说对于子元素来说,超出当前view的部分都会被切掉,那我们在这里把它设置成false,就表明超出view的部分,不要切掉,依然显示。

那为什么我们要设置这个属性呢?那是因为对于ViewPager控件来说,它只显示当前页(page)的View,轮到下一个view,就是下一页了,所以对于ViewPager本身这个控件来说,它永远只显示一个View,也就是一张图片。

2)另外,看如下代码:

        android:layerType="software"
这个是设置层的属性为软件层,因为从4.0之后,android是默认启动硬件加速的,而硬件加速对clip等操作是有影响的,会出一些bug,所以如果我们在自定义View样式中,用到clip等操作,对于4.0以上的android,我们需要将它的硬件加速关掉,不然是会出问题的,具体问题我忘了,不过这跑题了,sorry。

3)最后在这布局上还有一点要注意,我们要把ViewPager的宽度设置比父控件的小,这样两边才有空间去让view跑出viewpager,从而显示多个图片。

好了,下面我们来看看java的代码:

		vpGallery = (ViewPager)findViewById(R.id.vpGallery);
		galleryPagerAdapter = new GalleryPagerAdapter(imageViews);
		
		vpGallery.setAdapter(galleryPagerAdapter);
		vpGallery.setOnPageChangeListener(this);
		vpGallery.setOffscreenPageLimit(3);
		vpGallery.setPageMargin(5);
		if(imageViews.size() > 1){
			vpGallery.setCurrentItem(1);
		}
		
		flGalleryContainer = (LinearLayout)findViewById(R.id.flGalleryContainer);
		flGalleryContainer.setOnTouchListener(new OnTouchListener() {			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return vpGallery.dispatchTouchEvent(event);
			}
		});

4)其实ViewPager跟ListView和GridView这样的东西是同一个道理的,只是ListView和GridView是一次显示多个item,而ViewPager是像页一样,一次展现一页而已。相似的,也要定义一个Adapter来作为跟数据的接口,其中imageViews存放的就是这个任务所相关的图片了。

关于Adapter的代码,大家等一下在源代码里面看吧,这里就不放了,占地方。

5)既然是画廊,每次展现的图片肯定是要几张的对吧,那么我们就必须在这里利用下面这个函数来指定缓存几张图片,这样才有东西可以show,不会一拉过来,竟然是空白的。

vpGallery.setOffscreenPageLimit(imageViews.size());
6)需要把父控件的触摸响应函数传给ViewPager,如下:

		flGalleryContainer.setOnTouchListener(new OnTouchListener() {			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				return vpGallery.dispatchTouchEvent(event);
			}
		});
这是因为,我们在滑动图片的时候,不会总是点着ViewPager来左右滑动,我们也会点击旁边的空白处来滑动的,这个时候,我们必须把这种滑动的响应函数交给ViewPager来处理,ViewPager就会以为是自己在滑动,才会对应地将下一页的View给带出来,不然的话,父控件点它自己的空间,ViewPager在中间的是不知道的。

7)我们还可以看到,设置了一个OnPageChangeListener给这个ViewPager呢,如下所示:

vpGallery.setOnPageChangeListener(this);
而我们也在下面实现了它的接口方法,如下:

	@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		if(flGalleryContainer != null){
			flGalleryContainer.invalidate();
		}
	}

	@Override
	public void onPageSelected(int arg0) {
		
	}
}
在这里,我们只实现了其中一个方法,当页面在滑动的时候,不断地刷新viewPager父控件,这是因为ViewPager里面的View画到外面出来之后,外面的Layout不知道有东西放到它上面去了,所以需要强制去刷新一下,让layout重新画一下,才能将ViewPager跑到它外面的那部分图片给画到Layout上。

关于ViewPager实现画廊的效果大概就是这样了,不过我觉得这个效果其实也只是一般,比较麻烦。

不知道大家有没有看过我前面一篇博客:

Android学习小demo(3)自定义ViewGroup 利用 scroller 实行屏幕滚动

在里面我实现了如下一个效果:

这是一个自定义的控件,我觉得用这个来实现画廊效果,可能效果会更好呀,还能够加上自己的动画效果,多好看呀,是不!

关于TodoList增强版,大家请看:

Android学习小Demo(10)ToDoList的加强版

源代码请点击下载

Android学习小Demo(10)ToDoList的改进版之ViewPager显示多个图片,,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。