写在前面:
最近想对一个课表界面进行重构和增加功能,第一种方法是用自定义view做的,虽然最终放弃了这种方法,转向方法二,但是方法一一些思路还是值得梳理下。
效果图如下:
自定义view如下:
public class MURP_School_Schedule_Timetable_View extends View implements
OnTouchListener, OnGestureListener {
private GestureDetector detector;//手势
private float worldX;//画笔的x位置
private float worldY;//画笔的Y位置
private int height;//屏幕的高
private int width;//屏幕的宽
private Paint LinePaint;//绘制线的画笔
private TextPaint TextDrawPaint;//绘制字的画笔
private FontMetrics fontMetrics;//获得字体的高度
float fontHeight;//文字高度
float textBaseY;//文字Y位置
private Paint RectPaint;//矩形画笔
private float DatePanelWidth = 0;//周控件的宽度
private float WeekPanelHeight = 0;//周控件的高度
private float scale = 1f;//float类型的转换参数
private int lessons = 7;//一周七天
private int weeksNumber = 0;//控制周数的参数
private int weeks = 14;//节次总数
private float LessonWidth = 0;//每个格子的宽度
private float LessonHeight = 0;//每个格子的高度
private float velocityX;//当前屏幕X的偏移量
private float velocityY;//当前屏幕Y的偏移量
private Point point;//按键事件的矩阵换算
private int widthIndex = 0;//高度的格子数
private int heightIndex = 0;//宽度的格子数
public Context context;//上下文对象用于弹框
private String[] colors = new String[] { "#DAA653", "#E394AB", "#F87389",
"#7FB4CF", "#5CAC6D", "#E394AB", "#F87389" };// 1-7不同背景框
private String[] interimStrings = new String[] { "周一", "周二", "周三", "周四",
"周五", "周六", "周日" };
private String interimString;//临时绘制字符串变量
private RectF interimRect;//临时绘制矩形变量
private float timetabletx = 0;//临时绘制X坐标
private float timetablety = 0;//临时绘制Y坐标
private String academicyear;//记录当前学年
private int type;
private ImageView buttton;// 改背景
具体绘制如下:
/**
* 绘制节次
*
* @param c
*/
private void drawDatePanel(Canvas c) {
TextDrawPaint.setColor(Color.BLACK);
for (int i = widthIndex; i < weeks; i++) {
// 绘制节次
drawTextdraw();
}
}
/**
* 绘制星期
*
* @param c
*/
private void drawWeekPanel(Canvas c) {
timetabletx = worldX * scale + DatePanelWidth;
timetablety = 0;
TextDrawPaint.setColor(Color.BLACK);
// 多周
for (int i = heightIndex / lessons; i <= weeksNumber; i++) {
// 绘制周几
for (int j = 0; j < lessons; j++) {
interimString = interimStrings[j];
drawText(c, interimString, timetabletx + j * LessonWidth
* scale, timetablety, timetabletx + (j + 1)
* LessonWidth * scale, WeekPanelHeight);
}
}
/**
* 移屏计算
*
* @param distanceX
* @param distanceY
*/
private void move(float distanceX, float distanceY) {
worldX -= distanceX / scale;
if ((worldX + weeksNumber * lessons * LessonWidth) * scale
+ DatePanelWidth < width) {
worldX = (width - DatePanelWidth) / scale - weeksNumber * lessons
* LessonWidth;
velocityX = 0;
}
if (worldX > 0) {
worldX = 0;
velocityX = 0;
}
worldY -= distanceY / scale;
if ((worldY + weeks * LessonHeight) * scale + WeekPanelHeight < height) {
worldY = (height - WeekPanelHeight) / scale - weeks * LessonHeight;
velocityY = 0;
}
if (worldY > 0) {
worldY = 0;
velocityY = 0;
}
}
/**
* 拖动事件
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
//代码省略
}
该自定义view缺点很明细,每次用户移动屏幕,都需要绘制课程数据,经过思考改造后,新的view效率更高,移步:方法二