Giter Site home page Giter Site logo

zfman / timetableview Goto Github PK

View Code? Open in Web Editor NEW
709.0 13.0 107.0 22.27 MB

一款开源、完善、高效的Android课程表控件,支持添加广告、课程重叠自动处理、透明背景设置、空白格子点击事件处理等丰富的功能,并且有完善的开发文档、案例以供参考

Home Page: https://www.yuque.com/zhuangfei/timetableview/summary

License: MIT License

Java 99.54% Kotlin 0.46%
timetableview android

timetableview's Introduction

TimetableView

TimetableView是一款开源的Android课程表控件,你可以在 ChangeLog 查看本控件的开发进展,作者联系方式[email protected]

TimetableView是一款开源的、完善、高效的Android课程表控件。

  • 支持xml设置属性
  • 丰富的课程工具包
  • 支持多种自定义
  • 课程颜色管理
  • ScrollView可替换
  • 调用简洁、性能高效
  • 可设置背景以及透明度
  • 数据源可添加额外信息
  • 空白格子可点击,课程项可长按
  • 月份宽度可设置
  • 周末可设置隐藏
  • 课表具体逻辑可自定义
  • 本地配置:配置隔离、加载、导出至文本
  • 课程颜色可指定

最新文档

文档请参见:https://www.yuque.com/zhuangfei/timetableview/summary

完整案例-怪兽课表请参见:https://github.com/zfman/hputimetable

感谢贡献者

感谢所有参与本项目以及帮助我一起完善这个项目的开发者~~

用户 Issues pull request
Mystery00 #6.WeekView数组越界 修复#6,并添加新功能

关于作者

  • 刘壮飞,目前大四
  • 目前学习方向:Android,php和网页也会一点
  • 欢迎大家找我交流技术,共同学习进步
  • QQ:1193600556
  • 酷安ID:@zhuangfei
  • 掘金博客:@壮飞

timetableview's People

Contributors

mystery00 avatar zfman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

timetableview's Issues

周天显示bug

在OnDateBuildAapter类中:
设置高亮时layouts[dayOfWeek].setBackgroundColor(Color.parseColor("#BFF6F4"));,如果是周天dayOfWeek为0,layouts[dayOfWeek].索引异常。
if(dayOfWeek<0) dayOfWeek=7; 应该改成 if(dayOfWeek<=0) dayOfWeek=7;吧

课程格式导致的无法显示问题

今天才意识到这个问题,假设有如下格式数据:

课程名 上课周次 星期几 开始节次 持续节次 上课地点
高数b1 1 2 1 2 三教3303
高数b1 2 2 1 2 三教3303
高数b1 3 2 1 2 三教3303
大学物理 1 2 1 2 三教3101
英语 2 2 1 2 三教3301
体育 3 2 1 2 三教3302

可以很明显的看出来,它是以周次来切分课程的,每个周次都被作为了一门课程,高数在1、2、3周都有课,所以是三门课程。

根据使用本控件的开发者反馈,在这种格式下,他的课程有192个,并且课程界面什么都不会显示,这是由于控件内部的过滤课程机制造成的并不是控件问题,你需要遵循数据格式。

解决方法就是手动将课程合并,在此次中,将192个课程合并为了19个,其实课程项多的话,内部处理速度会变慢,处理19个数据和处理192个数据的速度可以相差很多的。

以下是我对其实现的一种合并课程的方法,你可以根据个人实际需要再修改:

list是类似上述表格中的数据

/**
     * 将192个课程合并为19个
     * @param list
     */
    public void handleData(List<MySchedule> list){
        if(list==null) return;
        Map<String,List<Integer>> map=new HashMap<>();
        List<MySchedule> delete=new ArrayList<>();
        for(MySchedule item:list){
            //保证键的唯一性
            String key=item.getName()+"#"+item.getRoom()+"#"+item.getTeacher()
                    +"#"+item.getTerm()+"#"+item.getDay()+"#"
                    +item.getStart()+"#"+item.getStep();
            if(map.containsKey(key)){
                map.get(key).addAll(item.getWeekList());
                delete.add(item);
            }else{
                map.put(key,item.getWeekList());
            }
        }

        list.removeAll(delete);
    }

课程时间跨度较大时,课程重叠会出现问题,缺少课程动态颜色改变

