Android中自定义ViewGroup实现表格展示学员信息

前一段时间有个Android刚入门的朋友想实现一个表格 来展示信息,下面我们通过扩展ViewGroup 来实现一个简单的。

本文通过扩展Android ViewGroup实现表格 可用于课程信息,学生信息视图展示,实现表格方式可以用布局拼凑 也可以自定义ViewGroup方式实现。

最终效果如下:

首先创建基本模型和Activity

public class Student {

	/**
	 *
	 */
	public Student() {
		// TODO Auto-generated constructor stub
	}

	public String stuId;
	public String stuName;
	public String stuFrom;
	public String stuRoom;
	public String stuClass;
	public String stuDate;

}
public class StudentInfoActivity extends Activity {

	public StudentInfoActivity() {

	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_student);
		StudentInfoView courseInfoView = (StudentInfoView) findViewById(R.id.myview);
		ArrayList<Student> list = new ArrayList<Student>();
		addList(list);
		courseInfoView.addChildViews(list);

	}

	private void addList(ArrayList<Student> list) {
		Student c = new Student();
		c.stuId = "stu1001";
		c.stuName = "张帆";
		c.stuFrom = "浙江";
		c.stuDate = "2014-10-09";
		c.stuRoom = "NO2105";
		c.stuClass ="一年级1班";
		list.add(c);

		c = new Student();
		c.stuId = "stu1002";
		c.stuName = "汪清";
		c.stuFrom = "湖北";
		c.stuDate = "2014-11-11";
		c.stuRoom = "NO2012";
		c.stuClass ="一年级1班";
		list.add(c);

		c = new Student();
		c.stuId = "stu1003";
		c.stuName = "李密";
		c.stuFrom = "东北";
		c.stuDate = "2014-11-10";
		c.stuRoom = "NO1901";
		c.stuClass ="一年级2班";
		list.add(c);

		c = new Student();
		c.stuId = "stu1004";
		c.stuName = "李坤";
		c.stuFrom = "北京";
		c.stuDate = "2014-11-12";
		c.stuRoom = "NO1204";
		c.stuClass ="一年级3班";
		list.add(c);
	}

}

布局文件

<?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:orientation="vertical"
    android:background="#ffffff"
    >
    <TextView
        android:id="@+id/title"
        android:layout_marginTop="5dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="学员基本信息"
        android:textSize="18sp"
        android:textColor="#000000"
        android:layout_centerHorizontal="true"
        />
    <com.birds.mobile.course.StudentInfoView
        android:id="@+id/myview"
        android:layout_below="@+id/title"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
    </com.birds.mobile.course.StudentInfoView>

</RelativeLayout>

下面重点介绍扩展的ViewGroup类,StudentInfoView.java

每个格子里面都是一个TextView用于显示文本,一行为一个Student信息,包括6个字段 所以这里有6列。

     int itemWidth = 0;
     int itemHeight = 0;
     @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    	int w = getDefaultSize(0, widthMeasureSpec);
    	int h = getDefaultSize(0, heightMeasureSpec);
    	int m = w/colcount;
    	itemWidth = m;
    	itemHeight = m/4;
    	int itemSpecWidth = MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY);
    	int itemSpecHeigh = MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY);
    	Log.d("","get item width:" + itemSpecWidth + ";" + w + ";" + h);
    	Log.d("","h:" + itemHeight + " width:" + m);
    	measureChildren(itemSpecWidth, itemSpecHeigh);
    	setMeasuredDimension(w, h);
    }

public int colcount = 6; //六列

高度我们取宽度的1/4,可以自己调整,我们把宽度和高度通过整个ViewGroup的宽度计算 ,这里刚好是屏幕的宽度 fill_parent

	protected void onLayout(boolean changed, int l, int t, int r, int b) {
			int childCount = getChildCount();
			for (int i = 0 ; i < childCount ; i++) {
				View child = getChildAt(i);
				int row = i % colcount;//第几行
				int col = i / colcount;//第几列
			    int w1 = child.getMeasuredWidth();
			    int padding = itemWidth - w1;
			    if (padding >= 5) {
			    	padding = 5; //这里是为了让每个TextView 都有个左间距,大家可以自己计算 放到中间需要计算文本内容字的宽度
			    }
				int left = row * itemWidth + padding;
				int top = col * child.getMeasuredHeight();
				int right = left + itemWidth;
				int bottom = top + child.getMeasuredHeight();
				child.layout(left, top, right, bottom);
			}
	}

数据方法。

	public void addChildViews(ArrayList<Student> list) {
		if (list == null)
			return;
		for (Student c : list) {
			addView(createItemView(c.stuId));
			addView(createItemView(c.stuName));
			addView(createItemView(c.stuFrom));
			addView(createItemView(c.stuDate));
			addView(createItemView(c.stuRoom));
			addView(createItemView(c.stuClass));
		}
		courseList = list;
		int totalRow = (courseList.size() / colcount) * colcount;
		Log.d("","totalRow:" + totalRow);
	}

	private ViewGroup createItemView(String text){
		ViewGroup v = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout.item_view, null);
		((TextView)v.findViewById(R.id.text)).setText(text);
		return v;
	}

item_view布局内容

<?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" >
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text=""
        android:textSize = "16sp"
        android:textColor="#00CD00"
        />
</RelativeLayout>

