

Android自定义控件之日历控件
source link: http://www.androidchina.net/3641.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Android自定义控件之日历控件
三月份学习android,至今也有半年有余,中间也做过两个项目,但是依然感觉自己做的应用不是很有新意,比不上应用市场上那些应用如此绚丽。所以自己仍需继续努力。学习至今,仍感觉自定义控件是一块硬骨头,还没修炼到身后的内功,下面就切入正题,以一次项目的需求,来实现一个自定义的日历控件。效果图先来一发。
我们分析下效果图,然后确定我们的需求。
(1)、绘制星期的自定义View,用于标识日期的礼拜。
(2)、绘制日期的自定义View。
(3)、绘制事务圆圈,从效果图中我们以红圈标识今日有事务。
(4)、绘制选中日期的颜色。
(5)、对选中日期进行点击事件的处理。
通过对效果图的分析,得出了我们的需求,我们在仔细分析效果图,发现里面就是绘制文字和绘制线条,所以我们只要回Canvas的这两个功能即可,主要的难点是如何将这些日期进行位置的安排,接下来我们就来逐个分析如何实现一个自定义View。
实现Week的自定义View
分析下效果图,我们需要绘制上下两条线、然后绘制描述文字(日、一、二、三、四、五、六)。下面就讲解下我们的实现。先看着部分的源码,然后在分开讲解。
public
class
WeekDayView
extends
View {
//上横线颜色
private
int
mTopLineColor = Color.parseColor(
"#CCE4F2"
);
//下横线颜色
private
int
mBottomLineColor = Color.parseColor(
"#CCE4F2"
);
//周一到周五的颜色
private
int
mWeedayColor = Color.parseColor(
"#1FC2F3"
);
//周六、周日的颜色
private
int
mWeekendColor = Color.parseColor(
"#fa4451"
);
//线的宽度
private
int
mStrokeWidth =
4
;
private
int
mWeekSize =
14
;
private
Paint paint;
private
DisplayMetrics mDisplayMetrics;
private
String[] weekString =
new
String[]{
"日"
,
"一"
,
"二"
,
"三"
,
"四"
,
"五"
,
"六"
};
public
WeekDayView(Context context, AttributeSet attrs) {
super
(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
paint =
new
Paint();
}
@Override
protected
void
onMeasure(
int
widthMeasureSpec,
int
heightMeasureSpec) {
int
widthSize = MeasureSpec.getSize(widthMeasureSpec);
int
widthMode = MeasureSpec.getMode(widthMeasureSpec);
int
heightSize = MeasureSpec.getSize(heightMeasureSpec);
int
heightMode = MeasureSpec.getMode(heightMeasureSpec);
if
(heightMode == MeasureSpec.AT_MOST){
heightSize = mDisplayMetrics.densityDpi *
30
;
}
if
(widthMode == MeasureSpec.AT_MOST){
widthSize = mDisplayMetrics.densityDpi *
300
;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected
void
onDraw(Canvas canvas) {
int
width = getWidth();
int
height = getHeight();
//进行画上下线
paint.setStyle(Style.STROKE);
paint.setColor(mTopLineColor);
paint.setStrokeWidth(mStrokeWidth);
canvas.drawLine(
0
,
0
, width,
0
, paint);
//画下横线
paint.setColor(mBottomLineColor);
canvas.drawLine(
0
, height, width, height, paint);
paint.setStyle(Style.FILL);
paint.setTextSize(mWeekSize * mDisplayMetrics.scaledDensity);
int
columnWidth = width /
7
;
for
(
int
i=
0
;i < weekString.length;i++){
String text = weekString[i];
int
fontWidth = (
int
) paint.measureText(text);
int
startX = columnWidth * i + (columnWidth - fontWidth)/
2
;
int
startY = (
int
) (height/
2
- (paint.ascent() + paint.descent())/
2
);
if
(text.indexOf(
"日"
) > -
1
|| text.indexOf(
"六"
) > -
1
){
paint.setColor(mWeekendColor);
}
else
{
paint.setColor(mWeedayColor);
}
canvas.drawText(text, startX, startY, paint);
}
}
/**
* 设置顶线的颜色
* @param mTopLineColor
*/
public
void
setmTopLineColor(
int
mTopLineColor) {
this
.mTopLineColor = mTopLineColor;
}
/**
* 设置底线的颜色
* @param mBottomLineColor
*/
public
void
setmBottomLineColor(
int
mBottomLineColor) {
this
.mBottomLineColor = mBottomLineColor;
}
/**
* 设置周一-五的颜色
* @return
*/
public
void
setmWeedayColor(
int
mWeedayColor) {
this
.mWeedayColor = mWeedayColor;
}
/**
* 设置周六、周日的颜色
* @param mWeekendColor
*/
public
void
setmWeekendColor(
int
mWeekendColor) {
this
.mWeekendColor = mWeekendColor;
}
/**
* 设置边线的宽度
* @param mStrokeWidth
*/
public
void
setmStrokeWidth(
int
mStrokeWidth) {
this
.mStrokeWidth = mStrokeWidth;
}
/**
* 设置字体的大小
* @param mWeekSize
*/
public
void
setmWeekSize(
int
mWeekSize) {
this
.mWeekSize = mWeekSize;
}
/**
* 设置星期的形式
* @param weekString
* 默认值 "日","一","二","三","四","五","六"
*/
public
void
setWeekString(String[] weekString) {
this
.weekString = weekString;
}
}
(1)、首先我们定义了我们需要的成员变量,比如上下线条的颜色、宽度、字体的大小、周期的表现形式。这些都是为了灵活定制而需要的。方便使用。
(2)、现在来看看onMeasure方法,我们知道在自定义view中,我们遇到wrap_content属性,这是view的大小可能就不是我们想要的了,所以我们在onMeasure方法中,指定此条件下的大小,即默认大小为300*30。
(3)、onDraw方法,我们在onDraw方法中进行我们需要内容的绘制。我们使用drawLine方法,进行上下横线的绘制,然后int columnWidth = width / 7;计算每列的宽度,为什么计算宽度呢?因为我们要将”日”,”一”,”二”,”三”,”四”,”五”,”六”这七个字放在对应格子的居中位置。通过drawText方法进行绘制文字,我们需要指定绘制文字的起始位置,为了达到居中的位置,我们需要进行计算。
int
startX = columnWidth * i + (columnWidth - fontWidth)/
2
;
int
startY = (
int
) (height/
2
- (paint.ascent() + paint.descent())/
2
);
此处不是很了解的,可以参照下爱哥的文章。后面就是一些设置属性,没什么讲头。
至此很简单的实现了我们的week的自定义view。下面我们来分析下日期的实现。
实现日期Date的自定义View
类似WeekView的实现,我们在DateView中的难点也是如何放置这些日期date。先上源码,然后我们在具体分析:
public
class
MonthDateView
extends
View {
private
static
final
int
NUM_COLUMNS =
7
;
private
static
final
int
NUM_ROWS =
6
;
private
Paint mPaint;
private
int
mDayColor = Color.parseColor(
"#000000"
);
private
int
mSelectDayColor = Color.parseColor(
"#ffffff"
);
private
int
mSelectBGColor = Color.parseColor(
"#1FC2F3"
);
private
int
mCurrentColor = Color.parseColor(
"#ff0000"
);
private
int
mCurrYear,mCurrMonth,mCurrDay;
private
int
mSelYear,mSelMonth,mSelDay;
private
int
mColumnSize,mRowSize;
private
DisplayMetrics mDisplayMetrics;
private
int
mDaySize =
18
;
private
TextView tv_date,tv_week;
private
int
weekRow;
private
int
[][] daysString;
private
int
mCircleRadius =
6
;
private
DateClick dateClick;
private
int
mCircleColor = Color.parseColor(
"#ff0000"
);
private
List<Integer> daysHasThingList;
public
MonthDateView(Context context, AttributeSet attrs) {
super
(context, attrs);
mDisplayMetrics = getResources().getDisplayMetrics();
Calendar calendar = Calendar.getInstance();
mPaint =
new
Paint();
mCurrYear = calendar.get(Calendar.YEAR);
mCurrMonth = calendar.get(Calendar.MONTH);
mCurrDay = calendar.get(Calendar.DATE);
setSelectYearMonth(mCurrYear,mCurrMonth,mCurrDay);
}
@Override
protected
void
onMeasure(
int
widthMeasureSpec,
int
heightMeasureSpec) {
int
widthSize = MeasureSpec.getSize(widthMeasureSpec);
int
widthMode = MeasureSpec.getMode(widthMeasureSpec);
int
heightSize = MeasureSpec.getSize(heightMeasureSpec);
int
heightMode = MeasureSpec.getMode(heightMeasureSpec);
if
(heightMode == MeasureSpec.AT_MOST){
heightSize = mDisplayMetrics.densityDpi *
200
;
}
if
(widthMode == MeasureSpec.AT_MOST){
widthSize = mDisplayMetrics.densityDpi *
300
;
}
setMeasuredDimension(widthSize, heightSize);
}
@Override
protected
void
onDraw(Canvas canvas) {
initSize();
daysString =
new
int
[
6
][
7
];
mPaint.setTextSize(mDaySize*mDisplayMetrics.scaledDensity);
String dayString;
int
mMonthDays = DateUtils.getMonthDays(mSelYear, mSelMonth);
int
weekNumber = DateUtils.getFirstDayWeek(mSelYear, mSelMonth);
Log.d(
"DateView"
,
"DateView:"
+ mSelMonth+
"月1号周"
+ weekNumber);
for
(
int
day =
0
;day < mMonthDays;day++){
dayString = (day +
1
) +
""
;
int
column = (day+weekNumber -
1
) %
7
;
int
row = (day+weekNumber -
1
) /
7
;
daysString[row][column]=day +
1
;
int
startX = (
int
) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayString))/
2
);
int
startY = (
int
) (mRowSize * row + mRowSize/
2
- (mPaint.ascent() + mPaint.descent())/
2
);
if
(dayString.equals(mSelDay+
""
)){
//绘制背景色矩形
int
startRecX = mColumnSize * column;
int
startRecY = mRowSize * row;
int
endRecX = startRecX + mColumnSize;
int
endRecY = startRecY + mRowSize;
mPaint.setColor(mSelectBGColor);
canvas.drawRect(startRecX, startRecY, endRecX, endRecY, mPaint);
//记录第几行,即第几周
weekRow = row +
1
;
}
//绘制事务圆形标志
drawCircle(row,column,day +
1
,canvas);
if
(dayString.equals(mSelDay+
""
)){
mPaint.setColor(mSelectDayColor);
}
else
if
(dayString.equals(mCurrDay+
""
) && mCurrDay != mSelDay && mCurrMonth == mSelMonth){
//正常月,选中其他日期,则今日为红色
mPaint.setColor(mCurrentColor);
}
else
{
mPaint.setColor(mDayColor);
}
canvas.drawText(dayString, startX, startY, mPaint);
if
(tv_date !=
null
){
tv_date.setText(mSelYear +
"年"
+ (mSelMonth +
1
) +
"月"
);
}
if
(tv_week !=
null
){
tv_week.setText(
"第"
+ weekRow +
"周"
);
}
}
}
private
void
drawCircle(
int
row,
int
column,
int
day,Canvas canvas){
if
(daysHasThingList !=
null
&& daysHasThingList.size() >
0
){
if
(!daysHasThingList.contains(day))
return
;
mPaint.setColor(mCircleColor);
float
circleX = (
float
) (mColumnSize * column + mColumnSize*
0.8
);
float
circley = (
float
) (mRowSize * row + mRowSize*
0.2
);
canvas.drawCircle(circleX, circley, mCircleRadius, mPaint);
}
}
@Override
public
boolean
performClick() {
return
super
.performClick();
}
private
int
downX =
0
,downY =
0
;
@Override
public
boolean
onTouchEvent(MotionEvent event) {
int
eventCode= event.getAction();
switch
(eventCode){
case
MotionEvent.ACTION_DOWN:
downX = (
int
) event.getX();
downY = (
int
) event.getY();
break
;
case
MotionEvent.ACTION_MOVE:
break
;
case
MotionEvent.ACTION_UP:
int
upX = (
int
) event.getX();
int
upY = (
int
) event.getY();
if
(Math.abs(upX-downX) <
10
&& Math.abs(upY - downY) <
10
){
//点击事件
performClick();
doClickAction((upX + downX)/
2
,(upY + downY)/
2
);
}
break
;
}
return
true
;
}
/**
* 初始化列宽行高
*/
private
void
initSize(){
mColumnSize = getWidth() / NUM_COLUMNS;
mRowSize = getHeight() / NUM_ROWS;
}
/**
* 设置年月
* @param year
* @param month
*/
private
void
setSelectYearMonth(
int
year,
int
month,
int
day){
mSelYear = year;
mSelMonth = month;
mSelDay = day;
}
/**
* 执行点击事件
* @param x
* @param y
*/
private
void
doClickAction(
int
x,
int
y){
int
row = y / mRowSize;
int
column = x / mColumnSize;
setSelectYearMonth(mSelYear,mSelMonth,daysString[row][column]);
invalidate();
//执行activity发送过来的点击处理事件
if
(dateClick !=
null
){
dateClick.onClickOnDate();
}
}
/**
* 左点击,日历向后翻页
*/
public
void
onLeftClick(){
int
year = mSelYear;
int
month = mSelMonth;
int
day = mSelDay;
if
(month ==
0
){
//若果是1月份,则变成12月份
year = mSelYear-
1
;
month =
11
;
}
else
if
(DateUtils.getMonthDays(year, month) == day){
//如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
month = month-
1
;
day = DateUtils.getMonthDays(year, month);
}
else
{
month = month-
1
;
}
setSelectYearMonth(year,month,day);
invalidate();
}
/**
* 右点击,日历向前翻页
*/
public
void
onRightClick(){
int
year = mSelYear;
int
month = mSelMonth;
int
day = mSelDay;
if
(month ==
11
){
//若果是12月份,则变成1月份
year = mSelYear+
1
;
month =
0
;
}
else
if
(DateUtils.getMonthDays(year, month) == day){
//如果当前日期为该月最后一点,当向前推的时候,就需要改变选中的日期
month = month +
1
;
day = DateUtils.getMonthDays(year, month);
}
else
{
month = month +
1
;
}
setSelectYearMonth(year,month,day);
invalidate();
}
/**
* 获取选择的年份
* @return
*/
public
int
getmSelYear() {
return
mSelYear;
}
/**
* 获取选择的月份
* @return
*/
public
int
getmSelMonth() {
return
mSelMonth;
}
/**
* 获取选择的日期
* @param mSelDay
*/
public
int
getmSelDay() {
return
this
.mSelDay;
}
/**
* 普通日期的字体颜色,默认黑色
* @param mDayColor
*/
public
void
setmDayColor(
int
mDayColor) {
this
.mDayColor = mDayColor;
}
/**
* 选择日期的颜色,默认为白色
* @param mSelectDayColor
*/
public
void
setmSelectDayColor(
int
mSelectDayColor) {
this
.mSelectDayColor = mSelectDayColor;
}
/**
* 选中日期的背景颜色,默认蓝色
* @param mSelectBGColor
*/
public
void
setmSelectBGColor(
int
mSelectBGColor) {
this
.mSelectBGColor = mSelectBGColor;
}
/**
* 当前日期不是选中的颜色,默认红色
* @param mCurrentColor
*/
public
void
setmCurrentColor(
int
mCurrentColor) {
this
.mCurrentColor = mCurrentColor;
}
/**
* 日期的大小,默认18sp
* @param mDaySize
*/
public
void
setmDaySize(
int
mDaySize) {
this
.mDaySize = mDaySize;
}
/**
* 设置显示当前日期的控件
* @param tv_date
* 显示日期
* @param tv_week
* 显示周
*/
public
void
setTextView(TextView tv_date,TextView tv_week){
this
.tv_date = tv_date;
this
.tv_week = tv_week;
invalidate();
}
/**
* 设置事务天数
* @param daysHasThingList
*/
public
void
setDaysHasThingList(List<Integer> daysHasThingList) {
this
.daysHasThingList = daysHasThingList;
}
/***
* 设置圆圈的半径,默认为6
* @param mCircleRadius
*/
public
void
setmCircleRadius(
int
mCircleRadius) {
this
.mCircleRadius = mCircleRadius;
}
/**
* 设置圆圈的半径
* @param mCircleColor
*/
public
void
setmCircleColor(
int
mCircleColor) {
this
.mCircleColor = mCircleColor;
}
/**
* 设置日期的点击回调事件
* @author shiwei.deng
*
*/
public
interface
DateClick{
public
void
onClickOnDate();
}
/**
* 设置日期点击事件
* @param dateClick
*/
public
void
setDateClick(DateClick dateClick) {
this
.dateClick = dateClick;
}
/**
* 跳转至今天
*/
public
void
setTodayToView(){
setSelectYearMonth(mCurrYear,mCurrMonth,mCurrDay);
invalidate();
}
}
(1)、首先我们还是定义了一些我们需要的成员变量,比如,字体的颜色、圆圈的颜色、选中的背景色、同样我们需要记录下我们正确的年月日、以及选中的年月日来进行区分,主要就这么多。
(2)、然后进行重写onMeasure方法,类似于WeekView,不做过多解释,差不多。
(3)、在onDraw方法中进行绘制,绘制的原理,我们根据Calendar获取当前月份的天数,以及第一天是礼拜几,只有计算出礼拜几,我们才知道我们的日历从哪列开始,这样我们就可以计算出每次绘制日期的位置:
int
column = (day+weekNumber -
1
) %
7
;
int
row = (day+weekNumber -
1
) /
7
;
daysString[row][column]=day +
1
;
int
startX = (
int
) (mColumnSize * column + (mColumnSize - mPaint.measureText(dayString))/
2
);
int
startY = (
int
) (mRowSize * row + mRowSize/
2
- (mPaint.ascent() + mPaint.descent())/
2
);
一个礼拜有七天,我们根据日期号和起始计算出日期的对应行列,然后在乘以行列宽,就可以计算出每个日期号的其实位置。这样我们就可以通过drawText进行日期的绘制。我们有一个成员变量记录选中的日期号,然后进行绘制选中的背景色,如下代码:
if
(dayString.equals(mSelDay+
""
)){
//绘制背景色矩形
int
startRecX = mColumnSize * column;
int
startRecY = mRowSize * row;
int
endRecX = startRecX + mColumnSize;
int
endRecY = startRecY + mRowSize;
mPaint.setColor(mSelectBGColor);
canvas.drawRect(startRecX, startRecY, endRecX, endRecY, mPaint);
//记录第几行,即第几周
weekRow = row +
1
;
}
(4)、我们还有一个需求,就是绘制事务标志,我们定义了List daysHasThingList的list对象,这个对象我们用来’装’事务的日期号。然后我们在onDraw方法中判断日期是否包含在这个list中,然后绘制对应的圆圈。
private
void
drawCircle(
int
row,
int
column,
int
day,Canvas canvas){
if
(daysHasThingList !=
null
&& daysHasThingList.size() >
0
){
if
(!daysHasThingList.contains(day))
return
;
mPaint.setColor(mCircleColor);
float
circleX = (
float
) (mColumnSize * column + mColumnSize*
0.8
);
float
circley = (
float
) (mRowSize * row + mRowSize*
0.2
);
canvas.drawCircle(circleX, circley, mCircleRadius, mPaint);
}
}
}
(5)、至此,日期的绘制和事务都完成了,但是还没有点击事件进行切换日期的选择,这怎么办呢?所以我们需要重写View的onTouchEvent方法,然后判断点击事件,根据获取的X、Y值,计算出我们选择行列,然后我们在根据行列在daysString中获取我们选中的日期,设置选中日期,然后刷新视图。
public
boolean
onTouchEvent(MotionEvent event) {
int
eventCode= event.getAction();
switch
(eventCode){
case
MotionEvent.ACTION_DOWN:
downX = (
int
) event.getX();
downY = (
int
) event.getY();
break
;
case
MotionEvent.ACTION_MOVE:
break
;
case
MotionEvent.ACTION_UP:
int
upX = (
int
) event.getX();
int
upY = (
int
) event.getY();
if
(Math.abs(upX-downX) <
10
&& Math.abs(upY - downY) <
10
){
//点击事件
performClick();
doClickAction((upX + downX)/
2
,(upY + downY)/
2
);
}
break
;
}
return
true
;
}
(5)、有的需求是进行点击事情的处理,这时我们只需要写一个简单的回调,然后在activity中进行处理即可。
private
void
doClickAction(
int
x,
int
y){
int
row = y / mRowSize;
int
column = x / mColumnSize;
setSelectYearMonth(mSelYear,mSelMonth,daysString[row][column]);
invalidate();
//执行activity发送过来的点击处理事件
if
(dateClick !=
null
){
dateClick.onClickOnDate();
}
}
/**
* 设置日期的点击回调事件
* @author shiwei.deng
*
*/
public
interface
DateClick{
public
void
onClickOnDate();
}
/**
* 设置日期点击事件
* @param dateClick
*/
public
void
setDateClick(DateClick dateClick) {
this
.dateClick = dateClick;
}
(6)主要的处理已经完成,剩下的需要我们获取日期的显示以及显示第几周、点击【今】返回到今天,这些处理的逻辑就是设置选中的日期,然后刷新视图。代码就不贴了,上面的源码注释的挺详细的。
最后就是我们使用自定义View进行显示。如:
<?
xml
version
=
"1.0"
encoding
=
"utf-8"
?>
android:layout_width
=
"fill_parent"
android:layout_height
=
"fill_parent"
android:layout_centerInParent
=
"true"
android:orientation
=
"vertical"
>
<!-- 日历时间选择栏 -->
<
RelativeLayout
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:gravity
=
"center_vertical"
android:background
=
"#ffffff"
android:layout_marginLeft
=
"10dp"
android:layout_marginRight
=
"10dp"
android:paddingTop
=
"3dp"
>
<
ImageView
android:id
=
"@+id/iv_left"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_alignParentLeft
=
"true"
android:contentDescription
=
"@null"
android:background
=
"@drawable/left_arrow"
/>
<
ImageView
android:id
=
"@+id/iv_right"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:layout_alignParentRight
=
"true"
android:contentDescription
=
"@null"
android:background
=
"@drawable/right_arrow"
/>
<
LinearLayout
android:id
=
"@+id/date_operator_ll"
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:layout_gravity
=
"center_vertical"
android:gravity
=
"center"
android:layout_centerInParent
=
"true"
android:orientation
=
"horizontal"
>
<
TextView
android:id
=
"@+id/tv_today"
android:layout_width
=
"25dp"
android:layout_height
=
"25dp"
android:layout_marginRight
=
"5dp"
android:text
=
"今"
android:gravity
=
"center"
android:background
=
"#FFD700"
android:textColor
=
"#ffffff"
android:textSize
=
"17sp"
/>
<
TextView
android:id
=
"@+id/date_text"
style
=
"@style/myschedule_current_month_tv"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:gravity
=
"center_horizontal"
android:textColor
=
"#93C73C"
android:textSize
=
"20sp"
android:text
=
""
/>
<
TextView
android:id
=
"@+id/week_text"
style
=
"@style/myschedule_current_month_tv"
android:layout_width
=
"wrap_content"
android:layout_height
=
"wrap_content"
android:gravity
=
"center_horizontal"
android:layout_marginLeft
=
"10dp"
android:textColor
=
"#93C73C"
android:textSize
=
"20sp"
android:text
=
""
/>
</
LinearLayout
>
</
RelativeLayout
>
<
LinearLayout
android:layout_width
=
"fill_parent"
android:layout_height
=
"wrap_content"
android:layout_marginLeft
=
"10dp"
android:layout_marginRight
=
"10dp"
android:background
=
"#ffffff"
android:orientation
=
"vertical"
>
<
com.dsw.datepicker.WeekDayView
android:layout_width
=
"match_parent"
android:layout_height
=
"30dp"
/>
<
com.dsw.datepicker.MonthDateView
android:id
=
"@+id/monthDateView"
android:layout_width
=
"fill_parent"
android:layout_height
=
"200dp"
/>
</
LinearLayout
>
</
LinearLayout
>
这样我们在activity中就能使用了:
public
class
MainActivity
extends
FragmentActivity {
private
ImageView iv_left;
private
ImageView iv_right;
private
TextView tv_date;
private
TextView tv_week;
private
TextView tv_today;
private
MonthDateView monthDateView;
@Override
protected
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
List<Integer> list =
new
ArrayList<Integer>();
list.add(
10
);
list.add(
12
);
list.add(
15
);
list.add(
16
);
setContentView(R.layout.activity_date);
iv_left = (ImageView) findViewById(R.id.iv_left);
iv_right = (ImageView) findViewById(R.id.iv_right);
monthDateView = (MonthDateView) findViewById(R.id.monthDateView);
tv_date = (TextView) findViewById(R.id.date_text);
tv_week =(TextView) findViewById(R.id.week_text);
tv_today = (TextView) findViewById(R.id.tv_today);
monthDateView.setTextView(tv_date,tv_week);
monthDateView.setDaysHasThingList(list);
monthDateView.setDateClick(
new
DateClick() {
@Override
public
void
onClickOnDate() {
Toast.makeText(getApplication(),
"点击了:"
+ monthDateView.getmSelDay(), Toast.LENGTH_SHORT).show();
}
});
setOnlistener();
}
private
void
setOnlistener(){
iv_left.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
monthDateView.onLeftClick();
}
});
iv_right.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
monthDateView.onRightClick();
}
});
tv_today.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
monthDateView.setTodayToView();
}
});
}
}
至此,全部的内容已经完成,一个简单的自定义view的使用,在实际项目中使用颇多,当然这个例子还有很多完善的地方,比如在onTouchEvent中进行滑动的监视,通过滑动来进行日期的修改,这些有兴趣的同学可以试试。
欢迎大家留言交流。
作者:mr_dsw 欢迎转载,与人分享是进步的源泉!
转载请保留地址:http://blog.csdn.net/mr_dsw
转载请注明:Android开发中文站 » Android自定义控件之日历控件
Recommend
-
49
JOJO是我看过脑洞最大的动漫(没有之一),每季必追 最近打算做简历,想自定义个能力分析图,首先就想到这里: 废话不多说,走起,噢啦,噢啦,噢啦,噢啦... 一、静态图的绘制 1.绘制外圈 为了减少变量值,让尺寸具有很好的联动性(等比扩缩),小黑条的长
-
40
零、前言 总算想到一个神级的自定义控件了 前方高能预警,萌新自带零食饮料 本文的前置知识你需简单了解:Android绘制函数图象及正弦函数的介绍 没错,今天玩自定义控件,和函数、录音有什么关系?用脚趾头稍微想一下就知道了... 废话不多说,看待仿效果:
-
17
自定义控件可以说是android里的一个门槛,对很多android开发者来说可能都会认为比较难,当然这也是成为一个高手的必经之路,因此我准备在定义控件上多下些功夫,多花点时间研究,多写博客,如果想一起学习自定义控件,欢迎大家关注,如有疑问欢迎留言,如有谬误...
-
14
Android开发之自定义控件(二)---onLayout详解_dmk877的专栏-CSDN博客_android onlayout 转载注明出处:http://blog.csdn.net/dmk877/article/details/49632959 话说一个乞...
-
12
话说一个有十年的编程经验的老汉,决定改行书法,在一个热火炎炎的中午,老汉拿着毛笔,在一张白纸上写了个“Hello World!”,从此开启了他的书法旅程。那么问题来了请问自定义一个控件需要怎样的流程?我们经常说自定义控件,那么究竟怎样去自定义一...
-
10
Android 自定义控件 优雅实现元素间的分割线 (支持3.0以下) 转...
-
6
转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/44098729,本文出自: 【张鸿洋的博客】 本篇博客...
-
11
Android 自定义控件 轻松实现360软件详情页_Hongyang-CSDN博客_android 自定义控件 转载请标明出处: http...
-
6
我的技术公众号 欢迎关注我的公众号,每天都有技术文章推送。
-
6
#夏日挑战赛# HarmonyOs- ArkUI(JS)自定义组件之日历控件 原创 精华 作者:曹琪娟 本文正在参加星光计划3.0–夏日挑战赛
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK