文章标题

  1. 效果图


    自定义课程显示图
  2. 自布局文件
    1)左上角的布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="50dip" android:layout_height="50dip" >

    <TextView  android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#FF0000" android:text="课程表" />

</RelativeLayout>

2)上边的布局文件,星期几

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="100dip" android:layout_height="50dip" >

    <TextView  android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#FF0000" android:text="星期几" />

</RelativeLayout>

3)课时的布局,例如1-2

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="50dip" android:layout_height="100dip" >

    <TextView  android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#FF0000" android:text="1-2" />

</RelativeLayout>

4)课的详细信息的布局文件,

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="50dip" android:layout_height="100dip" >

    <TextView  android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:textColor="#FF0000" android:text="1-2" />

</RelativeLayout>
  1. 自定义的CourseView,继承自ViewGroup,可以滑动!,支持横竖屏切换时数据的保存与恢复。
    实体类
package com.course.csh.view;

import java.io.Serializable;

import android.widget.RelativeLayout;

public class CourseBean implements Serializable{

    /** * */
    private static final long serialVersionUID = 1L;
    private RelativeLayout relativeLayout;
    public RelativeLayout getRelativeLayout() {
        return relativeLayout;
    }
    public void setRelativeLayout(RelativeLayout relativeLayout) {
        this.relativeLayout = relativeLayout;
    }
    //位置
    private int position;
    //课程名称
    private String courseName;
    //课程时间
    private String shijian;
    //课程老师
    private String teacher;

    public int getPosition() {
        return position;
    }
    public void setPosition(int position) {
        this.position = position;
    }
    public String getCourseName() {
        return courseName;
    }
    public void setCourseName(String courseName) {
        this.courseName = courseName;
    }
    public String getShijian() {
        return shijian;
    }
    public void setShijian(String shijian) {
        this.shijian = shijian;
    }
    public String getTeacher() {
        return teacher;
    }
    public void setTeacher(String teacher) {
        this.teacher = teacher;
    }

}
package com.course.csh.view;

import java.io.Serializable;
import java.util.ArrayList;

import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.course.csh.R;

public class CourseView extends ViewGroup {

    private ArrayList<CourseBean> array = new ArrayList<CourseBean>();
    /* * 横竖屏切换保存数据 */
    private Temp temp = new Temp();

    /* * 整个子布局的所有的宽度 */
    private int childWidth = 0;
    private int childHieght = 0;
    /* * 整个布局的宽度和高度 */
    private int totalWidth = 0;
    private int totalHeight = 0;
    /* * 相对于x,y偏移的坐标值 1次 */
    private int xOffset = 0;
    private int yOffset = 0;
    /* * 相对于x,y偏移的坐标值 总的 */
    private int txOffset = 0;
    private int tyOffset = 0;
    /* * 开始移动时的坐标值 */
    private int startX = 0;
    private int startY = 0;

