Android开发,使用ViewPager实现完全真正的左右循环滑动

        相信读者看到这个博客时,对它的内容一定不会陌生。这是一个Android开发中非常常见的需求,并且网上也有很多实现方法。然而,就笔者目前在网上看到的实现方法,大概可分为两种。一种是将PagerAdapter中的getCount()返回值定为Integer.MAX_VALUE,即使用户看不到边界;另一种是将数据源数组多出首尾两个节点,然后在onPageSelected(int position)中进行跳转。这两种方法实际上效果都不好。第一种方法由于将ViewPager边界设成很大,性能上会受到影响,有时会出现加载不了页面或加载很慢的情况。第二种方法的总体思路是正确的,但是选择在onPageSelected(int position)中进行跳转是错误的,因为此方法的调用时刻是图片滑动过一半时,从而导致滑动时出现跳闪的现象。

        完全正确的方法是,沿用上述第二种方法延长数据源、跳转的思想,但是在onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法中进行跳转。主要代码如下。

        1、布局文件

        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/frame1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">
            <android.support.v4.view.ViewPager
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical" >
                <LinearLayout
                    android:id="@+id/viewGroup"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_marginBottom="30dp"
                    android:gravity="center_horizontal"
                    android:orientation="horizontal" >
                </LinearLayout>
            </RelativeLayout>
        </FrameLayout>

        2、代码

MainActivity.java
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.support.v4.view.ViewPager;
import android.view.ViewGroup.LayoutParams;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.wondermatrix.bichampsalesassistant.R;
import com.wondermatrix.bichampsalesassistant.ui.adapter.ImageViewsAdapter;

import java.io.File;
import java.util.List;

import static com.wondermatrix.bichampsalesassistant.activity.MainActivity.Command.*;
import static com.wondermatrix.bichampsalesassistant.utils.Constant.*;


public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {

    private ViewPager viewPager;
    private ViewGroup viewGroup;
    private ImageView[] imageViews;
    private ImageView[] tips;
    private int imageId = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        viewPager = (ViewPager) findViewById(R.id.viewPager);
        viewGroup = (ViewGroup)findViewById(R.id.viewGroup);
        inflateImageViewPager();
    }


    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        if (Math.abs(positionOffset) < 0.01) {				     //最关键的地方,图片滑动到最终位置后再跳转
            if (imageViews.length > 1)
            {
                if (position == 0) {
                    viewPager.setCurrentItem(imageViews.length - 2, false);  //一定要设成false,取消动画
                } else if (position == imageViews.length - 1) {
                    viewPager.setCurrentItem(1, false);			     //同上
                }
            }
        }
    }


    @Override
    public void onPageSelected(int position) {
        imageId = position - 1;
        if (position == 0) {
            imageId = tips.length - 1;
        }
        if (position ==  imageViews.length - 1) {
            imageId = 0;
        }
        setTip(imageId);
    }


    @Override
    public void onPageScrollStateChanged(int state) {

    }


    private void inflateImageViewPager() {
        viewGroup.removeAllViews();
        int[] imageIds = showingMovie.getImageIds();	//笔者程序将所有Image的ID保存在了showingMovie变量中
        int[] newImageIds = new int[imageIds.length + 2];
        newImageIds[0] = imageIds[imageIds.length - 1];
        for (int i = 1; i < newImageIds.length - 1; i++) {
            newImageIds[i] = imageIds[i - 1];
        }
        newImageIds[newImageIds.length - 1] = 0;	//数据源数组多出首尾两个节点

        tips = new ImageView[imageIds.length];
        for (int i = 0; i < tips.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setLayoutParams(new LayoutParams(R.dimen.tip_size, R.dimen.tip_size));
            tips[i] = imageView;
            if (i == 0) {
                tips[i].setBackgroundResource(R.drawable.page_indicator_focused);
            } else {
                tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused);
            }

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            layoutParams.topMargin = 5;
            layoutParams.bottomMargin= 5;
            layoutParams.leftMargin = 5;
            layoutParams.rightMargin = 5;
            viewGroup.addView(imageView, layoutParams);
        }

        imageViews = new ImageView[newImageIds.length];
        for (int i = 0; i < imageViews.length; i++) {
            ImageView imageView = new ImageView(this);
            imageView.setImageBitmap(BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getPath() + File.separator
                    + ROOT_PATH + File.separator + IMAGES_PATH + File.separator + showingMovie.getNameEnglish() + File.separator
                    + showingMovie.getNameEnglish() + String.valueOf(newImageIds[i]) + IMAGE_SUFFIX));
            imageViews[i] = imageView;
        }
        viewPager.setAdapter(new ImageViewsAdapter(imageViews));
        viewPager.setOnPageChangeListener(this);
        viewPager.setCurrentItem(1);
    }


    private void setTip(int selectedItemId){
        for (int i = 0; i < tips.length; i++) {
            if (i == selectedItemId) {
                tips[i].setBackgroundResource(R.drawable.page_indicator_focused);
            } else {
                tips[i].setBackgroundResource(R.drawable.page_indicator_unfocused);
            }
        }
    }

}
ImageViewsAdapter.java
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.widget.ImageView;


public class ImageViewsAdapter extends PagerAdapter {

    public ImageView[] imageViews;

    public ImageViewsAdapter(ImageView[] imageViews) {
        this.imageViews = imageViews;
    }

    @Override
    public int getCount() {
        if (imageViews != null) {
            return imageViews.length;
        }
        return 0;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public void destroyItem(View container, int position, Object object) {
        ((ViewPager) container).removeView(imageViews[position]);
    }

    @Override
    public Object instantiateItem(View container, int position) {
        if (imageViews[position % imageViews.length].getParent() != null) {
            ((ViewPager) container).removeView(imageViews[position % imageViews.length]);
        }
        ((ViewPager) container).addView(imageViews[position]);
        return imageViews[position];
    }
}
        对于代码这里不做过多的解释了,相信研究这个问题的读者都具备了一定的Android编程功底。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值