本文出自簡(jiǎn)書:堯沐,如需轉(zhuǎn)載請(qǐng)標(biāo)明出處篮条,尊重原創(chuàng)謝謝
博客地址:http://www.reibang.com/p/6f40fb8d64e6
自定義View學(xué)習(xí)很久了,一直想寫點(diǎn)什么鞏固一下自己与纽,從最簡(jiǎn)單的自定一個(gè)日歷開始吧
組合控件就是用系統(tǒng)已經(jīng)封裝好的東西然后加以組合形成一個(gè)我們需要的東西侈离,相對(duì)于各種畫出來的簡(jiǎn)單很多很多脯倚。由易到難
1507346319(1).jpg
首先我們看一下日歷-沒錯(cuò)這就是win10自帶的 注意看紅色字體恬试,是每個(gè)地方的組成审丘,這么一看是不是簡(jiǎn)單很多很多
接下來寫布局- -寫布局注意幾點(diǎn) 不要嵌套很深吏够,這樣解析會(huì)慢(最近看書學(xué)的優(yōu)化~ ~)
說實(shí)在的很不想寫布局這種東西 麻煩的一逼 你就當(dāng)我寫好了吧- -
因?yàn)槭墙M合控件 所以就不是繼承VIew 而是一個(gè)布局 我這里繼承線性布局
然后實(shí)現(xiàn)三個(gè)構(gòu)造方法
@RequiresApi(api = Build.VERSION_CODES.N)
public DataView(Context context) {
super(context);
initFindIdAndLinsen(context);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public DataView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initFindIdAndLinsen(context);
}
@RequiresApi(api = Build.VERSION_CODES.N)
public DataView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initFindIdAndLinsen(context);
}
initFindIdAndLinsen 這個(gè)方法是綁定控件以及設(shè)置監(jiān)聽
里面的代碼很簡(jiǎn)單
@RequiresApi(api = Build.VERSION_CODES.N)
private void initFindIdAndLinsen(final Context context) {
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.view_calendar, this);
mWeekUp = (ImageView) findViewById(R.id.week_up);
mWeeknExt = (ImageView) findViewById(R.id.weekn_ext);
mWeekToday = (TextView) findViewById(R.id.week_today);
mWeekRecy = (RecyclerView) findViewById(R.id.week_recy);
renderCalender(context);
mWeekUp.setOnClickListener(new OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onClick(View v) {
calendata.add(Calendar.MONTH, -1);
renderCalender(context);
}
});
mWeeknExt.setOnClickListener(new OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public void onClick(View v) {
calendata.add(Calendar.MONTH, 1);
renderCalender(context);
}
});
}
這些都沒什么好說的對(duì)吧,其實(shí)難點(diǎn)就一個(gè) 就是日期的計(jì)算
1507346319(1).jpg
注意看滩报,我這個(gè)月的第一天是1號(hào) 他在星期日的位置 主要就是這個(gè)的計(jì)算锅知,這個(gè)要怎么算呢
/**
* 渲染界面
*
* @param context
*/
@RequiresApi(api = Build.VERSION_CODES.N)
private void renderCalender(Context context) {
/**
* 時(shí)間格式化
*/
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM yyyy");
mWeekToday.setText(simpleDateFormat.format(calendata.getTime()));
/**
* 為了不污染 本身的時(shí)間所以復(fù)制一個(gè)
*/
Calendar calendarOne = (Calendar) calendata.clone();
List<Date> mDate = new ArrayList<>();
/**
* 把日期放在第一天 然后看最后一個(gè)周末剩下幾天 然后位移
*/
calendarOne.set(Calendar.DAY_OF_MONTH, 1);
calendarOne.add(Calendar.DAY_OF_MONTH, - calendarOne.get(Calendar.DAY_OF_WEEK) - 1);
/**
* 裝數(shù)據(jù)進(jìn)去
*/
while (mDate.size() < 42) {
mDate.add(calendarOne.getTime());
calendarOne.add(Calendar.DAY_OF_MONTH, 1);
}
/**
* recylerview的Adapert總會(huì)把- -
*/
DataViewAdapter dataViewAdapter = new DataViewAdapter(R.layout.item_data, mDate);
mWeekRecy.setAdapter(dataViewAdapter);
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 7);
mWeekRecy.setLayoutManager(gridLayoutManager);
}
這樣這個(gè)控件就好了,難的地方就在怎么算日期上面 - -