相信讀者看到這個博客時,對它的內容一定不會陌生。這是一個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.javaimport 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編程功底。【參考】