本文出自簡書:堯沐,如需轉載請標明出處,尊重原創謝謝
博客地址:http://www.lxweimin.com/p/6f40fb8d64e6
自定義View學習很久了,一直想寫點什么鞏固一下自己,從最簡單的自定一個日歷開始吧
組合控件就是用系統已經封裝好的東西然后加以組合形成一個我們需要的東西,相對于各種畫出來的簡單很多很多。由易到難
1507346319(1).jpg
首先我們看一下日歷-沒錯這就是win10自帶的 注意看紅色字體,是每個地方的組成,這么一看是不是簡單很多很多
接下來寫布局- -寫布局注意幾點 不要嵌套很深,這樣解析會慢(最近看書學的優化~ ~)
說實在的很不想寫布局這種東西 麻煩的一逼 你就當我寫好了吧- -
因為是組合控件 所以就不是繼承VIew 而是一個布局 我這里繼承線性布局
然后實現三個構造方法
@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 這個方法是綁定控件以及設置監聽
里面的代碼很簡單
@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);
}
});
}
這些都沒什么好說的對吧,其實難點就一個 就是日期的計算
1507346319(1).jpg
注意看,我這個月的第一天是1號 他在星期日的位置 主要就是這個的計算,這個要怎么算呢
/**
* 渲染界面
*
* @param context
*/
@RequiresApi(api = Build.VERSION_CODES.N)
private void renderCalender(Context context) {
/**
* 時間格式化
*/
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM yyyy");
mWeekToday.setText(simpleDateFormat.format(calendata.getTime()));
/**
* 為了不污染 本身的時間所以復制一個
*/
Calendar calendarOne = (Calendar) calendata.clone();
List<Date> mDate = new ArrayList<>();
/**
* 把日期放在第一天 然后看最后一個周末剩下幾天 然后位移
*/
calendarOne.set(Calendar.DAY_OF_MONTH, 1);
calendarOne.add(Calendar.DAY_OF_MONTH, - calendarOne.get(Calendar.DAY_OF_WEEK) - 1);
/**
* 裝數據進去
*/
while (mDate.size() < 42) {
mDate.add(calendarOne.getTime());
calendarOne.add(Calendar.DAY_OF_MONTH, 1);
}
/**
* recylerview的Adapert總會把- -
*/
DataViewAdapter dataViewAdapter = new DataViewAdapter(R.layout.item_data, mDate);
mWeekRecy.setAdapter(dataViewAdapter);
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 7);
mWeekRecy.setLayoutManager(gridLayoutManager);
}
這樣這個控件就好了,難的地方就在怎么算日期上面 - -