1:课程时间跨度较大时,课程重叠会出现问题
问题描述
当自定义了一个很多的时间段
例如
private String[] DAY_ALL_TIME=new String[]{ "09:00","09:30","10:00","10:30","11:00","11:30", "12:00","12:30","13:00","13:30","14:00","14:30","15:00","15:30", "16:00","16:30","17:00","17:30","18:00","18:30","19:00","19:30", "20:00","20:30","21:00","21:30","22:00","22:30","23:00","23:30" };
填充MySubject数据
例如
`
mySubject1.setStart(DAY_ALL_TIME[6]);//12:00开始
mySubject1.setStep(7);//7节课,到15:00结束

//课程有重叠
mySubject2.setStart(DAY_ALL_TIME[6]);//12:00开始
mySubject2.setStep(7);//7节课,到15:00结束

mySubject3.setStart(DAY_ALL_TIME[12]);//15:00开始
mySubject3.setStep(7);//7节课,到18:00结束

`
最终显示的itemview结果会全部合并到mySubject1 这个里面

看了下源码
引起的原因是由于
ScheduleSupport类下fliterSchedule()方法引起的
if(s.getStart()>=s2.getStart()&&s.getStart()<=(s2.getStart()+s2.getStep()-1)){ is=false; if(isThisWeek(s2,curWeek)){ break; }else if(isThisWeek(s,curWeek)){ result.remove(s2); result.add(s); } }
还有一个错误是重复的角标数字也不对
ScheduleSupport类下findSubjects()方法引起的
for (int i = 0; i < data.size(); i++) { Schedule bean = data.get(i); if (bean.getStart() >= subject.getStart() && bean.getStart() < (subject.getStart() + subject.getStep())) result.add(data.get(i)); }

2.缺少课程动态颜色改变
由于课程有“点名”和“未点名”的类型区分,而且是动态读取的,暂未找到动态设置每一个项的颜色方法
/** * 指定课程的颜色,未指定的课程自动分配 */ public void forColor(){ Map<String,Integer> colorMap=new HashMap<>(); colorMap.put("数字图像处理",Color.RED); colorMap.put("算法分析与设计",Color.BLUE); mTimetableView.colorPool().setIgnoreUserlessColor(false).setColorMap(colorMap); mTimetableView.updateView(); }
这个方法不太理想

@zfman

动态显示或隐藏非本周课程有 bug

比如设置的当前周是 4,然后手动选择到第 5 周,此时调用timetable_view.isShowNotCurWeektimetable_view.updateView()之后,周次选择栏会保持在第 5 周,而下面课表控件显示的课程又会跳回第 4 周的。

请教一下一个旗标偏移的问题

就是下面图片里的这样,越往右列越偏,我以为是我旗标宽度设置的问题,但是看了文档发现旗标宽度改不了,请教一下这个应该怎么处理呢,麻烦了

00

部分空白格子无法触发回调(和已经解决的问题不同)

现象为:若当前周某位置有课,切换到某一周该位置无课时,点击无法触发回调(例如,当前为第二周,周三第四节有课,我切换到第三周,当前位置无课,但是点击空白地方无响应,无法触发回调)。

初步查找,问题应该在SimpleOperater类的checkPosition函数中,当我使用changeWeek函数临时切换周后,week值在SimpleOperater类中没有保存下来,checkPosition函数获取课程集合时,依然使用当前周作为条件,这就导致了显示和判断的结果不同(list= ScheduleSupport.getHaveSubjectsWithDay(mView.dataSource(),mView.curWeek(),day);)

适配深色模式

目前控件没有适配 Android 的深色模式,导致效果很难看。
image

异步请求显示课程

需求

从网络上获取数据,然后将课程显示出来,,有些同学还搞不懂这是怎么操作的,所以写了个例子:只给出了核心代码,导入包的语句省略,这只是一个简单的异步请求模板,仅供参考

/**
 * 项目地址
 * https://github.com/zfman/TimetableView
 *
 * 请参考v2.0.2文档
 * https://github.com/zfman/TimetableView/wiki/%E6%9C%80%E6%96%B0%E6%96%87%E6%A1%A3
 *
 * v2.0.2-javadocs
 * http://www.liuzhuangfei.com/github/timetableview/docs/v2.0.2/
 *
 */
