Android ViewPager無限循環(huán)滑動(dòng)并可自動(dòng)滾動(dòng)完整實(shí)例
對(duì)于ViewPager 廣告頁這個(gè)功能很多APP都有這個(gè)功能在網(wǎng)上也看過一些資料,我就在這把我自己完整的實(shí)現(xiàn)方法寫出來吧
基礎(chǔ)的ViewPager:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/top_item"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/top_vp"
></android.support.v4.view.ViewPager>
</LinearLayout>
很簡單 僅僅是一個(gè)ViewPager
接下來簡單的設(shè)置一下ViewPager的Adapter 添加ImageView
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模擬存放要展示的圖片
private List<ImageView> imageViews ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
}
/**
* 初始化圖片資源
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
return imageViews.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(imageViews.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(imageViews.get(position));
return imageViews.get(position);
}
});
}
}
上述是最基礎(chǔ)的一個(gè)ViewPager 下面我們就在這個(gè)基礎(chǔ)上改造就可以了
實(shí)現(xiàn)無限循環(huán)滑動(dòng):
這里我事先循環(huán)滑動(dòng)的方式很簡單 就是把 adapter的count 設(shè)置為一個(gè)很大的值 這樣 讓它滑不到頭 然后切換圖片 就可以實(shí)現(xiàn) 雖然方法比較LOW 但是效果還是可以的
代碼在基礎(chǔ)的ViewPager下修改如下 :
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模擬存放要展示的圖片
private List<ImageView> imageViews ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
}
/**
* 初始化圖片資源
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
// return imageViews.size(); 修改如下
return 10000;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// container.removeView(imageViews.get(position%imageViews.size())); 刪除此句 此句不刪除 會(huì)出現(xiàn) 滑動(dòng)中 布局消失的情況 因?yàn)楸灰瞥?此處這樣修改會(huì)影響一些性能。。。。。
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// container.addView(imageViews.get(position));
// return imageViews.get(position); 修改如下
try {
container.addView(imageViews.get(position%imageViews.size()));
}catch (Exception e){
}
return imageViews.get(position%imageViews.size());
}
});
}
}
這樣 之后就可以實(shí)現(xiàn)無限循環(huán)右滑了 但是在程序剛啟動(dòng) 是 無法向左滑動(dòng)的 要解決 很簡單 只需要在開始的時(shí)候
viewPager.setCurrentItem(1000*imageViews.size());
即可 這樣 就可以 實(shí)現(xiàn) 無限左右滑了
自動(dòng)定時(shí)循環(huán)滑動(dòng):
下面增加自動(dòng)定時(shí)左右滑動(dòng)的功能
要實(shí)現(xiàn)自動(dòng)滑動(dòng) 最主要的是 實(shí)現(xiàn)定時(shí)器功能我這里使用 Handler+Runnable的方法在上述代碼的基礎(chǔ)上 修改 如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initImageViews();
initVp();
handler = new Handler();
handler.postDelayed(new TimerRunnable(),5000);
}
class TimerRunnable implements Runnable{
@Override
public void run() {
int curItem = topVp.getCurrentItem();
topVp.setCurrentItem(curItem+1);
if (handler!=null){
handler.postDelayed(this,5000);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
handler = null; //此處在Activity退出時(shí)及時(shí) 回收
}
這之后 就可以實(shí)現(xiàn)自動(dòng)滑動(dòng)了
添加左下角圓形小按鈕:
接下來添加 左下角的導(dǎo)航小原點(diǎn)
首先 修改布局 :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/top_item"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="180dp">
<android.support.v4.view.ViewPager
android:layout_width="match_parent"
android:layout_height="180dp"
android:id="@+id/top_vp"
></android.support.v4.view.ViewPager>
<LinearLayout
android:id="@+id/lin_points"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
我們需要的原點(diǎn) 要放在 LinearLayout布局中
主要原理 就是向這個(gè)LinearLayout中動(dòng)態(tài)添加 小圓點(diǎn) 即可
public class MainActivity extends AppCompatActivity {
private ViewPager topVp;
private int[]images = new int[]{R.mipmap.ad0, R.mipmap.ad1, R.mipmap.ad3}; //模擬存放要展示的圖片
private List<ImageView> imageViews ;
private List<TextView> txtPoints;
private LinearLayout lin_points;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lin_points = (LinearLayout) findViewById(R.id.lin_points);
initImageViews();
initVp();
initCircle();
/*
* 計(jì)時(shí)器
*/
handler = new Handler();
handler.postDelayed(new TimerRunnable(),5000);
}
/**
* 初始化小圓點(diǎn)
*/
private void initCircle() {
txtPoints = new ArrayList<>();
int d = 20;
int m = 7;
for (int i = 0; i < imageViews.size(); i++) {
TextView txt = new TextView(this);
if (i == 0) {
txt.setBackgroundResource(R.drawable.point_pink);
} else {
txt.setBackgroundResource(R.drawable.point_grey);
}
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(d, d);
params.setMargins(m, m, m, m);
txt.setLayoutParams(params);
txtPoints.add(txt);
lin_points.addView(txt);
}
}
class TimerRunnable implements Runnable{
@Override
public void run() {
int curItem = topVp.getCurrentItem();
topVp.setCurrentItem(curItem+1);
changePoints((curItem+1)%imageViews.size());
if (handler!=null){
handler.postDelayed(this,5000);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
handler = null;
}
/**
* 初始化圖片資源
*/
private void initImageViews() {
imageViews = new ArrayList<>();
for(int i = 0;i<images.length;i++){
ImageView imageView = new ImageView(this);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setImageResource(images[i]);
imageViews.add(imageView);
}
}
private void initVp() {
topVp = (ViewPager) findViewById(R.id.top_vp);
topVp.setAdapter(new PagerAdapter() {
@Override
public int getCount() {
// return imageViews.size(); 修改如下
return 10000;
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// container.removeView(imageViews.get(position%imageViews.size())); 刪除此句
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
// container.addView(imageViews.get(position));
// return imageViews.get(position); 修改如下
try {
container.addView(imageViews.get(position%imageViews.size()));
}catch (Exception e){
}
return imageViews.get(position%imageViews.size());
}
});
topVp.setCurrentItem(imageViews.size()*1000);
topVp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
changePoints((position)%imageViews.size());
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
public void changePoints(int pos) {
if (txtPoints != null) {
for (int i = 0; i < txtPoints.size(); i++) {
if (pos == i) {
txtPoints.get(i).setBackgroundResource(R.drawable.point_pink);
} else {
txtPoints.get(i).setBackgroundResource(R.drawable.point_grey);
}
}
}
}
}
給ViewPager添加切換動(dòng)畫:
topVp.setPageTransformer(true,new CubeOutTransformer());
調(diào)用 此行代碼 可以添加 后面的TransFormer類 是自定義的過渡效果類
控制ViewPager 自動(dòng)切換的速度
ViewPager自身的切換速度是寫死的,我們無法修改,但是我們可以通過源碼看到,ViewPager的切換速度是通過 Scroller類 控制的,而Scroller類中是可以設(shè)置過渡的時(shí)間的,因此 我們可以通過自己創(chuàng)建一個(gè)Scroller類 繼承 Scroller 然后 通過反射 把ViewPager中的mScroller屬性 設(shè)置成我們自己的可以設(shè)置時(shí)間的Scroller類即可
下面是代碼:
public class FixedSpeedScroller extends Scroller {
private int mDuration = 1500;
public FixedSpeedScroller(Context context) {
super(context);
}
public FixedSpeedScroller(Context context, Interpolator interpolator) {
super(context, interpolator);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy) {
// Ignore received duration, use fixed one instead
super.startScroll(startX, startY, dx, dy, mDuration);
}
public void setmDuration(int time) {
mDuration = time;
}
public int getmDuration() {
return mDuration;
}
}
反射修改ViewPager屬性:
try {
Field field = ViewPager.class.getDeclaredField("mScroller");
field.setAccessible(true);
scroller = new FixedSpeedScroller(getActivity());
scroller.setmDuration(1000);
field.set(topVp, scroller);
} catch (Exception e) {
// e.printStackTrace();
System.out.println("aaaaaa錯(cuò)誤啦");
}
這樣就可以控制速度了
好了,Android ViewPager廣告頁可無限循環(huán)滑動(dòng)并可自動(dòng)滾動(dòng)帶有小圓點(diǎn)的功能基本就實(shí)現(xiàn)了,具體參數(shù)大家可以自行設(shè)定
- Android 使用viewpager實(shí)現(xiàn)無限循環(huán)(定時(shí)+手動(dòng))
- Android viewpager中動(dòng)態(tài)添加view并實(shí)現(xiàn)偽無限循環(huán)的方法
- Android ViewPager無限循環(huán)實(shí)現(xiàn)底部小圓點(diǎn)動(dòng)態(tài)滑動(dòng)
- Android無限循環(huán)RecyclerView的完美實(shí)現(xiàn)方案
- Android ViewPager實(shí)現(xiàn)無限循環(huán)效果
- Android實(shí)現(xiàn)ViewPager無限循環(huán)效果(一)
- Android實(shí)現(xiàn)帶指示點(diǎn)的自動(dòng)輪播無限循環(huán)效果
- Android實(shí)現(xiàn)基于ViewPager的無限循環(huán)自動(dòng)播放帶指示器的輪播圖CarouselFigureView控件
- Android實(shí)戰(zhàn)打飛機(jī)游戲之無限循環(huán)的背景圖(2)
- Android TV 3D卡片無限循環(huán)效果
相關(guān)文章
Android RadioGroup多行顯示效果 解決單選問題
這篇文章主要為大家詳細(xì)介紹了Android RadioGroup多行顯示效果,解決單選問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Android中butterknife的使用與自動(dòng)化查找組件插件詳解
這篇文章主要給大家介紹了關(guān)于Android中butterknife的使用與自動(dòng)化查找組件插件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
Android實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼功能
這篇文章主要介紹了Android實(shí)現(xiàn)滑塊拼圖驗(yàn)證碼功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
myeclipse android環(huán)境搭建圖文教程
在從事android應(yīng)用開發(fā)過程中,搭配環(huán)境是所有開始的第一步,本文將介紹myeclipse android環(huán)境搭建圖文教程,希望可以幫助大家完成android開發(fā)之旅2012-11-11
Android如何使用RecyclerView打造首頁輪播圖
這篇文章主要為大家詳細(xì)介紹了Android如何使用RecyclerView打造首頁輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
Android實(shí)現(xiàn)帶有指示器的自定義底部導(dǎo)航欄
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)帶有指示器的自定義底部導(dǎo)航欄,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04
Android如何使用ViewPager2實(shí)現(xiàn)頁面滑動(dòng)切換效果
這篇文章主要給大家介紹了關(guān)于Android如何使用ViewPager2實(shí)現(xiàn)頁面滑動(dòng)切換效果的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02

