自定義 輪播圖 BannerView

一、自定義BannerViewPager

①、繼承自ViewPager善绎,重寫(xiě)構(gòu)造
②、自定義BannerViewPagerAdapter 繼承PagerAdapter

public class BannerViewPager extends ViewPager{

 public BannerViewPager(Context context) {
    this(context, null);
  }
 public BannerViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

private class BannerViewPagerAdapter extends PagerAdapter{

   @Override
   public int getCount() {
   }
   @Override
   public boolean isViewFromObject(View view, Object object) {
   }
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
    }
   @Override
   public void destroyItem(ViewGroup container, int position, Object object) {

   }
   }
}

③诫尽、創(chuàng)建setAdapter()

   public void setAdapter(BannerAdapter adapter) {
     this.mAdapter=adapter;
    //設(shè)置父類(lèi) ViewPager的Adapter
   setAdapter(new BannerViewPagerAdapter());
    //可以向左滑動(dòng)
    setCurrentItem(mAdapter.getCount() * 1000);
}

其中BannerAdapter 為

public abstract class BannerAdapter {
/**
 * 根據(jù)位置獲取ViewPage中的子View
 * @param position
 * @return
 */
public abstract View getView(int position,View convertView);
/***
 * 獲取有多少條
 * @return
 */
public abstract int getCount();

}

適配器方法

  public int getCount() {
       //實(shí)現(xiàn)無(wú)線循環(huán)
       return Integer.MAX_VALUE;
   }

  /**
     * 創(chuàng)建條目回調(diào)的方法
     *
     * @param container
     * @param position
     * @return
     */
    @Override
    public Object instantiateItem(ViewGroup container, int position) {

        //用Adapter設(shè)計(jì)模式 可以自定義view    position%mAdapter.getCount())取余
        position %= mAdapter.getCount();
        if (position<0){
            position=mAdapter.getCount()+position;
        }

        View bannerItemView = mAdapter.getView(position, getConvertView());
        //添加到viewpage中
        container.addView(bannerItemView);


        return bannerItemView;


    }

   /**
    * 銷(xiāo)毀條目回調(diào)的方法
    * @param container
    * @param position
    * @param object
    */
   @Override
   public void destroyItem(ViewGroup container, int position, Object object) {

        container.removeView((View)object);
         //界面復(fù)用
       mConvertViews.add((View) object);

   }

界面復(fù)用

    /**
    * 界面復(fù)用
   * @return
  */
public View getConvertView() {
    for (int i = 0; i < mConvertViews.size(); i++) {
        //獲取沒(méi)有添加到ViewPage 中的View
        if (mConvertViews.get(i).getParent()==null){

            return mConvertViews.get(i);
        }
    }
    return null;
}

④自動(dòng)輪播

  /**
 * 開(kāi)始輪播
 */
 public void startRoll(){

         isRoll=true;

          //清楚消息
         mHandler.removeMessages(SCROLL_MSG);
        //發(fā)送延遲消息 實(shí)現(xiàn)輪播
        mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
  }

mHandler接收

// 發(fā)送消息的 msg
private final int SCROLL_MSG=0x0011;
//默認(rèn)輪播時(shí)間
private int mCutDownTime=3500;
//是否輪播
private boolean isRoll=false;
  private Handler mHandler=new Handler(){
    @Override
    public void handleMessage(Message msg) {

        //調(diào)用 父類(lèi)方法 切換到下一頁(yè)
       setCurrentItem(getCurrentItem()+1);
        //不斷循環(huán)調(diào)用
        startRoll();
    }
};

⑤禀酱、改變切換速率 利用反射

 public BannerViewPager(Context context, AttributeSet attrs) {
      super(context, attrs);
      try {

        //改變切換速率 duration 持續(xù)時(shí)間為局部變量  要想改變通過(guò)反射
        Field field= ViewPager.class.getDeclaredField("mScroller");
        //設(shè)置參數(shù)
        bannerScroller = new BannerScroller(context);

        //設(shè)置強(qiáng)制改變 private
        field.setAccessible(true);
        field.set(this, bannerScroller);

    } catch (Exception e) {
        e.printStackTrace();
    }
    mConvertViews=new ArrayList<>();
}

BannerScroller類(lèi)

 public class BannerScroller extends Scroller {
//動(dòng)畫(huà)持續(xù)的時(shí)間
private int mScrollerDuration=950;
/**
 * 設(shè)置動(dòng)畫(huà)切換的時(shí)間
 * @param mScrollerDuration
 */
public void setmScrollerDuration(int mScrollerDuration) {
    this.mScrollerDuration = mScrollerDuration;
}

public BannerScroller(Context context) {
    super(context);
}

public BannerScroller(Context context, Interpolator interpolator) {
    super(context, interpolator);
}

public BannerScroller(Context context, Interpolator interpolator, boolean flywheel) {
    super(context, interpolator, flywheel);
}
@Override
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
    super.startScroll(startX, startY, dx, dy, mScrollerDuration);
 }
}

⑥、觸摸時(shí)停止輪播

 /**
 * 觸摸監(jiān)聽(tīng) 停止自動(dòng)輪播
 * @param ev
 * @return
 */
