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