android项目案例之超级课程表

Posted 程序员小毛驴

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android项目案例之超级课程表相关的知识,希望对你有一定的参考价值。

转载请注明出处:http://blog.csdn.net/liulongling/article/details/50127819

demo和超级课程表界面和功能有些不一样 如:

 1.效果图左侧时间轴,超级课程表是每节课,我做的是每节课对应的时间

 2.每周课程切换,超级课程表是点击顶部的第几周显示每周课程,我做的是监听手指手势切换上下周

实现思路:

  1.UI上使用ScrollView来实现一天课程的滚动,因为需要实现通过手势来切换每周的课程,所以这里重写了ScrollViewExtend.否则手势监听事件会与ScrollView发生冲突

  2.布局上的划分,左边第一列是时间轴,一共24小时。除第一列,后面几列是显示课程内容.知道了每周是7天,每天24小时,屏幕宽高,求得每小时课程宽高,再深入计算每分钟的高度high。最后通过课程的时间 日期和high计算出课程显示的坐标.知道了坐标 剩下就是堆代码了...

代码运行需要配置:

 1.注解配置地址:http://jingyan.baidu.com/article/5552ef47c25fea518ffbc9e9.html

 2.注解包下载和使用地址:http://jakewharton.github.io/butterknife/

思路一代码:

1>重写ScrollView

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_main"
    android:orientation="vertical" >

    <include
        android:id="@+id/weekday"
        layout="@layout/course_week_date" />

    <com.app.lll.view.ScrollViewExtend
        android:id="@+id/scroll_body"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/weekday"
        android:scrollbars="none" >

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <LinearLayout
                android:id="@+id/ll_weekView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <LinearLayout
                    android:id="@+id/ll_time"
                    android:layout_width="50dp"
                    android:layout_height="wrap_content"
                    android:orientation="vertical" >
                </LinearLayout>

                <TextView
                    android:layout_width="1.5dp"
                    android:layout_height="match_parent"
                    android:background="#d8d8d8" />

                <RelativeLayout
                    android:id="@+id/rl_courses"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >
                </RelativeLayout>
            </LinearLayout>

            <RelativeLayout
                android:id="@+id/rl_user_courses"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </RelativeLayout>
        </RelativeLayout>
    </com.app.lll.view.ScrollViewExtend>
</RelativeLayout>

package com.app.lll.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.ScrollView;

/**
 * 重写ScrollView 可以与手势事件共同使用
 * @author liulongling
 *
 */
public class ScrollViewExtend extends ScrollView 
	
	GestureDetector gestureDetector;
	
	public ScrollViewExtend(Context context) 
		super(context);
	
	public ScrollViewExtend(Context context, AttributeSet attrs) 
		super(context, attrs);
	
	public ScrollViewExtend(Context context, AttributeSet attrs, int defStyle) 
		super(context, attrs, defStyle);
	
	public void setGestureDetector(GestureDetector gestureDetector) 
		this.gestureDetector = gestureDetector;
	

	public boolean onTouchEvent(MotionEvent ev) 
		super.onTouchEvent(ev);
		return gestureDetector.onTouchEvent(ev);
	

	public boolean dispatchTouchEvent(MotionEvent ev)
		gestureDetector.onTouchEvent(ev);
		super.dispatchTouchEvent(ev);
		return true;
	

2>计算课程格子高度宽度

	//第一个格子宽度
	firstGridWidth =DensityUtils.dp2px(mContext, 50+2);
	//格子平均宽度
	aveWidth = (ScreenUtils.getScreenWidth(mContext)-firstGridWidth) / 7;
	//格子平均高度
	gridHeight =ScreenUtils.getScreenHeight(mContext) / 12;

3>左侧时间轴

