Android自定義View(RollWeekView-炫酷的星期日期選擇控件)_第1頁
Android自定義View(RollWeekView-炫酷的星期日期選擇控件)_第2頁
Android自定義View(RollWeekView-炫酷的星期日期選擇控件)_第3頁
Android自定義View(RollWeekView-炫酷的星期日期選擇控件)_第4頁
Android自定義View(RollWeekView-炫酷的星期日期選擇控件)_第5頁
已閱讀5頁,還剩10頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

Android自定義View(RollWeekView—

炫酷的星期日期選擇控件)最近收到一個自定義控件的需求,需要做一個日期選擇控件,實現(xiàn)圖如下:一次展示一個星期的5天,中間放大的為當前選中的;如果點擊了其中一個日期,比如星期五,那么整體向左滑動,并將星期五慢慢放大,星期三慢慢縮小,星期六和星期天就展示出來了;如果繼續(xù)點擊星期六,那么照樣是整體向左滑動一個單位,星期日右邊就需要塞進一個星期一。就是一個無限循環(huán)的過程,中間選中的需要展示當天的日期。1、分析最開始,我想到在LinearLayout中依次排開7個子控件(星期幾),當點擊之后,把所有的子控件通過動畫移動相應的偏移量,但是,如果移動后就會出現(xiàn)空位的情況(周一的左邊和周日的右邊沒有了),所以這種方式可是可以,但是要解決無限循環(huán)空位的情況。于是就想到能不能多添加幾個子控件作為空位替補?這個方法肯定能實現(xiàn),但是究竟需要多少個替補呢?這些替補應該放在什么位置呢?當前展示的5個子控件中,如果點擊最左邊或者最右邊,這樣的偏移量是最大的,需要便宜兩個子控件單位,所以左邊和右邊最多個需要2個替補就行了,算起來也不多,一共才9個(當前展示5個,左邊隱藏替補2個,右邊隱藏替補2個)。在點擊之前,先將替補位置設置好,當點擊之后,所有子控件執(zhí)行偏移動畫(不可能出現(xiàn)空位,最多偏移2位),動畫結(jié)束之后,再重新為隱藏的4個替補分配位置并綁定數(shù)據(jù),綁定什么數(shù)據(jù)那就看當前中間顯示的是星期幾了。分析圖如下:Ip.width=ITEM_WIDTH;H_5.setLayoutParams(lp);Ip二(LinearLayout.LayoutParams)ll_6.getLayoutParams();Ip.width=ITEM_WIDTH;H_6.setLayoutParams(lp);Ip=(LinearLayout.LayoutParams)lI_7.getLayoutParams();Ip.width=ITEM_WIDTH;H_7.setLayoutParams(lp);Ip二(LinearLayout.LayoutParams)ll_8.getLayoutParams();Ip.width=ITEM_WIDTH;11_8.setLayoutParams(lp);Ip二(LinearLayout.LayoutParams)ll_9.getLayoutParams();Ip.width=ITEM_WIDTH;H_9.setLayoutParams(lp);)5、點擊后執(zhí)行動畫上面的步驟完成之后,基本上已經(jīng)完成的控件的初始設置,接下來就是點擊子控件后執(zhí)行動畫了。這里一共需要執(zhí)行兩套動畫,一套是縮放動畫、一套是移動動畫。添加點擊事件的代碼就不貼出來了,下面是執(zhí)行動畫的方法:privatevoidstartAnimation(finalWEEKDAYcenterWitch,finalLinearLayoutHClickView){if(centerWitch==centerNow)return;animalFinish=false;LinearLayoutinnerLL=(LinearLayout)113.getChildAt(0);TextViewtvDate=(TextView)innerLL.getChildAt(1);tvDate.setVisibility(View.GONE);innerLL=(LinearLayout)llClickView.getChildAt(O);tvDate=(TextView)innerLL.getChildAt(1);tvDate.setVisibility(View.VISIBLE);//根據(jù)當前中間位置顯示的和被點擊的日期,獲取需要偏移的增量intoffset=getXOffset(centerWitch);Log.d(TAG,”當前中間為“+centerNow+”,點擊的是“+centerWitch+”偏移量:“offset);〃當前中間位置的需要縮放到原尺寸// Log.v(TAG,"中間item縮放量scaleX=n+113.getChildAt(0).getScaleX()+nscaleY=n+lI3.getChildAt(0).getScaleY());ObjectAnimatoranim100=ObjectAnimator.ofFloat(113.getChildAt(0),nscaleXn,113.getChildAt(0).getScaleX(),1.Of);ObjectAnimatoranim101113.getChildAt(0).getScaleY(),1.00;〃被點擊的需要放大ObjectAnimatoranim102"scaleX",1,scaleSize);ObjectAnimatoranim103"scaleY“,1,scaleSize);=ObjectAnimator.ofFloat(113.getChildAt(0),nscaleYn=ObjectAnimator.ofFloat(113.getChildAt(0),nscaleYn,=ObjectAnimator.ofFloat(llClickView.getChildAt(0),=ObjectAnimator.ofFloat(llClickView.getChildAt(0),ObjectAnimator anim104 =ObjectAnimator.ofFloat(llClickView.getChildAt(0),nscaleY'\1,scaleSize);offset);offset);offset);offset);offset);offset);offset);offset);offset);offset);offset);offset);offset);offset);ObjectAnimatoranimlObjectAnimatoranim2ObjectAnimatoranim3ObjectAnimatoranim4ObjectAnimatoranim5ObjectAnimatoranim6ObjectAnimatoranim7ObjectAnimatoranim8ObjectAnimatoranim9=ObjectAnimator.ofFloat(ll_1,nX"=ObjectAnimator.ofFloat(ll_2,nXn=ObjectAnimator.ofFloat(ll_3,nX"=ObjectAnimator.ofFloat(ll_4,nXn=ObjectAnimator.ofFloat(ll_5,nXn=ObjectAnimator.ofFloat(ll_6,nXn=ObjectAnimator.ofFloat(ll_7,HXH二ObjectAnimator.ofFloat(ll_8,nXn=ObjectAnimator.ofFloat(ll_9,HXHll_l.getX(),ILl.getXQ+ll_2.getX(),ll_2.getX()+lL3.getX(),lL3.getX()+ll_4.getX(),ll_4.getX()+ll_5.getX(),ll_5.getX()+ll_6.getX(),ll_6.getX()+ll_7.getX(),ll_7.getX()+lL8.getX(),ll_8.getX()+ll_9.getX(),ll_9.getX()+AnimatorSetanimSet=newAnimatorSet();animSet.setDuration(du);animSet.playTogether(anim100,animlOl,anim102,animl03,animl,anim2,anim3,anim4,anim5,anim6,anim7,anim8,anim9);animSet.addListener(newAnimator.AnimatorListener(){@OverridepublicvoidonAnimationStart(Animatoranimation){)@OverridepublicvoidonAnimationEnd(Animatoranimation){Log.w(TAG,”動畫結(jié)束后位置:”+n」.getX()+“n+ll_2.getX()+n”+H_3.getX()+”+ll_4.getX()+"”+ll_5.getX()+””+ll_6.getX()+"”+L7.getX()+"“+ll_8.getX()+"“+ll_9.getX());setCenter(centerWitch);animalFinish=true;)@OverridepublicvoidonAnimationCancel(Animatoranimation){)@OverridepublicvoidonAnimationRepeat(Animatoranimation){)});animSet.start();)7、重置預備控件動畫執(zhí)行完畢之后,要做兩個操作。第一個就是將當前不在顯示范圍的4個子控件左右各放2個,第二步就是為預備控件綁定新的星期日期。下面的方法是根據(jù)各個子控件的坐標來判斷是隱藏還是展示,然后為隱藏的控件重新安排位置;然后綁定數(shù)據(jù):/*這些引用代表當前正在顯示的5個條目和四個預備條目,由于ll_x系列條目是不斷移動的,所以此處需要根據(jù)ll_x的位置重新為llx賦值其中111J5為當前正在顯示的條目,116、117為右邊隱藏的預備條目,118>119為左邊的隱藏預備條目/privateLinearLayout111,112,113,114,115,116,117,118,119;/**1、找到正在展示的五個item,并將預備item復位*/privatevoidsetCenter(WEEKDAYweekDay){〃記錄當前顯示在中間的星期XcenterNow=weekDay;〃1、找到當前顯示的5個條目的位置List<LinearLayout>list=newArrayListo(llList);for(inti=0;i<5;i++){for(intj=0;j<list.size();j++){LinearLayout11=list.get(j);if(ll.getX()==ITEM_WIDTH*i){list.rcmovc(ll); 〃找到之后就remove可以減少后面遍歷的次數(shù)// Log.d(TAG,“找到“+i+”了”+11);switch(i){case0:111=11;break;112=11;break;113=11;〃當前中間位置item放大113.getChildAt(0),setScaleX(scaleSize);113.getChildAt(0).setScaleY(scaleSize);break;114二11;break;115二11;break;))))Log.i(TAG”找完后還?!?list.size()+”總:"+llList.size());〃2、剩余的四個作為預備,歸位,左邊隱藏兩個,右邊隱藏兩個for(inti=0;i<list.size();i++){LinearLayout11=list.get(i);switch(i){case0:〃左1ll.setX(-ITEM_WIDTH*2);118=11;break;〃左2ll.setX(-ITEM_WIDTH*1);119=11;break;〃右1setX(ITEM_WIDTH*5);116=11;break;〃右2lLsctX(ITEM_WIDTH*6);117=11;break;))〃綁定數(shù)據(jù)reBoundDataByCenter(weekDay);/**2、重新綁定數(shù)據(jù)*/privatevoidreBoundDataByCenter(WEEKDAYweekDay){if(weekDay==WEEKDAY.wkl){/*星期1在中間,依次為4、5、6、7、1、2、3、4、5*/setLLText(118,4,false);setLLText(H9,5,false);setLLText(lll,6,false);setLLText(112,7,false);setLLText(113,1,true);setLLText(114,2,false);setLLText(H5,3,false);setLLText(116,4,false);setLLText(117,5,false);}elseif(weekDay==WEEKDAY.wk2){/*星期2在中間,依次為5、6、7、1、2、3、4、5、6*/setLEText(H8,5,false);setLLText(119,6,false);setLLText(lll,7,false);setLLText(112,1,false);setLLText(113,2,true);setLLText(114,3,false);setLLText(115,4,false);setLLText(116,5,false);setLLText(117,6,false);}elseif(weekDay==WEEKDAY.wk3){/*星期3在中間,依次為6、7、1、2、3、4、5、6、7*/setLLText(118,6,false);setLLText(119,7,false);setLLText(lll,1,false);setLLText(112,2,false);setLLText(113,3,true);setLLText(H4,4,false);setLLText(115,5,false);setLLText(116,6,false);setLLText(117,7,false);}clscif(wcckDay==WEEKDAY.wk4){/*星期4在中間,依次為7、1、2、3、4、5、6、7、1*/setLLText(118,7,false);setLLText(119,1,false);setLLText(ll1,2,false);setLLText(112,3,false);setLLText(113,4,true);setLLText(114,5,false);setLLText(115,6,false);setLLText(116,7,false);setLLText(117,1,false);}elseif(weekDay==WEEKDAY.wk5){/*星期5在中間,依次為1、2、3、4、5、6、7、1、2*/setLLText(118,1,false);setLLText(119,2,false);setLLText(lll,3,false);setLLText(112,4,false);setLLText(113,5,true);setLLText(114,6,false);setLLText(115,7,false);setLLText(116,1,false);setLLText(117,2,false);}elseif(weekDay==WEEKDAY.wk6){/*星期6在中間,依次為2、3、4、5、6、7、1、2、3*1setLLText(118,2,false);setLLText(119,3,false);setLLText(lll,4,false);setLLText(112,5,false);setLLText(113,6,true);setLLText(114,7,false);setLLText(115,1,false);setLLText(116,2,false);setLLText(117,3,false);}elseif(weekDay==WEEKDAY.wk7){/*星期7在中間,依次為3、4、5、6、7、1、2、3、4*/setLLText(118,3,false);setLLText(119,4,false);setLLText(lll,5,false);setLLText(112,6,false);setLLText(113,7,true);setLLText(114,1,false);setLLText(115,2,false);setLLText(116,3,false);setLLText(117,4,false);))privatevoidsetLLText(LinearLayout11,intwitchDay,booleanshowDate){ILsetTag(witchDay); 〃便于區(qū)分點擊事件LinearLayoutinnerLL=(LinearLayout)ll.getChildAt(O);TextViewtv=(TextView)innerLL.getChildAt(O);Stringtext="星期”+WEEK_STR[witchDay];tv.setText(text);TextViewtvDate=(TextView)innerLL.getChildAt(1);text=DATE_STR.get(witchDay);tvDate.setText(text);if(showDate){tvDate.setVisibility(View.VISIBLE);}else{tvDate.setVisibility(View.GONE);))當執(zhí)行完上面的方法后,控件的狀態(tài)又回到了初始狀態(tài),下次點擊又會重復上面的步驟。因為動畫執(zhí)行完后,只有被隱藏的子控件需要重新安排位置,所以,不會出現(xiàn)閃跳的現(xiàn)象。最終效果圖如卜:O€)OOG)?)010000 O€)OOG)?)010000 ,但是新的問題又來了,動畫執(zhí)行完畢之后,怎么判斷哪些子控件是當前正在顯示的呢(中間五個)?由于正在顯示的子控件的位置是可以確定的,因為要重寫onMeasure(),在onMeasure。方法中可以得到單個子控件的寬度(item_width=getMeasureWidth()/5),動畫結(jié)束之后,遍歷這些子控件,如果x=0的那肯定就是當前正在展示的第一個子控件,x==item_width則是第二個…剩余的4個就不用判斷了,直接將兩個移動到左邊,兩個移動到右邊,然后重新為這四個替補設置數(shù)據(jù)。2、定義控件布局組合控件的布局如下:<?xmlversion=n1.0nencoding=nutf-8n?><LinearLayoutxmlns:android=nHandroid:layout_width=nmatch_parentnandroid:layout_height="match_parentHandroid:orientation="horizontal”android:gravity=,'center_vertical',><LinearLayoutandroid:id=n@+id/ll_1nandroid:layout_width=nwrap_contentnandroid:layout_height=Hmatch_parentnandroid:gravity=ncentern><LinearLayoutandroid:layout_width=n@dimen/week_item_sisenandroid:layout_height=,'@dimen/week_item_siseHandroid:background=n@drawable/week_one_bgnandroid:oricntation=,,vcrticar,android:gravity=,,centern><TextViewandroid:id=n@+id/tv_lHandroid:layout_width=Hwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=ncenter"android:text=',Mln/><TextViewandroid:id=',@+id/tv_dater,android:layout_width="wrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=HcenterHandroid:text="周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id=",@+id/ll_2Mandroid:layout_width=nwrap_contentnandroid:layout_height=nmatch_parentMandroid:gravity=ncentern><LinearLayoutandroid:layout_width=n@dimen/week_item_sisenandroid:layout_height=n@dimen/week_item_sisenandroid:background=n@drawable/week_one_bgnandroid:orientation="vertical”android:gravity二"center”><TextViewandroid:id="@+id/tv_2"android:layout_width=nwrap_contentnandroid:layout_height=nwrap_contentuandroid:gravity="center1'android:text="周"/><TextViewandroid:id=n@+id/tv_date2nandroid:layout_width=Hwrap_content"android:layout_height=nwrap_contentnandroid:gravity=Hcenternandroid:text="周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id=n@+id/ll_3Mandroid:layout_width=nwrap_contcntHandroid:layout_height=nmatch_parentnandroid:gravity=Hcentern><LinearLayoutandroid:layout_width=H@dimen/week_item_siseHandroid:layout_height="@dimen/week_item_sisenandroid:background=n@drawable/week_one_bgnandroid:orientation=',verticar,android:gravity=,,centern><TextViewandroid:id="@+id/tv_3"android:layout_width=Hwrap_contentnandroid:layout_height=Hwrap_contentHandroid:gravity=ncenterHandroicktext=“周"/><TextViewandroid:id="@+id/tv_date3"android:layout_width=nwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=ncenternandroid:text=“周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id=n@+id/ll_4nandroid:layout_width=nwrap_contentnandroid:layout_height=nmatch_parentHandroid:gravity=Hcentern><LinearLayoutandroid:layout_width=n@dimen/week_item_sisenandroid:layout_height="@dimen/week_item_sisenandroid:background=n@drawable/week_one_bg"android:orientation="vertical”android:gravity=Hcentern><TextViewandroid:id=H@+id/tv_4Handroid:layout_width=nwrap_contentnandroid:layout_height=Hwrap_contentnandroid:gravity=ncenterHandroid:text=“周"/><TextViewandroid:id=n@+id/tv_date4nandroid:layout_width=nwrap_contentnandroid:layout_hcight=nwrap_contcntnandroid:gravity=ncenterHandroid:text=“周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id=n@+id/lL5nandroid:layout_width=nwrap_content"android:layout_height=nmatch_parentnandroid:gravity=Hcentern><LinearLayoutandroid:layout_width=H@dimen/week_item_sisenandroid:layout_height=,'@dimen/week_item_sisenandroid:background=H@drawable/week_one_bg"android:orientation=,'verticalHandroid:gravity=ncenterH><TextViewandroid:id="@+id/tv_5"android:layout_width=Hwrap_content"android:layout_height=Hwrap_contentHandroid:gravity=ncenterHandroid:text="周"/><TextViewandroid:id=n@+id/tv_date5nandroid:layout_width=Hwrap_content"android:layout_height=nwrap_contentnandroid:gravity="center”android:text="周”/></LinearLayout></LinearLayout><LinearLayoutandroid:id=',@+id/ll_6nandroid:layout_width=nwrap_contentnandroid:layout_height=nmatch_parentnandroid:gravity=Hcentern><LinearLayoutandroid:layout_width=n@dimen/week_item_sisenandroid:layout_height=,,@dimen/week_item_sisenandroid:background=H@drawable/week_one_bgnandroid:orientation=,'verticar,android:gravity=ncentern><TextViewandroid:id=n@+id/tv_6nandroid:layout_width=nwrap_contentnandroid:layout_height=Hwrap_contentHandroid:gravity=Hcenternandroid:text="周"/><TextViewandroid:id="@+id/tv_date6"android:layout_width=Hwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=ncenterHandroid:text=“周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id="@+id/l1_7”android:layout_width=Mwrap_contentnandroid:layout_height=nmatch_parentnandroid:gravity=Hcentern><LinearLayoutandroid:layout_width=H@dimen/week_item_siseHandroid:layout_height=,,@dimen/week_item_siseMandroid:background=n@drawable/week_one_bgnandroid:orientation=nverticar'android:gravity=,,centern><TextViewandroid:id="@+id/tv_7”android:layout_width=Hwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=HcenterHandroid:text="周"/><TextViewandroid:id=n@+id/tv_date7nandroid:layout_width=Hwrap_contentnandroid:layout_height="wrap_content”android:gravity=HcenterHandroid:text=“周"/></LinearLayout></LinearLayout><LinearLayoutandroid:id=',@+id/ll_8,,android:layout_width=Hwrap_contentnandroid:layout_height=Hmatch_parentnandroid:gravity=nccntcrn><LinearLayoutandroid:layout_width=n@dimen/week_item_siseHandroid:layout_height=,,@dimen/week_item_siseMandroid:background=n@drawable/week_one_bgnandroid:orientation=,,verticar,android:gravity=,'center,'><TextViewandroid:id=n@+id/tv_8nandroid:layout_width=nwrap_contentnandroid:layout_height=Hwrap_contentnandroid:gravity=ncenternandroid:text="周"/><TextViewandroid:id=n@+id/tv_date8nandroid:layout_width=Hwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=HcenterHandroid:text="周”/></LinearLayout></LinearLayout><LinearLayoutandroid:id="@+id/ll_9”android:layout_width=nwrap_contentnandroid:layout_height=nmatch_parentMandroid:gravity=ncentern><LinearLayoutandroid:layout_width=n@dimen/week_item_sisenandroid:layout_height=,,@dimen/week_item_sisenandroid:background=n@drawable/week_one_bgnandroid:orientation=,'verticar,android:gravity=ncentern><TextViewandroid:id="@+id/tv_9"android:layout_width=nwrap_contentnandroid:layout_height=Hwrap_contentHandroid:gravity=,'center,,android:text=nMln/><TextViewandroid:id=n@+id/tv_date9nandroid:layout_width=nwrap_contentnandroid:layout_height=nwrap_contentnandroid:gravity=Hcenternandroid:tcxt="周”/></LinearLayout></LinearLayout></LinearLayout>布局寫完后,接下來應該找一個容器接納他們,這個容器就是我們定義的CustomWeekView,讓其繼承LinearLayout,然后重寫構(gòu)造方法,并初始化子控件;此處自定義屬性就不再贅述,之前的所有自定義控件案例中都講解過publicclassCustomWeekViewextendsLinearLayout{publicCustomWeekView(Contextcontext){this(context,null);)publicCustomWeekView(Contextcontext,AttributeSetattrs){this(context,attrs,0);)publicCustomWeekView(Contextcontext,AttributeSetattrs,intdefStyleAttr){super(context,attrs,defStyleAttr);init(context,attrs);)privatevoidinit(Contextcontext,AttributeSetattrs){LayoutInflater.from(context).inflate(R.layout.custom_week_layout,this,true);11_1=(LinearLayout)findViewById(R.id.ll_l);11_2二(LinearLayout)findViewById(R.id.ll_2);???tv_l=(TextView)findViewById(R.id.tv_l);tv_2=(TextView)findViewById(R.id.tv_2);???tv_datel二(TextView)findViewById(R.id.tv_datel);tv_date2=(TextView)findViewById(R.id.tv_date2);???if(attrs!=null){TypedArrayta=context.obtainStyledAttributes(attrs,R.styleable.LimitScroller);limit=5;background=ta.getColor(R.styleable.LimitScroller_android_background,Color.TRANSPARENT);textSize=ta.getDimension(R.styleable.LimitScroller_android_textSize,15f);finalfloatfontScale=context.getResources().getDisplayMetrics().scaledDensity;textSize=textSize/fontScale+0.5f;dateTextSize=ta.getInteger(R.styleable.LimitScroll

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論