@Override
public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {

        case MotionEvent.ACTION_DOWN:
        case MotionEvent.ACTION_MOVE:

            //從消息隊(duì)列中移除所有message
            //停止輪播
            if (isRoll){
                mHandler.removeMessages(SCROLL_MSG);
            }
            break;
        case MotionEvent.ACTION_UP:

            if (isRoll){
                //重新發(fā)送
                mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
            }

            break;
    }
    return super.onTouchEvent(ev);
}

⑦牧嫉、防止泄漏

  /**
 * Activity銷(xiāo)毀 時(shí)回調(diào)該方法
 *
 * 防止內(nèi)存泄露
 */
@Override
protected void onDetachedFromWindow() {
    mHandler.removeMessages(SCROLL_MSG);
    mHandler=null;
    //解除綁定
    ((Activity) getContext()).getApplication().unregisterActivityLifecycleCallbacks(activityLifecycleCallbacks);

    super.onDetachedFromWindow();
}

⑧剂跟、不可見(jiàn)時(shí),停止發(fā)送

  //Activity生命周期管理
Application.ActivityLifecycleCallbacks activityLifecycleCallbacks=new DefaultActivityLifecycleCallbacks() {
    @Override
    public void onActivityResumed(Activity activity) {
        //實(shí)現(xiàn)輪播  是否是當(dāng)前的Activity
        if (activity==getContext()&& isRoll){
           //發(fā)送延遲消息 實(shí)現(xiàn)輪播
            mHandler.sendEmptyMessageDelayed(SCROLL_MSG, mCutDownTime);
        }
    }
    @Override
    public void onActivityPaused(Activity activity) {
        if (activity==getContext()&& isRoll){
            //停止輪播
            mHandler.removeMessages(SCROLL_MSG);
        }
    }
};

DefaultActivityLifecycleCallbacks類(lèi)實(shí)現(xiàn)

 public class DefaultActivityLifecycleCallbacks implements Application.ActivityLifecycleCallbacks {
   @Override
  public void onActivityCreated(Activity activity, Bundle savedInstanceState) {

   }

@Override
public void onActivityStarted(Activity activity) {

}

@Override
public void onActivityResumed(Activity activity) {

}

@Override
public void onActivityPaused(Activity activity) {

}

@Override
public void onActivityStopped(Activity activity) {

}

@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

}

@Override
public void onActivityDestroyed(Activity activity) {

}
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末酣藻,一起剝皮案震驚了整個(gè)濱河市曹洽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌臊恋,老刑警劉巖衣洁,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異抖仅,居然都是意外死亡坊夫,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)撤卢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)环凿,“玉大人,你說(shuō)我怎么就攤上這事放吩≈翘” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵渡紫,是天一觀的道長(zhǎng)到推。 經(jīng)常有香客問(wèn)我,道長(zhǎng)惕澎,這世上最難降的妖魔是什么莉测? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮唧喉,結(jié)果婚禮上捣卤,老公的妹妹穿的比我還像新娘忍抽。我一直安慰自己,他們只是感情好董朝,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開(kāi)白布鸠项。 她就那樣靜靜地躺著,像睡著了一般子姜。 火紅的嫁衣襯著肌膚如雪祟绊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,231評(píng)論 1 299
  • 那天闲询,我揣著相機(jī)與錄音久免,去河邊找鬼。 笑死扭弧,一個(gè)胖子當(dāng)著我的面吹牛阎姥,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鸽捻,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼呼巴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了御蒲?” 一聲冷哼從身側(cè)響起衣赶,我...
    開(kāi)封第一講書(shū)人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厚满,沒(méi)想到半個(gè)月后府瞄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碘箍,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年遵馆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丰榴。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡货邓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出四濒,到底是詐尸還是另有隱情换况,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布盗蟆,位于F島的核電站戈二,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏喳资。R本人自食惡果不足惜挽拂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望骨饿。 院中可真熱鬧亏栈,春花似錦、人聲如沸宏赘。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)察署。三九已至闷游,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贴汪,已是汗流浹背脐往。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留扳埂,地道東北人业簿。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阳懂,于是被迫代替她去往敵國(guó)和親梅尤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評(píng)論 25 707
  • 前言 目前市場(chǎng)上的APP中岩调,輪播圖可以說(shuō)是很常見(jiàn)的巷燥。一個(gè)好的輪播圖,基本上適用于所有的APP号枕。是時(shí)候打造一個(gè)自己的...
    帶心情去旅行閱讀 17,296評(píng)論 15 93
  • 我終究失去了你葱淳,或許是我的不夠好钝腺,又或許我不是你想要陪你走過(guò)一生的人 你在我的世界里逐漸消失,而我不知道該怎么去表...
    小鳳儀閱讀 312評(píng)論 0 1
  • 一旦你接納身體本來(lái)的樣子蛙紫,你就有力量改變它拍屑,及按照你自己的意愿重塑它。接納你的身體坑傅,你就可以輕而易舉的改變它僵驰。 看...
    英杰旺姆閱讀 128評(píng)論 0 0
  • 今天下雨,早晨吃過(guò)飯我早早的上班去并囑咐孩爹早點(diǎn)走唁毒,天氣不好會(huì)堵車(chē)的蒜茴! 下午單位開(kāi)會(huì)便讓孩爹接孩子放學(xué),晚上去朋友...
    瑞寶麻麻閱讀 152評(píng)論 0 0