Android自定義View實現(xiàn)課程表表格
自己閑下來時間寫的一個課表控件,使用的自定義LinearLayout,里面View都是用代碼實現(xiàn)的,最終效果如下圖,寫的可能有問題希望多多指點

創(chuàng)建一個自定義LinearLayout 控件用來裝載課程的信息和課程的周數(shù),和節(jié)數(shù)大概的布局三這樣的

根據(jù)上面的看來覺得總體布局我分了兩個 上面的星期是一個 下面的節(jié)數(shù)和格子是一個 總體使用Vertical 而單獨內(nèi)部者使用了Horizontal布局 中間使用了兩種布局線條 是這樣的
/**
* 橫的分界線
*
* @return
*/
private View getWeekTransverseLine() {
TextView mWeekline = new TextView(getContext());
mWeekline.setBackgroundColor(getResources().getColor(R.color.view_line));
mWeekline.setHeight(TimeTableLineHeight);
mWeekline.setWidth(LayoutParams.FILL_PARENT);
return mWeekline;
}
/**
* 豎向分界線
*
* @return
*/
private View getWeekVerticalLine() {
TextView mWeekline = new TextView(getContext());
mWeekline.setBackgroundColor(getResources().getColor(R.color.view_line));
mWeekline.setHeight(dip2px(TimeTableWeekNameHeight));
mWeekline.setWidth((TimeTableLineHeight));
return mWeekline;
}
下面就看其它的View
那就從上到下開始先看星期的布局
private void initView() {
mHorizontalWeekLayout = new LinearLayout(getContext());
mHorizontalWeekLayout.setOrientation(HORIZONTAL);
mVerticalWeekLaout = new LinearLayout(getContext());
mVerticalWeekLaout.setOrientation(HORIZONTAL);
//表格
for (int i = 0; i <= WEEKNUM; i++) {
switch (i) {
case 0:
//課表出的0,0格子 空白的
TextView mTime = new TextView(getContext());
mTime.setHeight(dip2px(TimeTableWeekNameHeight));
mTime.setWidth((dip2px(TimeTableNumWidth)));
mHorizontalWeekLayout.addView(mTime);
//繪制1~MAXNUM
LinearLayout mMonday = new LinearLayout(getContext());
ViewGroup.LayoutParams mm = new ViewGroup.LayoutParams(dip2px(TimeTableNumWidth), dip2px(MAXNUM * TimeTableHeight) + MAXNUM * 2);
mMonday.setLayoutParams(mm);
mMonday.setOrientation(VERTICAL);
for (int j = 1; j <= MAXNUM; j++) {
TextView mNum = new TextView(getContext());
mNum.setGravity(Gravity.CENTER);
mNum.setTextColor(getResources().getColor(R.color.text_color));
mNum.setHeight(dip2px(TimeTableHeight));
mNum.setWidth(dip2px(TimeTableNumWidth));
mNum.setTextSize(14);
mNum.setText(j + "");
mMonday.addView(mNum);
mMonday.addView(getWeekTransverseLine());
}
mVerticalWeekLaout.addView(mMonday);
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 設(shè)置顯示星期一 到星期天
LinearLayout mHoriView = new LinearLayout(getContext());
mHoriView.setOrientation(VERTICAL);
TextView mWeekName = new TextView(getContext());
mWeekName.setTextColor(getResources().getColor(R.color.text_color));
mWeekName.setWidth(((getViewWidth() - dip2px(TimeTableNumWidth))) / WEEKNUM);
mWeekName.setHeight(dip2px(TimeTableWeekNameHeight));
mWeekName.setGravity(Gravity.CENTER);
mWeekName.setTextSize(16);
mWeekName.setText(weekname[i - 1]);
mHoriView.addView(mWeekName);
mHorizontalWeekLayout.addView(mHoriView);
List<TimeTableModel> mListMon = new ArrayList<>();
//遍歷出星期1~7的課表
for (TimeTableModel timeTableModel : mListTimeTable) {
if (timeTableModel.getWeek() == i) {
mListMon.add(timeTableModel);
}
}
//添加
LinearLayout mLayout = getTimeTableView(mListMon, i);
mLayout.setOrientation(VERTICAL);
ViewGroup.LayoutParams linearParams = new ViewGroup.LayoutParams((getViewWidth() - dip2px(20)) / WEEKNUM, LayoutParams.FILL_PARENT);
mLayout.setLayoutParams(linearParams);
mLayout.setWeightSum(1);
mVerticalWeekLaout.addView(mLayout);
break;
default:
break;
}
TextView l = new TextView(getContext());
l.setHeight(dip2px(TimeTableHeight * MAXNUM) + MAXNUM * 2);
l.setWidth(2);
l.setBackgroundColor(getResources().getColor(R.color.view_line));
mVerticalWeekLaout.addView(l);
mHorizontalWeekLayout.addView(getWeekVerticalLine());
}
addView(mHorizontalWeekLayout);
addView(getWeekTransverseLine());
addView(mVerticalWeekLaout);
addView(getWeekTransverseLine());
}
TimeTableModel
package com.shallcheek.timetale;
public class TimeTableModel {
private int id;
private int startnum;
private int endnum;
private int week;
private String starttime="";
private String endtime="";
private String name="";
private String teacher="";
private String classroom="";
private String weeknum="";
@Override
public String toString() {
return "TimeTableModel [id=" + id + ", startnum=" + startnum
+ ", endnum=" + endnum + ", week=" + week + ", starttime="
+ starttime + ", endtime=" + endtime + ", name=" + name
+ ", teacher=" + teacher + ", classroom=" + classroom
+ ", weeknum=" + weeknum + "]";
}
public int getId() {
return id;
}
public int getStartnum() {
return startnum;
}
public int getEndnum() {
return endnum;
}
public int getWeek() {
return week;
}
public String getStarttime() {
return starttime;
}
public String getEndtime() {
return endtime;
}
public String getName() {
return name;
}
public String getTeacher() {
return teacher;
}
public String getClassroom() {
return classroom;
}
public String getWeeknum() {
return weeknum;
}
public void setId(int id) {
this.id = id;
}
public void setStartnum(int startnum) {
this.startnum = startnum;
}
public void setEndnum(int endnum) {
this.endnum = endnum;
}
public void setWeek(int week) {
this.week = week;
}
public void setStarttime(String starttime) {
this.starttime = starttime;
}
public void setEndtime(String endtime) {
this.endtime = endtime;
}
public void setName(String name) {
this.name = name;
}
public void setTeacher(String teacher) {
this.teacher = teacher;
}
public void setClassroom(String classroom) {
this.classroom = classroom;
}
public void setWeeknum(String weeknum) {
this.weeknum = weeknum;
}
public TimeTableModel() {
// TODO Auto-generated constructor stub
}
public TimeTableModel(int id, int startnum, int endnum, int week,
String starttime, String endtime, String name, String teacher,
String classroom, String weeknum) {
super();
this.id = id;
this.startnum = startnum;
this.endnum = endnum;
this.week = week;
this.starttime = starttime;
this.endtime = endtime;
this.name = name;
this.teacher = teacher;
this.classroom = classroom;
this.weeknum = weeknum;
}
}
TimeTableView
package com.shallcheek.timetale;
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
/**
* 課表顯示View
*
* @author shallcheek
*/
public class TimeTableView extends LinearLayout {
/**
* 配色數(shù)組
*/
public static int colors[] = {R.drawable.select_label_san,
R.drawable.select_label_er, R.drawable.select_label_si,
R.drawable.select_label_wu, R.drawable.select_label_liu,
R.drawable.select_label_qi, R.drawable.select_label_ba,
R.drawable.select_label_jiu, R.drawable.select_label_sss,
R.drawable.select_label_se, R.drawable.select_label_yiw,
R.drawable.select_label_sy, R.drawable.select_label_yiwu,
R.drawable.select_label_yi, R.drawable.select_label_wuw};
private final static int START = 0;
//最大節(jié)數(shù)
public final static int MAXNUM = 12;
//顯示到星期幾
public final static int WEEKNUM = 7;
//單個View高度
private final static int TimeTableHeight = 50;
//線的高度
private final static int TimeTableLineHeight = 2;
private final static int TimeTableNumWidth = 20;
private final static int TimeTableWeekNameHeight = 30;
private LinearLayout mHorizontalWeekLayout;//第一行的星期顯示
private LinearLayout mVerticalWeekLaout;//課程格子
private String[] weekname = {"一", "二", "三", "四", "五", "六", "七"};
public static String[] colorStr = new String[20];
int colornum = 0;
//數(shù)據(jù)源
private List<TimeTableModel> mListTimeTable = new ArrayList<TimeTableModel>();
public TimeTableView(Context context) {
super(context);
}
public TimeTableView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
/**
* 橫的分界線
*
* @return
*/
private View getWeekTransverseLine() {
TextView mWeekline = new TextView(getContext());
mWeekline.setBackgroundColor(getResources().getColor(R.color.view_line));
mWeekline.setHeight(TimeTableLineHeight);
mWeekline.setWidth(LayoutParams.FILL_PARENT);
return mWeekline;
}
/**
* 豎向分界線
*
* @return
*/
private View getWeekVerticalLine() {
TextView mWeekline = new TextView(getContext());
mWeekline.setBackgroundColor(getResources().getColor(R.color.view_line));
mWeekline.setHeight(dip2px(TimeTableWeekNameHeight));
mWeekline.setWidth((TimeTableLineHeight));
return mWeekline;
}
private void initView() {
mHorizontalWeekLayout = new LinearLayout(getContext());
mHorizontalWeekLayout.setOrientation(HORIZONTAL);
mVerticalWeekLaout = new LinearLayout(getContext());
mVerticalWeekLaout.setOrientation(HORIZONTAL);
//表格
for (int i = 0; i <= WEEKNUM; i++) {
switch (i) {
case 0:
//課表出的0,0格子 空白的
TextView mTime = new TextView(getContext());
mTime.setHeight(dip2px(TimeTableWeekNameHeight));
mTime.setWidth((dip2px(TimeTableNumWidth)));
mHorizontalWeekLayout.addView(mTime);
//繪制1~MAXNUM
LinearLayout mMonday = new LinearLayout(getContext());
ViewGroup.LayoutParams mm = new ViewGroup.LayoutParams(dip2px(TimeTableNumWidth), dip2px(MAXNUM * TimeTableHeight) + MAXNUM * 2);
mMonday.setLayoutParams(mm);
mMonday.setOrientation(VERTICAL);
for (int j = 1; j <= MAXNUM; j++) {
TextView mNum = new TextView(getContext());
mNum.setGravity(Gravity.CENTER);
mNum.setTextColor(getResources().getColor(R.color.text_color));
mNum.setHeight(dip2px(TimeTableHeight));
mNum.setWidth(dip2px(TimeTableNumWidth));
mNum.setTextSize(14);
mNum.setText(j + "");
mMonday.addView(mNum);
mMonday.addView(getWeekTransverseLine());
}
mVerticalWeekLaout.addView(mMonday);
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
// 設(shè)置顯示星期一 到星期天
LinearLayout mHoriView = new LinearLayout(getContext());
mHoriView.setOrientation(VERTICAL);
TextView mWeekName = new TextView(getContext());
mWeekName.setTextColor(getResources().getColor(R.color.text_color));
mWeekName.setWidth(((getViewWidth() - dip2px(TimeTableNumWidth))) / WEEKNUM);
mWeekName.setHeight(dip2px(TimeTableWeekNameHeight));
mWeekName.setGravity(Gravity.CENTER);
mWeekName.setTextSize(16);
mWeekName.setText(weekname[i - 1]);
mHoriView.addView(mWeekName);
mHorizontalWeekLayout.addView(mHoriView);
List<TimeTableModel> mListMon = new ArrayList<>();
//遍歷出星期1~7的課表
for (TimeTableModel timeTableModel : mListTimeTable) {
if (timeTableModel.getWeek() == i) {
mListMon.add(timeTableModel);
}
}
//添加
LinearLayout mLayout = getTimeTableView(mListMon, i);
mLayout.setOrientation(VERTICAL);
ViewGroup.LayoutParams linearParams = new ViewGroup.LayoutParams((getViewWidth() - dip2px(20)) / WEEKNUM, LayoutParams.FILL_PARENT);
mLayout.setLayoutParams(linearParams);
mLayout.setWeightSum(1);
mVerticalWeekLaout.addView(mLayout);
break;
default:
break;
}
TextView l = new TextView(getContext());
l.setHeight(dip2px(TimeTableHeight * MAXNUM) + MAXNUM * 2);
l.setWidth(2);
l.setBackgroundColor(getResources().getColor(R.color.view_line));
mVerticalWeekLaout.addView(l);
mHorizontalWeekLayout.addView(getWeekVerticalLine());
}
addView(mHorizontalWeekLayout);
addView(getWeekTransverseLine());
addView(mVerticalWeekLaout);
addView(getWeekTransverseLine());
}
private int getViewWidth() {
WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
return wm.getDefaultDisplay().getWidth();
}
private View addStartView(int startnum, final int week, final int start) {
LinearLayout mStartView = new LinearLayout(getContext());
mStartView.setOrientation(VERTICAL);
for (int i = 1; i < startnum; i++) {
TextView mTime = new TextView(getContext());
mTime.setGravity(Gravity.CENTER);
mTime.setHeight(dip2px(TimeTableHeight));
mTime.setWidth(dip2px(TimeTableHeight));
mStartView.addView(mTime);
mStartView.addView(getWeekTransverseLine());
final int num = i;
//這里可以處理空白處點擊添加課表
mTime.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), "星期" + week + "第" + (start + num) + "節(jié)", Toast.LENGTH_LONG).show();
}
});
}
return mStartView;
}
/**
* 星期一到星期天的課表
*
* @param model
* @param week
* @return
*/
private LinearLayout getTimeTableView(List<TimeTableModel> model, int week) {
LinearLayout mTimeTableView = new LinearLayout(getContext());
mTimeTableView.setOrientation(VERTICAL);
int modesize = model.size();
if (modesize <= 0) {
mTimeTableView.addView(addStartView(MAXNUM + 1, week, 0));
} else {
for (int i = 0; i < modesize; i++) {
if (i == 0) {
//添加的0到開始節(jié)數(shù)的空格
mTimeTableView.addView(addStartView(model.get(0).getStartnum(), week, 0));
mTimeTableView.addView(getMode(model.get(0)));
} else if (model.get(i).getStartnum() - model.get(i - 1).getStartnum() > 0) {
//填充
mTimeTableView.addView(addStartView(model.get(i).getStartnum() - model.get(i - 1).getEndnum(), week, model.get(i - 1).getEndnum()));
mTimeTableView.addView(getMode(model.get(i)));
}
if (i + 1 == modesize) {
mTimeTableView.addView(addStartView(MAXNUM - model.get(i).getEndnum(), week, model.get(i).getEndnum()));
}
}
}
return mTimeTableView;
}
/**
* 獲取單個課表View 也可以自定義我這個
*
* @param model 數(shù)據(jù)類型
* @return
*/
@SuppressWarnings("deprecation")
private View getMode(final TimeTableModel model) {
LinearLayout mTimeTableView = new LinearLayout(getContext());
mTimeTableView.setOrientation(VERTICAL);
TextView mTimeTableNameView = new TextView(getContext());
int num = model.getEndnum() - model.getStartnum();
mTimeTableNameView.setHeight(dip2px((num + 1) * TimeTableHeight) + num * 2);
mTimeTableNameView.setTextColor(getContext().getResources().getColor(
android.R.color.white));
mTimeTableNameView.setWidth(dip2px(50));
mTimeTableNameView.setTextSize(16);
mTimeTableNameView.setGravity(Gravity.CENTER);
mTimeTableNameView.setText(model.getName() + "@" + model.getClassroom());
mTimeTableView.addView(mTimeTableNameView);
mTimeTableView.addView(getWeekTransverseLine());
mTimeTableView.setBackgroundDrawable(getContext().getResources()
.getDrawable(colors[getColorNum(model.getName())]));
mTimeTableView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(getContext(), model.getName() + "@" + model.getClassroom(), Toast.LENGTH_LONG).show();
}
});
return mTimeTableView;
}
/**
* 轉(zhuǎn)換dp
*
* @param dpValue
* @return
*/
public int dip2px(float dpValue) {
float scale = getContext().getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
public void setTimeTable(List<TimeTableModel> mlist) {
this.mListTimeTable = mlist;
for (TimeTableModel timeTableModel : mlist) {
addTimeName(timeTableModel.getName());
}
initView();
invalidate();
}
/**
* 輸入課表名循環(huán)判斷是否數(shù)組存在該課表 如果存在輸出true并退出循環(huán) 如果不存在則存入colorSt[20]數(shù)組
*
* @param name
*/
private void addTimeName(String name) {
boolean isRepeat = true;
for (int i = 0; i < 20; i++) {
if (name.equals(colorStr[i])) {
isRepeat = true;
break;
} else {
isRepeat = false;
}
}
if (!isRepeat) {
colorStr[colornum] = name;
colornum++;
}
}
/**
* 獲取數(shù)組中的課程名
*
* @param name
* @return
*/
public static int getColorNum(String name) {
int num = 0;
for (int i = 0; i < 20; i++) {
if (name.equals(colorStr[i])) {
num = i;
}
}
return num;
}
}
布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@android:color/white" android:orientation="vertical" > <ScrollView android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.shallcheek.timetale.TimeTableView android:id="@+id/main_timetable_ly" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > </com.shallcheek.timetale.TimeTableView> </ScrollView> </LinearLayout>
最新版查看:查看地址
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android關(guān)于獲取時間的記錄(小結(jié))
這篇文章主要介紹了Android關(guān)于獲取時間的記錄(小結(jié)),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置)
本篇文章主要介紹了android仿微信通訊錄搜索示例(匹配拼音,字母,索引位置),具有一定的參考價值,有興趣的可以了解一下2017-09-09
深入解析Android中的setContentView加載布局原理
在日常開發(fā)Android中setContentView是必不可少的一部分,下面這篇文章主要給大家介紹了關(guān)于Android中setContentView的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。2017-09-09
Flutter pageview切換指示器的實現(xiàn)代碼
這篇文章主要介紹了Flutter pageview切換指示器的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04