public class DemoActivity extends Activity {
    private TimetableView mTimetableView;
    private WeekView weekView;

    private List<MySchedule> mySchedule = new ArrayList<>();

    Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            //更新界面
            if(msg.what==0x123){
                //如果需要合并,请先合并
               //注意:一旦课程数据发生变化,这两个都要修改数据源,然后更新视图
                weekView.source(mySchedule).showView();
                mTimetableView.source(mySchedule).updateView();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_demo);
        initView();
        initTimetableView();
        request();
    }

    public void request() {
        new Thread(new Runnable() {
            public void run() {
               //处理加载数据的请求
              //加载完成后,更新mySchedule的值
             //然后使用handler发送消息0x123通知界面更新
            }
        }).start();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mTimetableView.onDateBuildListener().onHighLight();
    }

    /**
     * 初始化课程控件
     */
    private void initTimetableView() {
        //获取控件
        mTimetableView = (TimetableView) findViewById(R.id.id_timetableView);
        weekView = (WeekView) findViewById(R.id.id_weekview);

        //设置周次选择属性
        weekView.source(mySchedule)
                .curWeek(1)
                .callback(new IWeekView.OnWeekItemClickedListener() {
                    @Override
                    public void onWeekClicked(int curWeek) {
                        mTimetableView.changeWeekOnly(curWeek);
                    }
                })
                .isShow(false)
                .showView();

        mTimetableView.source(mySchedule)
                .curWeek(1)
                .curTerm("大一上学期")
                .callback(new ISchedule.OnItemClickListener() {
                    @Override
                    public void onItemClick(View v, List<Schedule> scheduleList) {
                        display(scheduleList);
                    }
                })
                .showView();
    }

    /**
     * 显示内容
     *
     * @param beans
     */
    protected void display(List<Schedule> beans) {
        String str = "";
        for (Schedule bean : beans) {
            str += bean.getName() + "、";
        }
        Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
    }
}

v2.0.0缺陷统计&修复计划

6月20日发布了v2.0.0,代码改动很大,所有可能存在很多问题。
在此统计v2.0.0的缺陷,这些都会在下个版本中修复

反馈缺陷最好分为三部分:

  • 问题的现象
  • 产生的原因
  • 解决的方法

WeekView数组越界

当source里面的Schedule存储的课程数据,如果所在的位置是9-11节(9、10、11)的时候,在绘制原点的时候会出现数组越界。
image
解决办法(目测):在标记课程的时候,判断end是否大于10,如果大于10,将end置为10。

意见征集

有什么好的建议,可以在下方评论~

改变日期时报错

哈哈,这是个乌龙,我把代码位置放错了

这样就是对的

//设置周次选择属性
        mWeekView.data(schedules)
                .curWeek(curWeek)
                .itemCount(25)
                .callback(new IWeekView.OnWeekItemClickedListener() {
                    @Override
                    public void onWeekClicked(int week) {
                        int cur = mTimetableView.curWeek();
                        //更新切换后的日期,从当前周cur->切换的周week
                        mTimetableView.onDateBuildListener()
                                .onUpdateDate(cur, week);
                        mTimetableView.changeWeekOnly(week);
                    }
                })
                .callback(new IWeekView.OnWeekLeftClickedListener() {
                    @Override
                    public void onWeekLeftClicked() {
                        onWeekLeftLayoutClicked();
                    }
                })
                .isShow(false)
                .showView();

点击格子间隙也会出现旗标布局

点击格子间隙也会出现旗标布局

Bug产生的原因主要是由于未对点击的位置进行检测,所以我们只需要在点击空格时对位置进行手动检测即可临时的解决这个问题。

v2.0.2临时的解决方法,下个版本中将修复此问题:

.callback(new OnSpaceItemClickAdapter(){
                    @Override
                    public void onSpaceItemClick(int day, int start) {
                        List<Schedule> list;
                        if(mTimetableView.isShowNotCurWeek()){
                            list= ScheduleSupport.getAllSubjectsWithDay(mTimetableView.dataSource(),day);
                        }else{
                            list= ScheduleSupport.getHaveSubjectsWithDay(mTimetableView.dataSource(),mTimetableView.curWeek(),day);
                        }
                        boolean isHave=false;
                        for(Schedule item:list){
                            if(start==item.getStart()||(start>=item.getStart()&&start<=(item.getStart()+item.getStep()-1))){
                                isHave=true;
                            }
                        }
                        if(!isHave){
                            super.onSpaceItemClick(day, start);
                        }
                    }
                })

