搬磚戰(zhàn)士的自我修養(yǎng)之ConvenientBanner

導(dǎo)語

主要是為了分析一些我用過的第三方控件胧砰,學(xué)習(xí)一下一些酷炫的特效是怎么實現(xiàn)的。ConvenientBanner是我之前在github上翻到的一款輪播圖控件苇瓣,項目催的比較急就開始用了尉间,現(xiàn)在讓我這個磚戰(zhàn)士來分析一下。

腦補原理

先隨便腦補一下這玩意大概是怎么做的击罪,一個viewpager哲嘲,加個定時器,開始滑啊滑媳禁,大概就這樣了吧眠副。


傻狗.

??ConvenientBanner繼承的是LinearLayout???LinearLayout???LinearLayout???

分析

直接構(gòu)造方法

 public ConvenientBanner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.ConvenientBanner);
        canLoop = a.getBoolean(R.styleable.ConvenientBanner_canLoop,true);
        a.recycle();
        init(context);
    }

不多說,直接init(context);

    private void init(Context context) {
        View hView = LayoutInflater.from(context).inflate(
                R.layout.include_viewpager, this, true);
        viewPager = (CBLoopViewPager) hView.findViewById(R.id.cbLoopViewPager);
        loPageTurningPoint = (ViewGroup) hView
                .findViewById(R.id.loPageTurningPoint);
        initViewPagerScroll();

        adSwitchTask = new AdSwitchTask(this);
    }

原來是viewpager+ LinearLayout竣稽,LinearLayout里面放的是小圓點指示器囱怕,都忘記有小圓點這東西, = = 丧枪。所以用LinearLayout包起來了光涂。讓我looklook布局文件,CBLoopViewPager拧烦?看來這就是關(guān)鍵所在咯。

CBLoopViewPager

讓我們看看钝计,有一些必要的方法在里面恋博。

  • CBPageAdapter
    繼承PagerAdapter,重寫了幾個方法一個一個看私恬。
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        int realPosition = toRealPosition(position);

        View view = getView(realPosition, null, container);
//        if(onItemClickListener != null) view.setOnClickListener(onItemClickListener);
        container.addView(view);
        return view;
    }

展示pager用的债沮,返回一個自己想要的view,第一行判斷當(dāng)前position本鸣,第二行根據(jù)position獲取view添加點擊事件疫衩。getView里面有一個holder抽出來可以自己構(gòu)造想要展示的view。這個用的時候有印象荣德,可以直接構(gòu)造闷煤,用著還挺方便的。

  @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        View view = (View) object;
        container.removeView(view);
    }

移除item時候調(diào)用移除掉之前的view

 @Override
    public void finishUpdate(ViewGroup container) {
        int position = viewPager.getCurrentItem();
        if (position == 0) {
            position = viewPager.getFristItem();
        } else if (position == getCount() - 1) {
            position = viewPager.getLastItem();
        }
        try {
            viewPager.setCurrentItem(position, false);
        }catch (IllegalStateException e){}
    }

更新后期調(diào)用的方法涮瞻,在這里面調(diào)用顯示到指定位置的view鲤拿,獲取了當(dāng)前顯示的view的position,判斷了一下第一個和最后一個....然后卡住了署咽。丫嘍近顷,啥東西生音,為啥position==0的時候獲取的是positon == datas.size?然后還移動了過去?待老夫冥想一下.....

 @Override
    public int getCount() {
        return canLoop ? getRealCount()*MULTIPLE_COUNT : getRealCount();
    }

原來漏掉了這一段...MULTIPLE_COUNT是300.我說咋又fristItem又lastItem,又RealCount的,原來是他給乘了300啊窒升。這樣就差不多了缀遍,因為需要循環(huán)所以需要處理循環(huán)的item。
??Adpater差不多就這樣了饱须,感覺還蠻容易的域醇。

  • onTouchEvent
@Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isCanScroll) {
            if (onItemClickListener != null) {
                switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        oldX = ev.getX();
                        break;

                    case MotionEvent.ACTION_UP:
                        newX = ev.getX();
                        if (Math.abs(oldX - newX) < sens) {
                            onItemClickListener.onItemClick((getRealItem()));
                        }
                        oldX = 0;
                        newX = 0;
                        break;
                }
            }
            return super.onTouchEvent(ev);
        } else
            return false;
    }

點擊事件,原來是判斷了UP和DOWN冤寿,我說有時候咋點著費勁呢歹苦,看上去是判斷左右滑動和單擊事件的,恩督怜,一定是這樣殴瘦。

  • 其他
    ??別的都是些常規(guī)的屬性設(shè)置,沒啥可看的号杠。

醒醒蚪腋,醒醒,你丫倒是轉(zhuǎn)啊~~~~

  • AdSwitchTask 轉(zhuǎn)轉(zhuǎn)轉(zhuǎn)
static class AdSwitchTask implements Runnable {

        private final WeakReference<ConvenientBanner> reference;

        AdSwitchTask(ConvenientBanner convenientBanner) {
            this.reference = new WeakReference<ConvenientBanner>(convenientBanner);
        }

