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);
	}

表格上並未顯示錶頭 其實這個也能畫出來,或者用佈局拼湊也是可以的。

今天就到這裏,有問題請指出,謝謝。




發佈了64 篇原創文章 · 獲贊 5 · 訪問量 32萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章