完整示例如下:

mTimetableView.source(mySubjects)
                .curWeek(1)
                .curTerm("大三下学期")
              .callback(new OnSpaceItemClickAdapter(){
                    @Override
                    public void onSpaceItemClick(int day, int start) {
                        List<Schedule> list;
                        if(mTimetableView.isShowNotCurWeek()){
                            list= ScheduleSupport.getAllSubjectsWithDay(mTimetableView.dataSource(),day);
                        }else{
                            list= ScheduleSupport.getHaveSubjectsWithDay(mTimetableView.dataSource(),mTimetableView.curWeek(),day);
                        }
                        boolean isHave=false;
                        for(Schedule item:list){
                            if(start==item.getStart()||(start>=item.getStart()&&start<=(item.getStart()+item.getStep()-1))){
                                isHave=true;
                            }
                        }
                        if(!isHave){
                            super.onSpaceItemClick(day, start);
                        }
                    }
                })
              .showView();

v2.0.1缺陷统计&修复计划

6月20日发布了v2.0.0,代码改动很大,代码可能存在问题
6月24日发布了v2.0.1,修复部分bug
在此统计v2.0.1的缺陷,这些都会在下个版本中修复

反馈缺陷最好分为三部分:

  • 问题的现象
  • 产生的原因
  • 解决的方法

课程具体时间

感觉可以为左边的12345课程节数下添加这节课的时间段。
稍微把这一部分区域的宽度放大一些

日期月份计算错误

日期栏的月份不正确

该问题会在下个版本在源码中修复

解决办法:

不修改源码的解决方案,可暂时使用

可以在TimetableView初始化完成后调用以下代码对日期进行更正

int cur = mTimetableView.curWeek();
mTimetableView.onDateBuildListener() .onUpdateDate(cur, cur);

课程重叠显示错误

当某门课程跨度非常大时,之后的部分课程不能被完全的过滤掉

OS:课程重叠真的烦人,现在都没有彻底解决,由于之前没有进行大量测试才这样的,所以下次一定要多测试几种情况

等有时间我会尝试解决!

引入课表导致主题失效

QMUI和课表同时导入会导致QMUI的主题失效
出现问题的QMUI和课表版本分别为2.0.0-alpha02与2.0.7
QMUI在1.4.0版本上不会出现此问题
目前还不清楚是哪个项目导致的问题

澎湃OS,安卓14日期计算错误

首先十分感谢作者的控件!!!

之前使用一切正常,升级到了安卓14之后发现系统时间返回有了变化,控件内的判断存在边界错误,具体表现为:高亮日期是当前日期的后一天。

经过初步排查,问题出在OnDateBuildAapteronHighLight函数内。

//获取周几,1->7
        Calendar now = Calendar.getInstance();
        //一周第一天是否为星期天
        boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY);
        int weekDay = now.get(Calendar.DAY_OF_WEEK);
        //若一周第一天为星期天,则-1
        if (isFirstSunday) {
            weekDay = weekDay - 1;
            if (weekDay == 0) {
                weekDay = 7;
            }
        }

代码中,安卓13及以前, Calendar.getInstance().getFirstDayOfWeek()返回为1,逻辑正常,但是安卓14会返回2,但是代码会按返回值为0进行处理,从而导致计算结果比预期值+1。

// 安卓14的情况如下:
Calendar now = Calendar.getInstance();
        //一周第一天是否为星期天
        int firstDayOfWeek = now.getFirstDayOfWeek(); // 2
        int sunday = Calendar.SUNDAY; // 1
        boolean isFirstSunday = (now.getFirstDayOfWeek() == Calendar.SUNDAY); // false

所以需要将下方的计算函数改为:

if (isFirstSunday) {
            weekDay = weekDay - firstDayOfWeek ;
            if (weekDay == 0) {
                weekDay = 7;
            }
        }

希望作者尽快更新仓库代码,感谢!!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.