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編程功底。

【參考】
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章