viewpager輪播圖的實現(簡潔易懂)
在做這個效果的時候,我第一時間看了網上的輪播方式,發現問題很多,有的人在程式碼裡大量的判斷手動滑動和自動滑動的狀態改變,有的人的輪播是定義了一個很大的Int值,通過順序播放相同的圖片來實現的偽輪播,看過這些程式碼感覺並不滿意,所以嘗試自己實現。
在輪播更新UI的時候,我嘗試了Thread+handler,handler.postdelay,和timer+timertask+handler的方式,前兩種方式都會出現一些小Bug,並且不利於功能擴充套件,讀者可自行嘗試,所以我採用了第三種方式。
在解決手動滑動和自動滑動的上,其實根本不用設定什麼標誌位進行大量的判斷,這是一個思維誤區,因為我們根本不需要解決這兩者之間的衝突,我們只需要關注當前頁面是不是改變成功了,當前頁面是第幾個就可以了。所以我們只需要判斷onPageScrollStateChanged的state為2的時候,這個頁面的position就可以解決上述問題。
如果要給自己的輪播增加一些文字描述也非常的簡單,具體可以看我下面的程式碼分析。
效果圖:
直接看核心程式碼:
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Context ctx;
//viewpager初始化
private ViewPager viewPager;
private List<View> list;
private LPagerAdapter adapter;
//輪播控制
private Handler handler;
private Timer timer;
private TimerTask task;
private int mPosition;
//輪播內容
private LinearLayout point_container;
private ImageView[] imgs;
private List<ImageTip> tips;
private TextView tip1;
private TextView tip2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tip1 = (TextView) findViewById(R.id.tv_tip1);
tip2 = (TextView) findViewById(R.id.tv_tip2);
ctx = this;
initdata();
initpoint();
initTip();
//自定義adapter
adapter = new LPagerAdapter(ctx, list, new LPagerImgClickListener() {
@Override
public void ImgClick(int position) {
Toast.makeText(ctx, "點選了" + mPosition, Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ctx, SecondActivity.class);
intent.putExtra("position", position);
startActivity(intent);
}
});
//第一種動畫
// viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
//第二種動畫
viewPager.setPageTransformer(true,new DepthPageTransformer());
viewPager.setAdapter(adapter);
//監聽頁面的改變
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Log.i("LHD", "onPageScrolled" + " positionOffset:" + positionOffset + " positionOffsetPixels:" + positionOffsetPixels);
}
@Override
public void onPageSelected(final int position) {
// Log.i("LHD", "onPageSelected" + position);
}
@Override
public void onPageScrollStateChanged(int state) {
// Log.i("LHD", "onPageScrollStateChanged:" + state);
if (state == 2) {//圖片切換成功的狀態為2
mPosition = viewPager.getCurrentItem();
Log.i("LHD", "當前頁是:" + mPosition);
for (int i = 0; i < list.size(); i++) {
//設定所有原點
imgs[i].setImageResource(R.drawable.point1);
}
//設定當前頁的小圓點圖片和文字資訊
imgs[mPosition].setImageResource(R.drawable.point2);
tip1.setText(tips.get(mPosition).getTip1());
tip2.setText(tips.get(mPosition).getTip2());
}
}
});
imgPlay();
}
private void imgPlay() {
//迴圈播放
task = new TimerTask() {
@Override
public void run() {
Message msg = new Message();
msg.what = 1;
handler.sendMessage(msg);
}
};
timer = new Timer();
timer.schedule(task, 3000, 3000);
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
if (mPosition == (list.size() - 1)) {
viewPager.setCurrentItem(0, true);
} else {
Log.i("LHD", "bbbb: " + mPosition + "當前的程序ID: " + Thread.currentThread().getId());
viewPager.setCurrentItem(mPosition + 1, true);
Log.i("LHD", "cccc: " + mPosition);
}
}
}
};
}
private void imgStop() {
handler.removeMessages(1);
timer.cancel();
task.cancel();
}
private void initdata() {
list = new ArrayList<View>();
ImageView iv = new ImageView(ctx);
ImageView iv2 = new ImageView(ctx);
ImageView iv3 = new ImageView(ctx);
ImageView iv4 = new ImageView(ctx);
ImageView iv5 = new ImageView(ctx);
ImageView iv6 = new ImageView(ctx);
iv.setImageResource(R.drawable.image3);
iv2.setImageResource(R.drawable.image4);
iv3.setImageResource(R.drawable.image5);
iv4.setImageResource(R.drawable.image6);
iv5.setImageResource(R.drawable.image7);
iv6.setImageResource(R.drawable.image8);
list.add(iv);
list.add(iv2);
list.add(iv3);
list.add(iv4);
list.add(iv5);
list.add(iv6);
imgs = new ImageView[list.size()];
}
private void initpoint() {
point_container = (LinearLayout) findViewById(R.id.point_container);
for (int i = 0; i < list.size(); i++) {
ImageView imageView = new ImageView(ctx);
imageView.setImageResource(R.drawable.point1);
//對佈局控制元件新增相對屬性
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
20,
20);
//新增規則,示例 靠父控制元件最右邊
param.setMargins(10, 0, 0, 0);
Log.i("LHD", "新增小圓點:" + list.size());
imgs[i] = imageView;//新增到圖片陣列
point_container.addView(imageView, param);
imgs[0].setImageResource(R.drawable.point2);
}
}
private void initTip() {
tips = new ArrayList<ImageTip>();
tips.add(new ImageTip("山治:我要尋找all bule", "2016/6/23"));
tips.add(new ImageTip("弗蘭奇:我要飛上天", "2016/6/24"));
tips.add(new ImageTip("烏索普:我要成為勇敢的海上戰士", "2016/6/25"));
tips.add(new ImageTip("羅賓:我要尋找歷史原文", "2016/6/26"));
tips.add(new ImageTip("娜美:我要環繞世界一週", "2016/6/27"));
tips.add(new ImageTip("路飛:我要成為海賊王!", "2016/6/28"));
tip1.setText(tips.get(0).getTip1());
tip2.setText(tips.get(0).getTip2());
}
@Override
protected void onPause() {
super.onPause();
Log.i("LHD", "onPause");
//儲存當前頁位置
mPosition = viewPager.getCurrentItem();
//停止輪播
imgStop();
}
@Override
protected void onRestart() {
super.onRestart();
Log.i("LHD", "onRestart");
//重新啟動輪播
imgPlay();
}
}
分析:
imgPlay()
這個函式就是用來控制圖片輪播的函式,
在這個函式裡,使用了Timer+TimerTask+handler的方式來更新UI。
imgStop()
這個函式用來取消圖片輪播,當按下HOME鍵或者返回鍵的時候需要將動畫取消,再次啟動Activity的時候再恢復。
initdata()
將需要輪播的圖片存放在一個List裡,並且定義了一個存放圖片的陣列。
initpoint()
根據圖片數量來新增小圓點
initTip()
圖片下面文字的初始化
重寫了onPause方法和onRestart方法,在onPause方法裡儲存圖片位置,停止動畫,在onRestart方法裡重啟動畫。
接下來看ViewPager的介面卡:
LPagerAdapter.java
/**
* Created by LHD on 2016/6/29.
*/
public class LPagerAdapter extends PagerAdapter {
private Context ctx;
private List<View> mlist;
private LPagerImgClickListener mlistener;
public LPagerAdapter(Context ctx, List<View> mlist, LPagerImgClickListener listener) {
this.ctx = ctx;
this.mlist = mlist;
this.mlistener = listener;
}
@Override
public int getCount() {
return mlist.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
@Override
public Object instantiateItem(ViewGroup container, final int position) {
container.addView(mlist.get(position));
mlist.get(position).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Toast.makeText(ctx, "點選了" + position, Toast.LENGTH_SHORT).show();
if (mlistener != null) {
mlistener.ImgClick(position);
}
}
});
return mlist.get(position);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(mlist.get(position));
}
}
和普通的viewpager介面卡沒有區別,只是增加了一個監聽,當點選圖片的時候,呼叫mlistener.ImgClick(position);
介面:
LPagerImgClickListener.java
public interface LPagerImgClickListener {
public void ImgClick(int position);
}
另外提供了兩種viewpager的動畫,這兩種動畫都是谷歌官方提供,可以根據需要修改裡面的引數。
動畫1:
DepthPageTransformer.java
/**
* Created by LHD on 2016/6/30.
*/
public class DepthPageTransformer implements ViewPager.PageTransformer{
private static float MIN_SCALE = 0.75f;
@SuppressLint("NewApi")
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when
// moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE + (1 - MIN_SCALE)
* (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
動畫2:
ZoomOutPageTransformer.java
package com.example.eventbus.imagecarousellhd;
import android.support.v4.view.ViewPager;
import android.view.View;
/**
* Created by LHD on 2016/6/30.
*/
public class ZoomOutPageTransformer implements ViewPager.PageTransformer{
private static float MIN_SCALE = 0.85f;
private static float MIN_ALPHA = 0.5f;
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to
// shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE)
/ (1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
相關推薦
viewpager輪播圖的實現(簡潔易懂)
在做這個效果的時候,我第一時間看了網上的輪播方式,發現問題很多,有的人在程式碼裡大量的判斷手動滑動和自動滑動的狀態改變,有的人的輪播是定義了一個很大的Int值,通過順序播放相同的圖片來實現的偽輪播,看過這些程式碼感覺並不滿意,所以嘗試自己實現。 在輪播更新UI
圖片輪播的實現(html js)
1.簡單實現 1)實現思想:通過輪播次數來決定顯示那一張首先,可以用簡單的div 包含img的框架來實現,我們為他新增按鈕,每個按鈕對應不同的圖片,那麼,每點選一次,將要顯示的圖片的style.dispay屬性設定為'block'將不顯示的圖片的display設定為none,可以實現簡單的按
ViewPager輪播圖:自動無限輪播,手指長按停止,實現點選事件(實用版)
此Demo是自定義的viewpager,實現功能如下:無限自動輪播,pager點選事件處理,手指長按停止自動輪播,手指擡起恢復自動輪播; 幾乎可以滿足目前專案中的要求;大家可以直接使用; 整個Demo分兩大類,一個是自定義的ViewPager,一個是MainActivi
Android 輪播圖 實現 一 :三方框架 自定義viewPager (CircleViewPager.)實現無限輪播。
使用流程:1 。 gradle中新增依賴compile 'com.zhpan.library:viewpager:1.0.3'2.在xml檔案中新增如下程式碼:<com.zhpan.viewpager.view.CircleViewPager andr
ViewPager輪播圖 Banner方式實現
1.提取的基類 package com.example.viewpager_demo; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app
ViewPager輪播圖 Handler方式實現
1.提取的基類BaseActivity package com.example.viewpager_demo; import android.os.Bundle; import android.support.annotation.Nullable; import android.su
Android 實現輪播圖效果(三) 底部圓點狀態改變
自動輪播和手動輪播之後應該實現圓點的切換 自定義改變圓點狀態的監聽器 新建介面public interface DotChangeListener,新增方法void dotChangeListener(int index);並在ImageBannerFramLayout實
微信小程式學習筆記(三)----初識小程式程式碼、輪播圖實現
從這一節開始我們就開始接觸小程式前臺程式碼了,其實前臺邏輯還是比較簡單的,學習難度比學習一個前端框架難不了多少,記得以前一開始學前端框架的時候,流程就是:熟悉一下--檢視元件--找到要用的--複製貼上,其實對於大部分人來說,小程式前臺也是一樣。 首先,我們可以先看下小程式的
TabLayout + ViewPager輪播圖 (雙層巢狀),側拉展示條目(頭像加listview,點選頭像可切換)PullToRefreshListView重新整理載入
模組簡介: 1.底部:TabLayout + ViewPager輪播圖 2.主頁面可測拉 展示頭像,可選擇系統相簿,切換圖片(二級取樣) 3.TabLayout + ViewPager巢狀TabLayout + ViewPager以展示 正在上映 和 *
Bootstrap實現基於carousel.js框架的輪播圖效果(無過渡動畫)
宣告式觸發需要使用到的幾個data-*屬性 1.data-ride:作用在最外層容器上,固定值:carousel 2.data-target:作用在class=carousel-indicator
Boostrap部落格網站搭建(三)-首頁輪播圖實現
1、使用輪播圖外掛這裡我們使用swiper.js外掛並附上下載地址:https://pan.baidu.com/s/1c3MifM4 下面就需要新增HTML程式碼了 <div class="jumbotron container-slider"> &
JQuery 基礎案例(3)—— jQuery實現輪播圖無縫(無回滾)滾動切換效果
輪播圖無縫滾動切換原理 基本框架 <div class="slide"> <!-- 導航點 --> <ul class="slide-nav"> <li class="activ
js原生實現輪播圖效果(面向對象編程)
alt 狀態 off wid 編程) .proto eat doc 持續時間 面向對象編程js原生實現輪播圖效果 1.先看效果圖 2.需要實現的功能: 自動輪播 點擊左右箭頭按鈕無縫輪播 點擊數字按鈕切換圖片 分析:如何實現無縫輪播? 在一個固定大小的相框裏有一個ul
原生js輪播圖實現
索引 獲取 mouseout abs length ati point css ack 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta chars
vue輪播圖報錯 Uncaught RangeError: Maximum call stack size exceeded 附完整輪播圖實現程式碼
Vue初學者,寫專案實現輪播圖時報錯且頁面初始化後不會自動輪播。 設定的計時器時長是6000,但報錯是幾乎沒有停歇的報錯。 檢查核心程式碼,發現 錯誤一:這裡導致輪播圖初始化不輪播 mounted的方法寫在了methods裡面,將mounted的方法挪出,解決頁面初始化輪播圖不
ViewPager輪播圖
.activity_main.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
JS原生輪播圖實現
作為一個PHP全棧攻城獅,不僅要會後端PHP和資料庫,還要會前端JS。今天原始碼時代 PHP培訓 學科老師要和大家分享一下JS原生編寫輪播圖的外掛。 說起輪播圖,很多人會選擇使用各種外掛,比如基於JQuery或其它框架的。不瞞大家,我也用過,甚至還用過Flash的輪播圖。總體來說,用起來是比較簡
移動端輪播圖實現
1:HTML樣式<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width,initial-s
最簡單的輪播圖實現
需求:每隔2秒切換一張圖片的效果 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>輪播圖</title>
側拉+TabLayout切換fragment+Viewpager輪播圖小圓點和圖片上顯示標題+多條目+上拉載入+下拉重新整理
1.MainActivity主頁面 package com.example.zonghelianxi01; import android.annotation.SuppressLint; import android.support.annotation.Nullable; impor