        @Override
        public void run() {
            ConvenientBanner convenientBanner = reference.get();

            if(convenientBanner != null){
                if (convenientBanner.viewPager != null && convenientBanner.turning) {
                    int page = convenientBanner.viewPager.getCurrentItem() + 1;
                    convenientBanner.viewPager.setCurrentItem(page);
                    convenientBanner.postDelayed(convenientBanner.adSwitchTask, convenientBanner.autoTurningTime);
                }
            }
        }
    }

開線程姨蟋,這是viewpager切換屉凯,convenientBanner.autoTurningTime,還專門動態(tài)搞了個時間眼溶。好的悠砚,你終于可以輪播了,啪啪啪堂飞。

贈品:圓點指示器

  • 圓點基礎(chǔ)屬性
public ConvenientBanner setPageIndicator(int[] page_indicatorId) {
        loPageTurningPoint.removeAllViews();
        mPointViews.clear();
        this.page_indicatorId = page_indicatorId;
        if(mDatas==null)return this;
        for (int count = 0; count < mDatas.size(); count++) {
            // 翻頁指示的點
            ImageView pointView = new ImageView(getContext());
            pointView.setPadding(5, 0, 5, 0);
            if (mPointViews.isEmpty())
                pointView.setImageResource(page_indicatorId[1]);
            else
                pointView.setImageResource(page_indicatorId[0]);
            mPointViews.add(pointView);
            loPageTurningPoint.addView(pointView);
        }
        pageChangeListener = new CBPageChangeListener(mPointViews,
                page_indicatorId);
        viewPager.setOnPageChangeListener(pageChangeListener);
        pageChangeListener.onPageSelected(viewPager.getRealItem());
        if(onPageChangeListener != null)pageChangeListener.setOnPageChangeListener(onPageChangeListener);

        return this;
    }

配置圓點灌旧,往LinearLayout強行插♂入圖片,這是監(jiān)聽回調(diào)不拉不拉绰筛,那樣吧枢泰,雖然看上去懂了,但是估計自己寫的時候夠嗆铝噩,默念三遍衡蚂,啦啦啦啦啦啦啦,OK

  • 圓點的位置
  public ConvenientBanner setPageIndicatorAlign(PageIndicatorAlign align) {
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) loPageTurningPoint.getLayoutParams();
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, align == PageIndicatorAlign.ALIGN_PARENT_LEFT ? RelativeLayout.TRUE : 0);
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, align == PageIndicatorAlign.ALIGN_PARENT_RIGHT ? RelativeLayout.TRUE : 0);
        layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL, align == PageIndicatorAlign.CENTER_HORIZONTAL ? RelativeLayout.TRUE : 0);
        loPageTurningPoint.setLayoutParams(layoutParams);
        return this;
    }

作者可以的骏庸,夠人性的毛甲,RelativeLayout設(shè)置圓點的位置,左敞恋,中丽啡,右滿足你的所有體位,666

總結(jié)

  • 就這樣硬猫,和我想的差不多补箍,關(guān)鍵是里面的一些細節(jié)自己想不到改执,比如點擊事件,按下的時候別滑動等等坑雅,自己寫肯定就是各種大坑辈挂,學(xué)習(xí)一個思路吧。另外裹粤,這篇文章從早上稀稀拉拉寫终蒂,寫到現(xiàn)在,感覺周期有些長了遥诉,和自己想的不太一樣.....期間還玩了一會SourceTree,git,github和Markdown嘿嘿嘿拇泣。

OVER El psy congroo。

啊哈哈哈哈哈哈
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末矮锈,一起剝皮案震驚了整個濱河市霉翔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌苞笨,老刑警劉巖债朵,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瀑凝,居然都是意外死亡序芦,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門粤咪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谚中,“玉大人,你說我怎么就攤上這事寥枝〔卣龋” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵脉顿,是天一觀的道長。 經(jīng)常有香客問我点寥,道長艾疟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任敢辩,我火速辦了婚禮蔽莱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘戚长。我一直安慰自己盗冷,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布同廉。 她就那樣靜靜地躺著仪糖,像睡著了一般柑司。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锅劝,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天攒驰,我揣著相機與錄音,去河邊找鬼故爵。 笑死玻粪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诬垂。 我是一名探鬼主播劲室,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼结窘!你這毒婦竟也來了很洋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤晦鞋,失蹤者是張志新(化名)和其女友劉穎蹲缠,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悠垛,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡线定,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了确买。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斤讥。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖湾趾,靈堂內(nèi)的尸體忽然破棺而出芭商,到底是詐尸還是另有隱情,我是刑警寧澤搀缠,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布铛楣,位于F島的核電站,受9級特大地震影響艺普,放射性物質(zhì)發(fā)生泄漏簸州。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一歧譬、第九天 我趴在偏房一處隱蔽的房頂上張望岸浑。 院中可真熱鬧,春花似錦瑰步、人聲如沸矢洲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽读虏。三九已至责静,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掘譬,已是汗流浹背泰演。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留葱轩,地道東北人睦焕。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像靴拱,于是被迫代替她去往敵國和親垃喊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

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