好,现在数据基本能显示到ui上,只是还没画线。我门需要复写dispatchDraw 方法进行Canvas绘画

	protected void dispatchDraw(Canvas canvas) {
		super.dispatchDraw(canvas);
		Log.d("", "width:" + itemWidth + " heigh:" + itemHeight);
		//画水平线
		int totalRow = courseList.size();
     	for (int i = 0 ; i <= totalRow; i++) {
     		int startY = i * itemHeight;
     		int stopY = startY;
     		canvas.drawLine(0, startY, itemWidth * colcount, stopY, linePaint);
     	}
     	//画垂直线
     	for (int i = 0 ; i <= colcount; i++) {
     		int startX = i*itemWidth;
     		int stopX  = i*itemWidth;
     		int startY = 0;
     		int stopY = itemHeight * totalRow;
     		canvas.drawLine(startX, startY, stopX, stopY, linePaint);
     	}	

	}

画线就是计算的过程,通过每个item的宽和高,下面是线的属性代码。

	private Paint linePaint;

	private void init(){
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.GRAY);
        linePaint.setStrokeWidth(0.5f);
	}

表格上并未显示表头 其实这个也能画出来,或者用布局拼凑也是可以的。

今天就到这里,有问题请指出,谢谢。

时间: 2024-10-09 11:13:07

Android中自定义ViewGroup实现表格展示学员信息的相关文章

android中自定义ViewGroup的实现

在android中提供了常见的几种ViewGroup的实现,包括LinearLayout.Relativeayout.FrameLayout等.这些ViewGroup可以满足我们一般的开发需求,但是对于界面要求复杂的,这几个布局就显得捉襟见肘了.所以自定义的ViewGroup在我们接触过的应用中比比皆是. 要想实现一个自定义的ViewGroup,第一步是学会自定义属性,这些自定义的属性将让我们配置布局文件的时候更加的灵活.自定义属性是在value目录下声明一个attrs.xml文件. <?xml

Android中自定义下拉样式Spinner

Android中自定义下拉样式Spinner 本文继续介绍android自定义控件系列,自定义Spinner控件的使用. 实现思路 1.定义下拉控件布局(ListView及子控件布局) 2.自定义SpinerPopWindow类 3.定义填充数据的Adapter 效果图 一.定义控件布局 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http:/

android中自定义view涉及到的绘制知识

android中自定义view的过程中,需要了解的绘制知识. 1.画笔paint: 画笔设置: <span style="font-size:14px;"> paint.setAntiAlias(true);//抗锯齿功能 paint.setColor(Color.RED); //设置画笔颜色 paint.setStyle(Style.FILL);//设置填充样式 paint.setStrokeWidth(30);//设置画笔宽度 paint.setShadowLayer(

android中自定义下拉框(转)

android自带的下拉框好用不?我觉得有时候好用,有时候难有,项目规定这样的效果,自带的控件实现不了,那么只有我们自己来老老实实滴写一个新的了,其实最基本的下拉框就像一些资料填写时,点击的时候出现在编辑框的下面,然后又很多选项的下拉框,可是我在网上找了一下,没有这种下拉框额,就自己写了一个,看效果图先: ,这个是资料填写的一部分界面,三个下拉框,选择故乡所在地: 点击之后弹出下拉框,选择下面的选项: 三个下拉框时关联的,第一个决定了第二数据内容,第二个决定了第三个数据内容,如果三个全部选好之后

Android 中自定义软键盘

Android 中自定义软键盘    图一为搜狗输入法.图二为自定义密码键盘.图三为自定义密码键盘 java源文件 package com.keyboarddemo; import android.content.Context; import android.graphics.Paint; import android.graphics.Rect; import android.text.method.PasswordTransformationMethod; import android.u

Android中自定义View的MeasureSpec使用

有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/guide/topics/ui/custom-components.html 一般来说,自定义控件都会去重写View的onMeasure方法,因为该方法指定该控件在屏幕上的大小. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) onMeasure传

Android中自定义ListView无法响应OnItemClickListener中的onItemClick方法问题解决方案

如果你的自定义ListViewItem中有Button或者Checkable的子类控件的话,那么默认focus是交给了子控件,而ListView 的Item能被选中的基础是它能获取Focus,也就是说我们可以通过将ListView中Item中包含的所有控件的focusable属性设置为 false,这样的话ListView的Item自动获得了Focus的权限,也就可以被选中了 我们可以通过对Item Layout的根控件设置其android:descendantFocusability="blo

Android中自定义视图View之---前奏篇

前言 好长时间没写blog了,心里感觉有点空荡荡的,今天有时间就来写一个关于自定义视图的的blog吧.关于这篇blog,网上已经有很多案例了,其实没什么难度的.但是我们在开发的过程中有时候会用到一些自定义的View以达到我们所需要的效果.其实网上的很多案例我们看完之后,发现这部分没什么难度的,我总结了两点: 1.准备纸和笔,计算坐标 2.在onDraw方法中开始画图,invalidate方法刷新,onTouchEvent方法监听触摸事件 对于绘图相关的知识,之前在弄JavaSE相关的知识的时候,

[转]Android中自定义样式与View的构造函数中的第三个参数defStyle的意义

转自:http://www.cnblogs.com/angeldevil/p/3479431.html Android中自定义样式与View的构造函数中的第三个参数defStyle的意义 零.序 一.自定义Style 二.在XML中为属性声明属性值 1. 在layout中定义属性 2. 设置Style 3. 通过Theme指定 三.在运行时获取属性值 1. View的第三个构造函数的第三个参数defStyle 2. obtailStyledAttributes 3. Example 四.结论与代