<pre name="code" class="java">public void initViewParams()
		if(mHourParams == null)
			mHourParams = new RelativeLayout.LayoutParams(firstGridWidth,gridHeight);
		

		if(mHourTextParams == null)
			mHourTextParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
			mHourTextParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
			mHourTextParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		

		if(mHourLineParams == null)
			mHourLineParams = new RelativeLayout.LayoutParams(DensityUtils.dp2px(mContext, 10),DensityUtils.dp2px(mContext, (float)1.5));
			mHourLineParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
			mHourLineParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
		
	

/**
	 * 初始化24小时*8view
	 */
	public void initTwentyFourHourViews()
		initViewParams();
		for(int i=1;i<HOURS.length;i++)
			for(int j=1;j<=8;j++)
				if(j==1)
					addTimeView(i-1);//时间轴
				else
					addDotView(i,j-1);//小黑点

					//可以点击的TextView 用来添加课程
					TextView tx = new TextView(mContext);
					tx.setId((i - 1) * 7  + j);
					//相对布局参数
					RelativeLayout.LayoutParams rp = new RelativeLayout.LayoutParams(aveWidth,gridHeight);
					//设置他们的相对位置
					if(j == 2)
						if(i > 1)
							rp.addRule(RelativeLayout.BELOW, (i - 2) * 7+j);
						
					else
						//字体样式
						tx.setTextAppearance(mContext, R.style.courseTableText);
						rp.addRule(RelativeLayout.RIGHT_OF, (i - 1) * 7  + j - 1);
						rp.addRule(RelativeLayout.ALIGN_TOP, (i - 1) * 7  + j - 1);
						tx.setText("");
					

					tx.setLayoutParams(rp);
					tx.setOnClickListener(new OnClickListener() 
						@Override
						public void onClick(View v) 
							int hour = (v.getId()-2)/7;
							int weekofday=(v.getId() -1)%7;
							if(weekofday == 0)
								weekofday = 7;
							

							if(hour < 0)
								hour = 0;
							
							//莫忘了计算点击的时间时 加上开始时间
							hour += HOURS[0];
							if(curClickView!=null)
								curClickView.setBackground(null);
								if(curClickView.getId() == v.getId())
									curClickView = null;
									//跳转到添加课程界面
									return;
								
							
							curClickView = v;
							curClickView.setBackground(getResources().getDrawable(R.drawable.bg_course_add));
							curClickView.setAlpha((float)0.5);
						
					);
					courseLayout.addView(tx);
				
			
		
	

 

 

4>左侧时间轴格子

<pre name="code" class="java">	/**
	 * 时间轴
	 * @param hour 几点
	 */
	public void addTimeView(int hour)
		RelativeLayout layout = new RelativeLayout(mContext);
		layout.setLayoutParams(mHourParams);

		//第一个格子里显示2个时间 24点 1点
		if(hour == 0)
		
			RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
			layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
			layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);

			TextView textView = new TextView(mContext);
			textView.setText("0"+HOURS[0]+":00");
			textView.setLayoutParams(layoutParams);
			textView.setTextAppearance(mContext, R.style.weekViewTimeText);
			layout.addView(textView);
		
		//第一个时间显示在格子顶部 其它时间显示在底部
		hour = HOURS[hour+1];

		TextView textView = new TextView(mContext);
		textView.setLayoutParams(mHourTextParams);
		textView.setTextAppearance(mContext, R.style.weekViewTimeText);
		
		StringBuilder builder = new StringBuilder();
		builder.append(hour < 10?("0"+hour):hour);
		builder.append(":00");
		
		//22点不显示
		textView.setText(builder.toString());
		
		if(hour == 22)
			textView.setVisibility(View.INVISIBLE);
		
		
		layout.addView(textView);
		
		//22点横线不显示
		if(hour != 22)
			TextView lineView = new TextView(mContext);
			lineView.setLayoutParams(mHourLineParams);
			lineView.setBackgroundColor(getResources().getColor(R.color.week_view_black));
			layout.addView(lineView);
		
		timeLayout.addView(layout);
	

 

思路二代码

自定义view显示课程位置

