使用ViewPager实现图片滑动展示

通常会自动滚动,也可以根据手势滑动。我没有研究过人家的APP是通过什么实现的,可能有第三方已经封装好的控件可以直接使用,也可能通过webview来实现,毕竟在网页上也有很多类似的内容。如果有高手经验丰富不妨指点一二。不管别人怎样,今天我准备自己动手做一个,其实也不是特别复杂的。
 
 
 
我主要使用的实现方法是Android自带的ViewPager控件,这个控件主要用于实现屏幕水平切换,有自带的动画效果。Android官网上有使用教程:http://developer.android.com/training/animation/screen-slide. html,当然下文会有相一致的说明。
 
 
 
然后就开始动手实现这个图片滑动效果吧。
 
1. 首先解释一下ViewPager的使用过程,通常来说ViewPager可以和Fragment结合起来用,每次ViewPager滑动,也就是展示一个新的Fragment。Fragment里面就是我们需要展现的内容。而这滑动的动画就交给ViewPager来实现。所以第一步我们需要设置好Fragment的内容,新建一个布局文件,这里只需要展示一张图即可,当然可以根据自己的需要进行改变:
 
复制代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
 
    <ImageView
        android:id="@+id/iv_main_pic"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:contentDescription="@string/main_image"
        android:scaleType="fitXY" />
 
</RelativeLayout>
复制代码
 
 
2. 然后建立Fragment类。
 
复制代码
import android.support.v4.app.Fragment;
......
 
public class PictureSlideFragment extends Fragment {
 
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        
        View v = inflater.inflate(R.layout.fragment_picture_slide, container, false);
        
        return v;
    }
 
}
复制代码
3. 在Activity布局文件的合适位置加入ViewPager控件。
 
        <android.support.v4.view.ViewPager
            android:id="@+id/pager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
 
 
4. 在Activity中得到这个ViewPager并且为其设置Adapter:
 
复制代码
private ViewPager mPager;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  mPager = (ViewPager) findViewById(R.id.pager);
  mPagerAdapter = new PictureSlidePagerAdapter(getSupportFragmentManager());
  mPager.setAdapter(mPagerAdapter);
}    
复制代码
 
 
5. 这个Adapter继承自FragmentStatePagerAdapter,其中getCount()返回的值是一共需要显示的内容数,是个常数:
 
复制代码
    private class PictureSlidePagerAdapter extends FragmentStatePagerAdapter {
 
        public PictureSlidePagerAdapter(FragmentManager fm) {
            super(fm);
            // TODO Auto-generated constructor stub
        }
 
        @Override
        public Fragment getItem(int arg0) {
            // TODO Auto-generated method stub
            return new PictureSlideFragment();
        }
 
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return NUM_PIC;
        }
    }
复制代码
 
 
6. 到目前为止所有的内容都和官方的教程一致。如果你在Fragment中的那个ImageView通过android:src属性设置图片,会实现数张静态图片滑动的效果。这离我们的目标还有一些区别:
 
(1)图片需要能够动态改变,而不是固定的内容;
 
(2)每张图片需要有点击的响应;
 
(3)一般情况下需要实现循环滚动,即滑到最后一张图时继续滑动会回到第一张图;
 
(4)图片要能够自动滚动;
 
(5)图片下方需要有显示第几张图的指示(小圆点)。
 
 
 
7. 接下来我们朝着目标继续努力。首先是图片的变化。观察上述Adapter的实现方法,可以发现getItem()方法每次返回的都是一个Fragment的实例,需要显示多少个Fragment这个方法就会执行多少遍。但我们发现每次创建新的Fragment都没有区别,直接new一个了事,因此我们需要改写这个创建新Fragment实例的方法,以实现每次新建的Fragment实例都不一样。在我们的Fragment类中补充如下内容:
 
复制代码
    private int mIndex;
    
    public static PictureSlideFragment newInstance(int index) {
        PictureSlideFragment f = new PictureSlideFragment();
        
        Bundle args = new Bundle();
        args.putInt("index", index);
        f.setArguments(args);
        
        return f;
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        mIndex = getArguments() != null ? getArguments().getInt("index") : 1;
 
    }
复制代码
这个叫做newInstance的方法主要功能也是创建一个Fragment实例,和直接new的区别是传递进来一个index参数,这个参数在onCreate()方法中被获得。然后我们将Adapter的getItem()改写为如下:
 
        @Override
        public Fragment getItem(int arg0) {
            // TODO Auto-generated method stub
            return PictureSlideFragment.newInstance(arg0);
        }
每次getItem都将Item的序号传递到新建的Fragment,然后再Fragment中根据需要设定不同的内容。真正实现的时候,可以在Fragment中加入从网络获取图片的操作。
 
 
 
8. 图片的点击响应。这个比较简单,在Fragment中获得ImageView控件,然后设置onClick监听器即可。就不给出代码了。
 
9. 图片的循环滚动。一般的ViewPager不能实现内容的循环滚动,即第一张向左滑或者最后一张向右滑都会到顶,显示到顶的效果。如果要从ViewPager自身入手加入这功能需要对这个控件进行改写,比较麻烦,这里我从stackoverflow上找到了一种比较聪明的办法。
 
  要实现几张图的循环滚动,其实只需要满足视觉效果就可以了。比如有三张图A,B,C,要实现A->B->C->A->B......以及C->B->A->C->B...这样的循环,实际上可以这样实现:
 
  提供5张图,分别是C'  A  B  C  A',其中C'和C,A'和A完全相同,当滑到C'时,自动切换到C,当滑到A'时,自动切换到A,并且这个切换过程没有动画,于是,使用者体验出来的感觉就是A B C三张图在循环滚动了。
 
  于是我们为ViewPager添加setOnPageChangeListener方法:
 
复制代码
        mPager.setOnPageChangeListener(new OnPageChangeListener() {
            
            @Override
            public void onPageSelected(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 onPageScrollStateChanged(int state) {
                // 当到第一张时切换到倒数第二张,当到最后一张时切换到第二张
                 if (state == ViewPager.SCROLL_STATE_IDLE) {
                     int curr = mPager.getCurrentItem();
                     int lastReal = mPager.getAdapter().getCount() - 2;
                     if (curr == 0) {
                         mPager.setCurrentItem(lastReal, false);
                     } else if (curr > lastReal) {
                         mPager.setCurrentItem(1, false);
                     }
                 }
            }
        });
复制代码
覆写的onPageScrollStateChanged方法在滑动内容改变时调用,在其中实现C'和C,A'和A的切换。
 
 
 
10. 图片的自动滚动,这里我使用了timer启动线程来实现,定时器线程每隔5秒发送消息,UI线程捕获消息并调用ViewPager.setCurrentItem(currentItem+1, true)方法,滚动到下一张图片。代码就不赘述了。这里有个体验细节,就是当使用者用手指滑动时,定时器需要取消,防止自动滑动和手指滑动发生冲突。这个我在Fragment的ImageView的onTouchListener中实现:
 
复制代码
        mMainImage.setOnTouchListener(new OnTouchListener() {
            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    ((MainActivity)getActivity()).getTimer().cancel();
                } else if (event.getAction() == MotionEvent.ACTION_CANCEL) {
                    ((MainActivity)getActivity()).startSwitchImage();
                }
 
                return false;
            }
        });
复制代码
 
 
 11. 图片序号的指示,也就是图片下方的几个小圆点,这个实现比较简单,首先在Activity的布局文件中添加几个图片,因为这几个小圆点本身不能随ViewPager移动,因此不能放在Fragment布局中。切换内容也就是切换显示不同颜色小圆点的位置,这个方法同样可以在onPageScrollStateChanged方法中调用。注意一些细节,因为之前为了实现循环滚动而多用了两个Fragment,而显示的小圆点数量不能增加,因此需要调整好对应的序号。代码也不再赘述了。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值