ViewPager+TimerTask实现Gallery画廊效果

转载请注明出处:http://blog.csdn.net/haoyuegongzi/article/details/78365888

先来一张效果图
ViewPager+TimerTask下的Gallery画廊效果

前期要做一个画廊的轮播效果,当时参考网上的一些思路,通过Gallery实现了,但Gallery作为一个已经过时的控价,现在还在用的话,感觉有点out,跟不上技术的发展,跟不上大神大佬们速度,于是乎琢磨着怎么通过ViewPager来实现。通过查阅一些资料和反复调试,终于实现了,具体实现如下:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#a2d0ff"
tools:context="bonc.demopractice_allkinsoff.viewpager.ViewPagerActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:clipChildren="false"
        android:orientation="vertical">

        <android.support.v4.view.ViewPager
            android:id="@+id/vpSeries"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:clipChildren="false"/>
    </LinearLayout>
</RelativeLayout>

注意:上面布局中LinearLayout里面的android:clipChildren="false"和ViewPager里面的android:clipChildren="false"不能够落下,不然,不能完整的实现画廊效果。

android:clipChildren属性的意思是:是否限制子View在其范围内

布局中的其他内容都是常规的,在此不做提示。
Activity里面代码如下,其中重要关键的信息旁边有注释:

public class ViewPagerActivity extends AppCompatActivity {
    @BindView(R.id.vpSeries)
    ViewPager mVpSeries;
    private LoopPagerAdapetr mPagerAdapetr;
    private List<View> mViews;
    private List<Integer> listPeacture;
    private int currentPosition = 0;/**OnPageChangeListener监听中position的记录*/
    private int DELAY = 2000;/**延迟执行时间*/
    private int PERIOD = 1500;/**执行的频率*/
    private Timer timer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_pager);
        EventBus.getDefault().register(this);
        ButterKnife.bind(this);
        addDataToListPeacture();
        setAdapetr();
    }

    private void addDataToListPeacture(){
        mViews = new ArrayList<>();
        listPeacture = new ArrayList<>();

        listPeacture.add(R.drawable.spring06);
        listPeacture.add(R.drawable.spring01);
        listPeacture.add(R.drawable.spring02);
        listPeacture.add(R.drawable.spring03);
        listPeacture.add(R.drawable.spring04);
        listPeacture.add(R.drawable.spring05);
        listPeacture.add(R.drawable.spring06);
        listPeacture.add(R.drawable.spring01);

        for (int i = 0; i < listPeacture.size(); i++) {
            View view = LayoutInflater.from(this).inflate(R.layout.view_pager, null);
            ImageView image = (ImageView) view.findViewById(R.id.ivViewPagerItem);
            image.setImageResource(listPeacture.get(i));
            mViews.add(view);
        }
        timer = new Timer();
    }

    private void setAdapetr(){
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        ViewGroup.LayoutParams params = mVpSeries.getLayoutParams();
        params.width = (int) (metrics.widthPixels * 0.6);/**设置ViewPager中Item的相对屏幕的宽度*/
        params.height = params.width * 682 / 1024;/**682:图片的高度,1024:图片的宽度*/
        mVpSeries.setLayoutParams(params);

        mPagerAdapetr = new LoopPagerAdapetr(mViews);
        mVpSeries.setAdapter(mPagerAdapetr);

        mVpSeries.setOffscreenPageLimit(mViews.size());
        mVpSeries.setPageMargin(30);/**设置ViewPager中相邻Item的间距*/
        /**设置ViewPager默认起始播放位置,不能为0或者最后一个,否则就会出现起始时的Item的左边或右边是空的,没有形成循环,给人中断的感觉*/
        mVpSeries.setCurrentItem(1);

        timer.schedule(task, DELAY, PERIOD);

        mVpSeries.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected(int position) {
                currentPosition = position;
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state != ViewPager.SCROLL_STATE_IDLE){
                    return;
                }
                if(currentPosition == 0){/**如果当前加载是第一张*/
                    mVpSeries.setCurrentItem(mPagerAdapetr.getCount() - 2, true);/**则加载倒数第二张*/
                }
                if(currentPosition == mPagerAdapetr.getCount() - 2 ){/**如果当前加载是最后一张*/
                    currentPosition = 0;
                    mVpSeries.setCurrentItem(1, true);/**则设置页面加载第二张*/
                }
            }
        });
    }

    public void onEventMainThread(EventMsg msg){
        mVpSeries.setCurrentItem(msg.position, false);
    }

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            int currentItem = mVpSeries.getCurrentItem();
            if(currentItem == 0){/**如果当前加载是第一张*/
                EventBus.getDefault().post(new EventMsg((mPagerAdapetr.getCount() - 2) % mViews.size()));
            }else if(currentPosition == mPagerAdapetr.getCount() - 2){/**如果当前加载是最后一张*/
                EventBus.getDefault().post(new EventMsg( 1 % mViews.size()));
            }else {
                EventBus.getDefault().post(new EventMsg((mVpSeries.getCurrentItem() + 1) % mViews.size()));
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        timer.cancel();
        task.cancel();
    }
}

LoopPagerAdapetr 就是一个常规的PagerAdapter,没有什么重要的内容,再次不展示。
EventMsg类文件中就一个int型的position,很简单。
该思路的核心理念就是根据屏幕的宽度动态的给ViewPager的Item设置宽度,改变显示效果:

	DisplayMetrics metrics = getResources().getDisplayMetrics();
    ViewGroup.LayoutParams params = mVpSeries.getLayoutParams();
    params.width = (int) (metrics.widthPixels * 0.6);/**设置ViewPager中Item的相对屏幕的宽度*/       

同时由于新的item的宽高尺寸,一方面根据屏幕宽度作出设置,另一方面为了保证图片在展示时不失真,还结合了图片本身的宽高比:

	params.height = params.width * 682 / 1024;/**682:图片的高度,1024:图片的宽度*/

因此,开发中控制好图片的宽高比例,避免图片显示失真。

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值