欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ViewPager+TimerTask实现Gallery画廊效果

程序员文章站 2022-05-15 17:17:21
...

转载请注明出处: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:图片的宽度*/

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

ViewPager+TimerTask实现Gallery画廊效果