前一段时间有个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