简单方法实现仿超级课程表界面

本文介绍了如何使用自定义ViewGroup和LinearLayout实现仿超级课程表的界面。作者分享了早期尝试使用GridView和RecyclerView未能解决跨行问题的经历,以及现在的实现思路,包括对课程信息的排序和布局。虽然这种方法实现效果不错,但缺乏拓展性,如点击监听等。文章提供了源代码链接供读者参考。

简单方法实现仿超级课程表界面

这里写图片描述

(这个代码其实是我好久之前写武大课程表的时候自己突发奇想实现的。由于当时代码水平不高,所以想出来的方法可能有点歪门邪道的感觉。现在看来,对于实现的方法又有了许多的想法,不过没有自己试验过,我会在下面说一下,有哪位大佬要是实现了,希望能留个言,说一下具体思路,也算为后面来的新人一个方向)

遇到的困难

当初第一次有这个想法的时候感觉也不是特别难,但是一上手却发现自己想到的方法竟然都不能用,也是醉了。先说说我当时想到的思路(当然,都没能实现)
1.一开始看到,这不就是个表格嘛,就只想着使用gridview(表格布局)。但是有一个极大的问题就是,gridview是没有动态改变什么跨行啊,等等一系列的方法的,于是该方法gg。
2.当时在网上也看了,但是当时水平低,看不懂,有人说可以使用listview,奈何太菜,也gg。
3.使用recycleview。该方法同gridview,不知道怎么设置跨行之类的,gg。

现在的畅想

现在也算多接触了一些技术,有了一些其他的想法。
1.使用自定义viewgroup。从超级课程表的布局来看,好像就是这个方法实现的。(这里放一下两张图的对比)
这里写图片描述

如果写过自定义viewgroup的,就会知道,这里是相对于边界的定位,然后画出的。

这里写图片描述

我这里使用了7个Linearlayout,每一个竖排都是一个Linearlayout。

2.继承并重写Linearlayout也是可以的,相当于我这个实现方法的一个封装。

具体实现

因为我这里是使用了7个Linearlayout,那么必然需要对获得的课程信息进行一个排序,确定谁在哪个Linearlayout里面,谁先加入Linearlayout等等。

1.布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    //这里是toolbar
    <android.support.v7.widget.Toolbar
        android:id="@+id/Toolbar_grid"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary">

        <RelativeLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:layout_centerInParent="true">
                <TextView
                    android:id="@+id/txt1_gird"
                    android:textSize="20dp"
                    android:layout_gravity="center"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content" />
                <TextView
                    android:layout_gravity="center"
                    android:id="@+id/txt2_grid"
                    android:textSize="10dp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"  />
            </LinearLayout>

            <Button
                android:id="@+id/bt_gird"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:textSize="18dp"
                android:text="列表模式"
                android:background="@color/colorPrimaryDark"/>
        </RelativeLayout>
    </android.support.v7.widget.Toolbar>


    //这是最上面那一排显示星期几的。style就不贴了,注意有weight,把布局均分就行
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:orientation="horizontal"
        android:divider="@drawable/divider"
        android:showDividers="middle">
        <TextView
            android:singleLine="false"
            android:id="@+id/month"
            android:textSize="13dp"
            android:layout_width="24dp"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="2\n月"/>
        <TextView
            android:id="@+id/Mon"
            style="@style/top"
            android:text="周一\n27号" />
        <TextView
            android:id="@+id/Tus"
            style="@style/top"
            android:text="周二" />
        <TextView
            android:id="@+id/Wed"
            style="@style/top"
            android:text="周三" />
        <TextView
            android:id="@+id/Thu"
            style="@style/top"
            android:text="周四" />
        <TextView
            android:id="@+id/Fri"
            style="@style/top"
            android:text="周五" />
        <TextView
            android:id="@+id/Sat"
            style="@style/top"
            android:text="周六" />
        <TextView
            android:id="@+id/Sun"
            style="@style/top"
            android:text="周日" />
    </LinearLayout>

    //这里是第一竖排,显示第几节课 1-13
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:orientation="vertical"
                android:layout_width="24dp"
                android:layout_height="match_parent">
                <TextView
                    style="@style/first_item"
                    android:text="1" />
                <TextView
                    style="@style/first_item"
                    android:text="2" />
                <TextView
                    style="@style/first_item"
                    android:text="3" />
                <TextView
                    style="@style/first_item"
                    android:text="4" />
                <TextView
                    style="@style/first_item"
                    android:text="5" />
                <TextView
                    style="@style/first_item"
                    android:text="6" />
                <TextView
                    style="@style/first_item"
                    android:text="7" />
                <TextView
                    style="@style/first_item"
                    android:text="8" />
                <TextView
                    style="@style/first_item"
                    android:text="9" />
                <TextView
                    style="@style/first_item"
                    android:text="10" />
                <TextView
                    style="@style/first_item"
                    android:text="11" />
                <TextView
                    style="@style/first_item"
                    android:text="12" />
                <TextView
                    style="@style/first_item"
                    android:text="13" />
            </LinearLayout>

            //这里开始就是7个linearlayout了,用来显示课程的
            <LinearLayout
                android:id="@+id/column_1"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_2"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_3"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_4"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_5"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_6"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

            <LinearLayout
                android:id="@+id/column_7"
                android:layout_weight="1"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:orientation="vertical">
            </LinearLayout>

        </LinearLayout>

    </ScrollView>

