Android自定义View课程表,自定义View(一)之课程表

自定义View(一)之课程表

课程表大家可是从小用到大了,想不想搞个手机版的玩玩呢,那就跟我来吧,废话不说,先上图

0818b9ca8b590ca3270a3433284dd417.png

开始写代码之前你还要注意几个问题

1. 你需要一个算法通过当前时间算出这一周的日期,用于填充时间栏

2. 你需要设计一个数据结构用来存储和传递数据(如果你真的准备拿出来用的话)

3. 将数据写入课程表中时候要计算字符串的长度,如果长度大于了课表单元的宽度那就要写到下一行去

日期算法

private List dateToWeek(Date mDate)

{

int b = mDate.getDay();

Date fDate;

List list = new ArrayList();

Long fTime = mDate.getTime() - b * 24 * 3600000;

for (int a = 0; a < 8; a++)

{

fDate = new Date();

fDate.setTime(fTime + (a * 24 * 3600000));

Calendar calendar = new GregorianCalendar();

calendar.setTime(fDate);

calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动

fDate = calendar.getTime(); // 这个时间就是日期往后推一天的结果

list.add(a, fDate);

}

return list;

}

写入数据的方法

这里使用了paint的mearsureText方法来计算字符串的长度与我们的课表的一个单元的宽进行比较

private void drawText(Canvas canvas, String s, float x, float y, float width, Paint paint)

{

StringBuffer buffer = new StringBuffer();

char c;

for (int i = 0; i < s.length(); i++)

{

//一行写不下了,就输出

if(paint.measureText(buffer.toString())+30 > width)

{

canvas.drawText(buffer.toString(), x, y, paint);

y+=30;

buffer.setLength(0);

}

//一行能写下,就再加字符

c = s.charAt(i);

buffer.append(c);

}

canvas.drawText(buffer.toString(), x, y, paint);

}

在构造方法中初始化一些数据

public TimeTableView(Context context, AttributeSet attrs)

{

super(context, attrs);

imagePaint = new Paint();

//画矩形标题的笔

titlePaint = new Paint();

titlePaint.setColor(Color.argb(127, 164, 159, 155));

//画分割线的笔

linePaint = new Paint();

linePaint.setColor(Color.argb(127, 95, 87, 84));

//得到当前一周的日期

dates = dateToWeek(new Date());

}

onMearsure

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

{

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

//测量view的宽高

winWidth = measureWidth(widthMeasureSpec);

winHeight = measureHeight(heightMeasureSpec);

setMeasuredDimension(winWidth, winHeight);

widthSize = (winWidth - NUM_SIZE) / 7;

heightSize = winHeight / 12;

Log.i("main", "winWidth:"+winWidth+", winHeight:"+winHeight);

//字体大小

textSize = winWidth/36;

//用于画文字的笔

textPaint = new Paint();

textPaint.setColor(Color.argb(255, 255, 255, 255));

textPaint.setTextSize(textSize);

textPaint.setTextAlign(Paint.Align.CENTER);

}

测量方法。(高的测量方法与宽几乎一致,我就不重复了)

private int measureWidth(int measureSpc)

{

int result = 0;

int specMode = MeasureSpec.getMode(measureSpc);

int specSize = MeasureSpec.getSize(measureSpc);

//如果给的是精确值(具体数值或者match_parent)

if (specMode == MeasureSpec.EXACTLY)

{

result = specSize;

}

else

{

//不是精确值的话就先给一个初始值

result = 300;

//如果是wrap_content的话,就让他为不超过最大值的一个默认值

if (specMode == MeasureSpec.AT_MOST)

{

result = Math.min(result, specSize);

}

}

return result;

}

onDraw

@Override

protected void onDraw(Canvas canvas)

{

Paint paint = new Paint();

//背景图画

canvas.drawBitmap(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(),

R.drawable.pic9), winWidth, winHeight, true), 0, 0, new Paint());

//绘制月份