<pre name="code" class="java">/**
	 * 根据课程时间绘制课程显示的位置
	 * @param name    课程名称
	 * @param sHour   课程开始时间
	 * @param sHour   课程开始分钟
	 * @param min     这节课有多少分钟
	 * @param weekday 周几
	 */
	public void addCourseView(Lesson bean)

		int[] sParams = DateUtil.getTime(bean.getsTime());
		int[] eParams = DateUtil.getTime(bean.geteTime());
		if(sParams == null || eParams == null)
			return;
		

		//开始时间 分钟  总时间
		int sHour,sMin,eHour,eMin,min;

		sHour = sParams[0];
		sMin = sParams[1];

		eHour= eParams[0];
		eMin = eParams[1];

		if(eHour > sHour || eMin > sMin)
			min = (eHour - sHour)*60+(eMin - sMin);
			if(min < 40)
				min = 40;
			
			//课程高度
			float minHeight = (float)gridHeight/(float)60;
			int cHeight = (int)(((float)gridHeight/(float)60)*min);
			int weekday = DateUtil.getWeekOfDate(bean.getLessonDate());
			if(weekday == 0)
				weekday = 7;
			

			//1.添一个相对布局 来存储图片和文字
			RelativeLayout layout = new RelativeLayout(mContext);
			layout.setTag(String.valueOf(bean.getId()));
			RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(aveWidth,cHeight);
			//Calculate the location of the course Since the beginning of the course is from 7 points  
			rlp.topMargin = (sHour-7)*gridHeight+(int)(minHeight*sMin);
			rlp.leftMargin = firstGridWidth+(weekday-1)*aveWidth;
			layout.setLayoutParams(rlp);
			//设置背景框
			layout.setBackgroundResource(R.drawable.course_bg);
			//设置背景颜色
			GradientDrawable  drawable =(GradientDrawable) layout.getBackground();
			drawable.setColor(ColorUtils.getFillColor(1));
			//设置描边颜色
			drawable.setStroke(DensityUtils.dp2px(mContext, 2),ColorUtils.getStrokeColor(2));

			//bean.status == ClientCode.YS?mContext.getResources().getColor(background[0]):mContext.getResources().getColor(background[DateUtil.getWeekDay()])
			
			//设置不透明度
			layout.getBackground().setAlpha(222);

			//2.添加课程
			TextView courseInfo = new TextView(mContext);

			StringBuilder builder = new StringBuilder();
			builder.append(bean.getsTime());
			builder.append("\\n");
			builder.append(" ");
			builder.append(bean.getName());
			courseInfo.setText(builder.toString());

			// 偏移由这节课是星期几决定
			//rlp.addRule(RelativeLayout.RIGHT_OF, 1);
			// 字体居中
			//courseInfo.setGravity(Gravity.CENTER);
			RelativeLayout.LayoutParams layoutParams= new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
			courseInfo.setTextSize(12);
			courseInfo.setLayoutParams(layoutParams);
			courseInfo.setTextColor(Color.WHITE);

			layout.setOnClickListener(new OnClickListener() 
				@Override
				public void onClick(View v) 
					 //课程信息界面
				
			);

			layout.addView(courseInfo);
			//课程以上显示已经图标
			if(bean.getStatus() == 1)
				layout.addView(addClassOkIcon());
			
			mUserCourseLayout.addView(layout);
		
	

源码下载地址(需CSDN积分):http://download.csdn.net/detail/liulongling/9422256 

源码github地址:https://github.com/liulongling/CourseTable.git

以上是关于android项目案例之超级课程表的主要内容,如果未能解决你的问题,请参考以下文章

Linux课程笔记 Linux系统集权分治管理sudoer配置案例

Ruby on Rails全栈课程3.8 权限管理之超级管理员审批功能实现

(第9篇)大数据的的超级应用——数据挖掘-推荐系统

免费送课程+海量学习资料计算机二级考试超级干货大放送~

2019年春第三次课程设计实验报告

Android课程表的设计开发