</LinearLayout>

(假设你已经获取到了课表的详细信息,尤其是开始和结束是第几节课)
2.将课程根据星期分类。
(lesson是一个自定义的课程类)

//根据星期分类,然后添加到一个自定义的课程数组中
    private void sortWeek() {
        for (int i = 0; i < mDataset.length; i++) {
            switch (mDataset[i].getDay(0)) {
                case "1" :
                    Mon.add(mDataset[i]);
                    break;
                case "2":
                    Tus.add(mDataset[i]);
                    break;
                case "3":
                    Wed.add(mDataset[i]);
                    break;
                case "4":
                    Thu.add(mDataset[i]);
                    break;
                case "5":
                    Fri.add(mDataset[i]);
                    break;
                case "6":
                    Sta.add(mDataset[i]);
                    break;
                case "7":
                    Sun.add(mDataset[i]);
                    break;
            }
        }

        //这里是将分好类的课程添加到指定的linearlayout中。setview和sortlesson都是自定义的方法,后面有
        setView(linearLayout1, sortLesson(Mon));
        setView(linearLayout2, sortLesson(Tus));
        setView(linearLayout3, sortLesson(Wed));
        setView(linearLayout4, sortLesson(Thu));
        setView(linearLayout5, sortLesson(Fri));
        setView(linearLayout6, sortLesson(Sta));
        setView(linearLayout7, sortLesson(Sun));

3.对每个星期的课程排序

 //对指定星期的课程排序
    private Lesson[] sortLesson(List<Lesson> Week) {

        int k = 0;
        Lesson[] lesson = new Lesson[Week.size()];

        for (Lesson L : Week) {
            lesson[k] = L;
            k++;
        }
        //排序
        for (int i = 0; i < (k-1); i++) {
            for (int j = i+1; j < k; j++) {
                int a = Integer.parseInt(lesson[i].getstatrt(0));
                int b = Integer.parseInt(lesson[j].getstatrt(0));
                if (Integer.parseInt(lesson[i].getstatrt(0)) >    Integer.parseInt(lesson[j].getstatrt(0)) ) {
                    Lesson alesson = lesson[i];
                    lesson[i] = lesson[j];
                    lesson[j] = alesson;
                }
            }
        }
        return lesson;
    }

4.将课程转化为一个textview,然后添加到linearlayout中

//对指定的星期课程分析,设置上边的margin,和该课程的高度height即几个格子。然后添加TextView
    private void setView(LinearLayout linearLayout, Lesson[] lesson) {
        int last = 0;
        for (int i = 0; i < lesson.length; i++) {
            if (i != 0) {
                last = Integer.parseInt(lesson[i - 1].getend(0));
                if (Integer.parseInt(lesson[i-1].getstatrt(0)) == Integer.parseInt(lesson[i].getstatrt(0))) {
                    continue;
                }
            }

            int margin = 64 * (Integer.parseInt(lesson[i].getstatrt(0)) - last - 1);
            int height = 64 * (Integer.parseInt(lesson[i].getend(0)) - Integer.parseInt(lesson[i].getstatrt(0)) + 1);
            setstyle(linearLayout, lesson[i].getName(0)+"@"+lesson[i].getarea(0)+" "+lesson[i].getroom(0), height - 3, margin);
        }
    }

//添加一个TextView
    private void setstyle(LinearLayout linearLayout, String string, int height, int margin) {
        TextView textView = new TextView(this);
        textView.setText(string);
        textView.setBackgroundColor(Color.parseColor("#b9b9b9"));
        textView.setGravity(Gravity.CENTER);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dpTopx(height));
        lp.setMargins(dpTopx(2), dpTopx(margin + 3), dpTopx(2), 0);
        textView.setLayoutParams(lp);
        linearLayout.addView(textView);
    }

    //将dp单位换算为px
    private int dpTopx(int dp) {
        int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, this.getResources().getDisplayMetrics());
        return px;
    }

到这里就完成了

总的来说,还是一个比较苯的办法,不过也很好理解,实现效果还是可以的。但是这样的话是没有拓展性的,比如对于课程的点击监听就会有些无奈了。所以如果你有实力的话,最好的方法还是自定义一个viewgroup。

最后附上github源代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值