canvas.drawText(new Date().getMonth()+1 + "月", NUM_SIZE / 2, heightSize - 60, textPaint);

//初始化日期

for (int i = 0; i < 7; i++)

{

//画首行格子

RectF rectF = new RectF((NUM_SIZE + widthSize * i),

0,

(NUM_SIZE + widthSize * (i + 1)),

heightSize);

canvas.drawRect(rectF, titlePaint);

//第一行的分割线

canvas.drawLine((NUM_SIZE + widthSize * i),

0,

(NUM_SIZE + widthSize * i),

heightSize,

linePaint);

//第一行的日期

canvas.drawText(dates.get(i).getDate() + "",

(NUM_SIZE + widthSize / 2) + widthSize * i,

heightSize / 3,

textPaint);

canvas.drawText(Translate.translateDateToChinese(i + 1),

(NUM_SIZE + widthSize / 2) + widthSize * i,

(heightSize / 3) * 2,

textPaint);

}

//初始化序号

for (int i = 0; i < 12; i++)

{

//画首列格子

RectF rectF = new RectF(0, heightSize * i, NUM_SIZE, heightSize * (i + 1));

canvas.drawRect(rectF, titlePaint);

//第一列的分割线

canvas.drawLine(0, heightSize * i, NUM_SIZE, heightSize * i, linePaint);

if (i > 0)

{

//第一列的序号

canvas.drawText(i + "", NUM_SIZE / 2, (heightSize * i) + heightSize / 2, textPaint);

}

}

//初始化具体数据

if(times != null)

{

for (int i = 0; i < times.size(); i++)

{

TimeBean bean = times.get(i);

int num = bean.getTo()-bean.getFrom();

//画圆角矩形

imagePaint.setColor(bean.getType().getColor());

RectF rectF = new RectF((bean.getWeek()-1)*widthSize+NUM_SIZE, bean.getFrom()*heightSize,

bean.getWeek()*widthSize+NUM_SIZE, (bean.getTo()+1)*heightSize);

canvas.drawRoundRect(rectF, 20, 20, imagePaint);

//写字

drawText(canvas, bean.getType().getType()+":"+bean.getRemark(),

(bean.getWeek()-1)*widthSize+widthSize/2+NUM_SIZE,

bean.getFrom()*heightSize+(num+1)*heightSize/2, widthSize, textPaint);

}

}

}

提供一个方法给外界传入数据

public void setData(List times)

{

this.times = times;

invalidate();

}

这是我的数据结构:

也没想过要拿出来用就随便写写了╮(╯▽╰)╭

public class TimeBean

{

private TimeType type;

private int week;

private int from;

private int to;

private String remark;

public TimeBean(TimeType type, int week, int from, int to, String remark)

{

this.type = type;

this.week = week;

this.from = from;

this.to = to;

this.remark = remark;

}

public TimeType getType()

{

return type;

}

public void setType(TimeType type)

{

this.type = type;

}

public String getRemark()

{

return remark;

}

public void setRemark(String remark)

{

this.remark = remark;

}

public int getWeek()

{

return week;

}

public void setWeek(int week)

{

this.week = week;

}

public int getFrom()

{

return from;

}

public void setFrom(int from)

{

this.from = from;

}

public int getTo()

{

return to;

}

public void setTo(int to)

{

this.to = to;

}

public enum TimeType

{

CLASS("上课", Color.argb(127, 255, 0, 0)), ACTIVITY("体育活动", Color.argb(127, 255, 255, 0)),

COMMUNITY("社团活动", Color.argb(127, 255, 153, 0)), SLEEP("睡觉", Color.argb(127, 0, 255, 0)),

OTHER("其他", Color.argb(127, 0, 0, 0));

private String type;

private int color;

TimeType(String type, int color)

{

this.type = type;

this.color = color;

}

public String getType()

{

return type;

}

public int getColor()

{

return color;

}

}

}

今天就到这里了 (╯▔^▔)╯

想要源码的小伙伴戳这

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值