?Banner由圖片,標(biāo)題組成枢舶,有的還有四個點
?除了第三方的涂邀,還可以用viewpager來實現(xiàn),只需要給viewpager外面套一個容器
?原因:里面有title和viewpager2
?還有一種是自己定義一個viewgroup,滑動和監(jiān)聽(事件分發(fā))
?設(shè)置一個adapter研铆,在adapter綁定一個banner
?adapter是一個經(jīng)典模式埋同,很多地方都會用到,viewgroup棵红,recyclerview...
viewpager2支持垂直滑動凶赁,支持RTL布局,支持notifyDataSetChanged
?banner的容器是約束布局逆甜,在里面添加內(nèi)容虱肄,在onFinishInflate里面添加圖片,標(biāo)題交煞,
?先創(chuàng)建ConstrainSet的對象咏窿,將布局克隆,執(zhí)行constrainSet.clone()方法错敢,然后繪制布局翰灾,將各個方向連起來,并且給該控件設(shè)置大小addview稚茅,在該容器中添加imageview纸淮。
?在一棵view樹,ID只要在里面不重復(fù)就行亚享,在其他分支重復(fù)不影響
?初始化view就是為了把view添加進(jìn)去咽块,viewpager2,imageview欺税,textview
執(zhí)行順序:解析xml侈沪,創(chuàng)建對象,繪制布局晚凿,設(shè)置寬高亭罪,添加進(jìn)容器中,把設(shè)置好的條件用在viewpager上
?啟動倆種用法:把圖片和title的數(shù)組傳過去歼秽,或者自己提供布局
?實體類中必須有接口中的倆個方法 getImageUrl()应役,getTitle();
?adapter中創(chuàng)建onCreateViewHolder方法,直接創(chuàng)建imageview的對象燥筷,設(shè)置布局的大小箩祥,在onBindViewHolder中判斷id來添加圖片,綁定布局肆氓。
?圖片切換的時候title也會切換袍祖,所以要設(shè)置一個監(jiān)聽pager2.registerOnPageChangeCallback,在監(jiān)聽里面添加
textView.setText(mDatas.get(position%mDatas.size()).getTitle());
?滑動循環(huán):滑動到最后一頁時谢揪,無法繼續(xù)往下滑蕉陋,把count改成最大捐凭,將下標(biāo)設(shè)置為position%mDatas.size(),
?創(chuàng)建5個view凳鬓,有4個圖片柑营,當(dāng)?shù)谒膫€圖片滑出去時,第一個圖片就會進(jìn)去第五個view村视,展示出來官套;想要從banner1滑到banner4,要通過最大值item/2%data.size來判斷
?banner指示器可以用RadioGroup和RadioButton來實現(xiàn)蚁孔,還可以用自定義view來實現(xiàn)
?用RadioGroup和RadioButton來實現(xiàn)奶赔,高是圓點的直徑,長是4個圓點的直徑+間距
?banner數(shù)量不限制杠氢,指示器要設(shè)置一個最大值站刑,不能超過最大值
?指示器需要設(shè)置半徑,數(shù)量鼻百,間距绞旅,選中的顏色,未選中的顏色
?坐標(biāo):絕對坐標(biāo):相對于屏幕
相對坐標(biāo):相對于其他控件
?約束布局連線時需要id温艇,所以要寫getId
?需要在Indicator接口中定義指示器需要的屬性因悲,通過CircleIndicator繼承view實現(xiàn)這個接口,為了有這個方法勺爱,
?view中有g(shù)etId和setId方法晃琳,還要定義getId和setId方法,是為了在banner中添加到屏幕上pager.getId()
?多態(tài):用父類指向子類琐鲁,會傳不同的子類卫旱,實現(xiàn)不同的方法
new CircleIndicator(getContext());返回private Indicator mIndicator;適用于各種指示器
?用private來定義變量,不想讓別人隨意訪問的變量就用private围段,第三方的SDK顾翼,想對外暴露的用public,不想暴露的奈泪,用private
?先計算出控件的寬和高适贸,然后畫,需要畫筆段磨,要new一個paint取逾,初始化畫筆耗绿,去鋸齒(setAntiAlias(true))苹支,實心圓(setStyle(Paint.Style.FILL)),圓的顏色(setColor(Color.WHITE))误阻,在每個CircleIndicator方法里都需要初始化畫筆债蜜,半徑修改了晴埂,就會重新計算,invalidate(); 就是為了 刷新頁面寻定,使之前的無效儒洛,重新onMeasure onLayout,onDraw,
?當(dāng)它添加到window上時狼速,會計算琅锻,在onMeasure方法中,設(shè)置自己的寬和高向胡,在onDraw方法中通過畫筆繪制恼蓬。創(chuàng)建CircleIndicator對象,設(shè)置id僵芹,添加在view中addview处硬,設(shè)置約束條件,將四個方向連接起來拇派。
?要先設(shè)置指示器的數(shù)量荷辕,才能設(shè)置寬和高,否則沒有效果
?滑動圖片件豌,展示第二張圖片疮方,需要重新執(zhí)行onDraw,需要在setCurrent方法里執(zhí)行invalidate()方法
?跑馬燈效果:
textView.setEllipsize(TextUtils.TruncateAt.MARQUEE);
textView.setSelected(true);
textView.setMarqueeRepeatLimit(-1);
textView.setSingleLine(true);
?輪播:
用handle來實現(xiàn)茧彤,停止時移除 getHandler().removeCallbacks(mLoopTask);
開始時案站, getHandler().postDelayed(mLoopTask, mInterval);
?時間較長時,會一直存在handle中棘街,導(dǎo)致內(nèi)存泄漏蟆盐,所以要移除
private Runnable mLoopTask = new Runnable() {
@Override
public void run() {
int item = pager2.getCurrentItem();
pager2.setCurrentItem(++item, true);
getHandler().postDelayed(this, mInterval);
}
};
private void stopLoop() {
getHandler().removeCallbacks(mLoopTask);
}
private void startLoop() {
if (isAutoLoop && mDatas != null && mDatas.size() > 1) {
getHandler().postDelayed(mLoopTask, mInterval);
}
}
?手指觸摸屏幕時,banner不會輪播遭殉,事件分發(fā)的第一個方法dispatchTouchEvent石挂,設(shè)置監(jiān)聽MotionEvent.ACTION_DOWN
手指按下,執(zhí)行stopLoop()险污,MotionEvent.ACTION_UP手指抬起痹愚,執(zhí)行startLoop()
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
if (visibility == VISIBLE) {
startLoop();
} else {
stopLoop();
}
}