    public CourseView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        this(context, null);
    }

    public CourseView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, null);
    }

    public CourseView(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (array.size() == 0) {
            init();
        }
        for (int i = 0; i < 36; i++) {
            RelativeLayout layout = null;
            if (i == 0) {
                // 添加表头
                layout = getBiaoTou(context, "课程表");
            } else if (i > 0 && i <= 5) {
                switch (i) {
                case 1:
                    layout = getXingQi(context, "星期一");
                    break;
                case 2:
                    layout = getXingQi(context, "星期二");
                    break;
                case 3:
                    layout = getXingQi(context, "星期三");
                    break;
                case 4:
                    layout = getXingQi(context, "星期四");
                    break;
                case 5:
                    layout = getXingQi(context, "星期五");
                    break;
                }
            } else {
                if (i % 6 == 0) {
                    if (i / 6 == 1) {
                        layout = getKeShi(context, "1-2");
                    } else if (i / 6 == 2) {
                        layout = getKeShi(context, "3-4");
                    } else if (i / 6 == 3) {
                        layout = getKeShi(context, "5-6");
                    } else if (i / 6 == 4) {
                        layout = getKeShi(context, "7-8");
                    } else if (i / 6 == 5) {
                        layout = getKeShi(context, "9-10");
                    }
                } else {
                    layout = getCourseMessage(context,
                            array.get((i / 6 - 1) * 5 + i % 6 - 1));
                    array.get((i / 6 - 1) * 5 + i % 6 - 1).setRelativeLayout(
                            layout);
                }
            }
            if (i % 5 == 4) {
                layout.setBackgroundResource(R.drawable.background1);
            } else if (i % 5 == 3) {
                layout.setBackgroundResource(R.drawable.background2);
            } else if (i % 5 == 2) {
                layout.setBackgroundResource(R.drawable.background3);
            } else if (i % 5 == 1) {
                layout.setBackgroundResource(R.drawable.background4);
            } else {
                layout.setBackgroundResource(R.drawable.background5);
            }
            addView(layout);
        }
    }

    // 初始化数据参数
    private void init() {
        array.clear();
        for (int i = 0; i < 25; i++) {
            CourseBean bean = new CourseBean();
            bean.setCourseName("课程名" + i);
            bean.setPosition(i);
            bean.setShijian("09-12");
            bean.setTeacher("csh4220");
            array.add(bean);
        }
    }

    public CourseView(Context context) {
        this(context, null);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        // TODO Auto-generated method stub
        totalWidth = getWidth();
        totalHeight = getHeight();
        int count = getChildCount();

        int pw = txOffset;
        int ph = tyOffset;
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
            int cw = view.getMeasuredWidth();
            int ch = view.getMeasuredHeight();

            int cl = 0, ct = 0, cr = 0, cb = 0;
            cl = pw;
            ct = ph;
            cr = cl + cw;
            cb = ct + ch;
            if (i % 6 == 5) {
                ph += ch;
                pw = txOffset;
            } else {
                pw += cw;
            }
            view.layout(cl, ct, cr, cb);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int width = 0;
        int height = 0;
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        for (int i = 0; i < 6; i++) {
            View view = getChildAt(i);
            int cwidth = view.getMeasuredWidth();

            width += cwidth;
        }
        for (int i = 0; i < 36; i += 6) {
            View view = getChildAt(i);
            int chieght = view.getMeasuredHeight();

            height += chieght;
        }

        childWidth = width;
        childHieght = height;

        setMeasuredDimension((widthMode == MeasureSpec.EXACTLY) ? widthSize
                : width, (heightMode == MeasureSpec.EXACTLY) ? heightSize
                : height);
    }

    /* * 取得课程表的表头 */
    private RelativeLayout getBiaoTou(Context context, String message) {
        RelativeLayout layout = (RelativeLayout) View.inflate(context,
                R.layout.biaotou, null);
        TextView textView = (TextView) layout.findViewById(R.id.textView1);
        textView.setText(message);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                (int) context.getResources().getDimension(R.dimen.course2),
                (int) context.getResources().getDimension(R.dimen.course2));
        layout.setLayoutParams(params);
        return layout;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        return super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        // TODO Auto-generated method stub
        int ex = (int) ev.getX();
        int ey = (int) ev.getY();
        switch (ev.getAction()) {
        case MotionEvent.ACTION_DOWN:
            startX = ex;
            startY = ey;
            return true;
        case MotionEvent.ACTION_UP:
            xOffset = ex - startX;
            yOffset = ey - startY;
            txOffset += xOffset;
            tyOffset += yOffset;
            dealBianJie();
            onLayout(true, 0, 0, 0, 0);
            startX = ex;
            startY = ey;
            break;
        case MotionEvent.ACTION_MOVE:
            xOffset = ex - startX;
            yOffset = ey - startY;
            txOffset += xOffset;
            tyOffset += yOffset;
            dealBianJie();
            onLayout(true, 0, 0, 0, 0);
            startX = ex;
            startY = ey;
            return true;
        }
        return false;
    }


    /* * 处理不要超出边界线 */
    private void dealBianJie() {
        // 右
        if (0 - txOffset + totalWidth >= childWidth) {
            txOffset = totalWidth - childWidth;
        }
        // 下
        if (0 - tyOffset + totalHeight >= childHieght) {
            tyOffset = totalHeight - childHieght;
        }
        // 上
        if (txOffset >= 0) {
            txOffset = 0;
        }
        // 左
        if (tyOffset >= 0) {
            tyOffset = 0;
        }
    }

    /* * 取得星期 */
    private RelativeLayout getXingQi(Context context, String message) {
        RelativeLayout layout = (RelativeLayout) View.inflate(context,
                R.layout.xingqi, null);
        TextView textView = (TextView) layout.findViewById(R.id.textView1);
        textView.setText(message);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                (int) context.getResources().getDimension(R.dimen.course1),
                (int) context.getResources().getDimension(R.dimen.course2));
        layout.setLayoutParams(params);
        return layout;
    }

    /* * 取得课时 */
    private RelativeLayout getKeShi(Context context, String message) {
        RelativeLayout layout = (RelativeLayout) View.inflate(context,
                R.layout.keshi, null);
        TextView textView = (TextView) layout.findViewById(R.id.textView1);
        textView.setText(message);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                (int) context.getResources().getDimension(R.dimen.course2),
                (int) context.getResources().getDimension(R.dimen.course1));
        layout.setLayoutParams(params);
        return layout;
    }

    /* * 取得课程内容 */
    private RelativeLayout getCourseMessage(Context context, CourseBean bean) {
        RelativeLayout layout = (RelativeLayout) View.inflate(context,
                R.layout.item, null);
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
                (int) context.getResources().getDimension(R.dimen.course1),
                (int) context.getResources().getDimension(R.dimen.course1));
        layout.setLayoutParams(params);
        TextView textView1 = (TextView) layout.findViewById(R.id.textView1);
        TextView textView2 = (TextView) layout.findViewById(R.id.textView2);
        TextView textView3 = (TextView) layout.findViewById(R.id.textView3);
        textView1.setText(bean.getCourseName());
        textView2.setText(bean.getShijian());
        textView3.setText(bean.getTeacher());
        bean.setRelativeLayout(layout);
        return layout;
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        return true;
    }

    // 横竖屏转化时对数据进行保存
    @Override
    protected Parcelable onSaveInstanceState() {
        // TODO Auto-generated method stub
        Parcelable superState = super.onSaveInstanceState();
        MyData ss = new MyData(superState);
        temp.setArray(array);
        ss.temp = temp;
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        // TODO Auto-generated method stub
        MyData ss = (MyData) state;
        super.onRestoreInstanceState(ss.getSuperState());
        temp = ss.temp;
        for (int i = 0; i < 25; i++) {
            // array.add(temp.getArray().get(i));
            CourseBean courseBean = array.get(i);
            CourseBean bean = temp.getArray().get(i);
            courseBean.setCourseName(bean.getCourseName());
            courseBean.setPosition(bean.getPosition());
            courseBean.setShijian(bean.getShijian());
            courseBean.setTeacher(bean.getTeacher());
        }
        refreshDate();
    }

    private void refreshDate() {
        int len = array.size();
        for (int i = 0; i < len; i++) {
            CourseBean bean = array.get(i);
            RelativeLayout relativeLayout = bean.getRelativeLayout();
            TextView textView1 = (TextView) relativeLayout
                    .findViewById(R.id.textView1);
            TextView textView2 = (TextView) relativeLayout
                    .findViewById(R.id.textView2);
            TextView textView3 = (TextView) relativeLayout
                    .findViewById(R.id.textView3);
            textView1.setText(bean.getCourseName());
            textView2.setText(bean.getShijian());
            textView3.setText(bean.getTeacher());
        }
        invalidate();
        onLayout(true, 0, 0, 0, 0);
    }

    private class Temp implements Serializable {
        /** * */
        private static final long serialVersionUID = 2L;
        private ArrayList<CourseBean> array = new ArrayList<CourseBean>();

        public ArrayList<CourseBean> getArray() {
            return array;
        }

        public void setArray(ArrayList<CourseBean> array) {
            this.array = array;
        }

    }

    private class MyData extends BaseSavedState {

        private Temp temp;

        MyData(Parcelable superState) {
            super(superState);
        }

        private MyData(Parcel in) {
            super(in);
            temp = (Temp) in.readSerializable();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeSerializable(temp);
        }

        @SuppressWarnings("unused")
        public Parcelable.Creator<MyData> CREATOR = new Parcelable.Creator<MyData>() {
            public MyData createFromParcel(Parcel in) {
                return new MyData(in);
            }

            public MyData[] newArray(int size) {
                return new MyData[size];
            }
        };
    }
}
  1. actiivty的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.course.csh.view.CourseView
        android:id="@+id/courseView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" >
    </com.course.csh.view.CourseView>

</RelativeLayout>
  1. Activity文件!
package com.course.csh;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

菜鸟写作,欢迎大神指导!免费下载地址

你可能感兴趣的:(android,布局,ViewGroup,课程格子)