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

来源:互联网 发布:linux 查看登录用户 编辑:程序博客网 时间:2024/06/11 23:04

        相信读者看到这个博客时,对它的内容一定不会陌生。这是一个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编程功底。

【参考】
1、ViewPager实现左右无限循环效果
0 0