如何在第一列固定的情况下显示水平和垂直滚动的表格?

时间:2015-04-22 07:11:09

标签: android android-layout android-linearlayout android-tablelayout

我希望有一个类似于结构的表,其中包含标题行和数据行。 第一列应该是固定的,而其他列应该是水平可滚动的。类似地,数据行也应该是垂直可滚动的。如何在android中实现这一点。我应该采取哪种方法

2 个答案:

答案 0 :(得分:0)

尝试创建两个表,一个用于将要修复的列,另一个表包含可以使用scollview标记滚动的其余数据。

答案 1 :(得分:0)

我通过以下链接中的代码帮助完成了这项工作 https://www.codeofaninja.com/2013/08/android-scroll-table-fixed-header-column.html

package com.Table;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class TableMainLayout extends RelativeLayout {

	public final String TAG = "TableMainLayout.java";

	// set the header titles
	String headers[] = { "Header 1 \n multi-lines", "Header 2", "Header 3",
			"Header 4", "Header 5", "Header 6", "Header 7", "Header 8",
			"Header 9", "Header 10", "Header 11", "Header 12", "Header 13",
			"Header 14",

	};

	TableLayout tableA;
	TableLayout tableB;
	TableLayout tableC;
	TableLayout tableD;

	HorizontalScrollView horizontalScrollViewB;
	HorizontalScrollView horizontalScrollViewD;

	ScrollView scrollViewC;
	ScrollView scrollViewD;

	Context context;

	List<SampleObject> sampleObjects = this.sampleObjects();

	int headerCellsWidth[] = new int[headers.length];

	int screenWidthDp, screenHeightDp;

	public TableMainLayout(Context context) {

		super(context);

		this.context = context;

		// initialize the main components (TableLayouts, HorizontalScrollView,
		// ScrollView)
		this.initComponents();
		this.setComponentsId();
		this.setScrollViewAndHorizontalScrollViewTag();

		Configuration configuration = this.getResources().getConfiguration();
		screenWidthDp = configuration.screenWidthDp; // The current width of
														// the available
														// screen space, in
														// dp units,
														// corresponding to
														// screen width
														// resource
														// qualifier.
		screenHeightDp = configuration.screenHeightDp;

		// no need to assemble component A, since it is just a table
		this.horizontalScrollViewB.addView(this.tableB);

		this.scrollViewC.addView(this.tableC);

		this.scrollViewD.addView(this.horizontalScrollViewD);
		this.horizontalScrollViewD.addView(this.tableD);

		// add the components to be part of the main layout
		this.addComponentToMainLayout();

		// add some table rows
		this.addTableRowToTableA();
		this.addTableRowToTableB();

		this.resizeHeaderHeight();

		this.getTableRowHeaderCellWidth();

		this.generateTableC_AndTable_B();

		this.resizeBodyTableRowHeight();

	}

	// this is just the sample data
	List<SampleObject> sampleObjects() {

		List<SampleObject> sampleObjects = new ArrayList<SampleObject>();

		for (int x = 1; x <= 25; x++) {

			SampleObject sampleObject = new SampleObject("Col 1, Row " + x,
					"Col 2, Row " + x + " - multi-lines", "Col 3, Row " + x,
					"Col 4, Row " + x, "Col 5, Row " + x, "Col 6, Row " + x,
					"Col 7, Row " + x, "Col 8, Row " + x, "Col 9, Row " + x,
					"Col 10, Row " + x, "Col 11, Row " + x, "Col 12, Row " + x,
					"Col 13, Row " + x, "Col 14, Row " + x

			);

			sampleObjects.add(sampleObject);
		}

		return sampleObjects;

	}

	// initalized components
	private void initComponents() {

		this.tableA = new TableLayout(this.context);
		this.tableB = new TableLayout(this.context);
		this.tableC = new TableLayout(this.context);
		this.tableD = new TableLayout(this.context);

		this.horizontalScrollViewB = new MyHorizontalScrollView(this.context);
		this.horizontalScrollViewD = new MyHorizontalScrollView(this.context);

		this.scrollViewC = new MyScrollView(this.context);
		this.scrollViewD = new MyScrollView(this.context);

		this.tableA.setBackgroundColor(Color.GREEN);
		this.horizontalScrollViewB.setBackgroundColor(Color.LTGRAY);

	}

	// set essential component IDs
	private void setComponentsId() {
		this.tableA.setId(1);
		this.horizontalScrollViewB.setId(2);
		this.scrollViewC.setId(3);
		this.scrollViewD.setId(4);
	}

	// set tags for some horizontal and vertical scroll view
	private void setScrollViewAndHorizontalScrollViewTag() {

		this.horizontalScrollViewB.setTag("horizontal scroll view b");
		this.horizontalScrollViewD.setTag("horizontal scroll view d");

		this.scrollViewC.setTag("scroll view c");
		this.scrollViewD.setTag("scroll view d");
	}

	// we add the components here in our TableMainLayout
	private void addComponentToMainLayout() {

		// RelativeLayout params were very useful here
		// the addRule method is the key to arrange the components properly
		RelativeLayout.LayoutParams componentB_Params = new RelativeLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		componentB_Params.addRule(RelativeLayout.RIGHT_OF, this.tableA.getId());

		RelativeLayout.LayoutParams componentC_Params = new RelativeLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		componentC_Params.addRule(RelativeLayout.BELOW, this.tableA.getId());

		RelativeLayout.LayoutParams componentD_Params = new RelativeLayout.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
		componentD_Params.addRule(RelativeLayout.RIGHT_OF,
				this.scrollViewC.getId());
		componentD_Params.addRule(RelativeLayout.BELOW,
				this.horizontalScrollViewB.getId());

		// 'this' is a relative layout,
		// we extend this table layout as relative layout as seen during the
		// creation of this class
		this.addView(this.tableA);
		this.addView(this.horizontalScrollViewB, componentB_Params);
		this.addView(this.scrollViewC, componentC_Params);
		this.addView(this.scrollViewD, componentD_Params);

		tableA.setBackgroundColor(Color.YELLOW);
		horizontalScrollViewB.setBackgroundColor(Color.BLUE);

	}

	private void addTableRowToTableA() {
		this.tableA.addView(this.componentATableRow());
	}

	private void addTableRowToTableB() {
		this.tableB.addView(this.componentBTableRow());
	}

	// generate table row of table A
	TableRow componentATableRow() {

		TableRow componentATableRow = new TableRow(this.context);
		TextView textView = this.headerTextView(this.headers[0]);
		componentATableRow.addView(textView);

		return componentATableRow;
	}

	// generate table row of table B
	TableRow componentBTableRow() {

		TableRow componentBTableRow = new TableRow(this.context);
		int headerFieldCount = this.headers.length;

		TableRow.LayoutParams params = new TableRow.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
		params.setMargins(2, 0, 0, 0);

		for (int x = 0; x < (headerFieldCount - 1); x++) {
			TextView textView = this.headerTextView(this.headers[x + 1]);
			textView.setLayoutParams(params);
			componentBTableRow.addView(textView);
		}

		return componentBTableRow;
	}

	// generate table row of table C and table D
	private void generateTableC_AndTable_B() {

		// just seeing some header cell width
		for (int x = 0; x < this.headerCellsWidth.length; x++) {
			Log.v("TableMainLayout.java", this.headerCellsWidth[x] + "");
		}

		for (SampleObject sampleObject : this.sampleObjects) {

			TableRow tableRowForTableC = this.tableRowForTableC(sampleObject);
			TableRow taleRowForTableD = this.taleRowForTableD(sampleObject);

			tableRowForTableC.setBackgroundColor(Color.LTGRAY);
			taleRowForTableD.setBackgroundColor(Color.LTGRAY);

			this.tableC.addView(tableRowForTableC);
			this.tableD.addView(taleRowForTableD);

		}
	}

	// a TableRow for table C
	TableRow tableRowForTableC(SampleObject sampleObject) {

		TableRow.LayoutParams params = new TableRow.LayoutParams(
				this.headerCellsWidth[0], LayoutParams.MATCH_PARENT);
		params.setMargins(0, 2, 0, 0);

		TableRow tableRowForTableC = new TableRow(this.context);
		TextView textView = this.bodyTextView(sampleObject.header1);
		tableRowForTableC.addView(textView, params);

		return tableRowForTableC;
	}

	TableRow taleRowForTableD(SampleObject sampleObject) {

		TableRow taleRowForTableD = new TableRow(this.context);

		int loopCount = ((TableRow) this.tableB.getChildAt(0)).getChildCount();
		String info[] = { sampleObject.header2, sampleObject.header3,
				sampleObject.header4, sampleObject.header5,
				sampleObject.header6, sampleObject.header7,
				sampleObject.header8, sampleObject.header9,
				sampleObject.header10, sampleObject.header11,
				sampleObject.header12, sampleObject.header13,
				sampleObject.header14

		};

		for (int x = 0; x < loopCount; x++) {
			TableRow.LayoutParams params = new TableRow.LayoutParams(
					headerCellsWidth[x + 1], LayoutParams.MATCH_PARENT);
			params.setMargins(2, 2, 0, 0);

			TextView textViewB = this.bodyTextView(info[x]);
			taleRowForTableD.addView(textViewB, params);
		}

		return taleRowForTableD;

	}

	// table cell standard TextView
	TextView bodyTextView(String label) {

		TextView bodyTextView = new TextView(this.context);
		bodyTextView.setBackgroundColor(Color.WHITE);
		bodyTextView.setText(label);
		bodyTextView.setGravity(Gravity.CENTER);
		bodyTextView.setPadding(5, 5, 5, 5);
		bodyTextView.setWidth(screenWidthDp / 3);
		return bodyTextView;
	}

	// header standard TextView
	TextView headerTextView(String label) {

		TextView headerTextView = new TextView(this.context);
		headerTextView.setBackgroundColor(Color.WHITE);
		headerTextView.setText(label);
		headerTextView.setGravity(Gravity.CENTER);
		headerTextView.setWidth(screenWidthDp / 3);
		headerTextView.setPadding(5, 5, 5, 5);
		return headerTextView;
	}

	// resizing TableRow height starts here
	void resizeHeaderHeight() {

		TableRow productNameHeaderTableRow = (TableRow) this.tableA
				.getChildAt(0);
		TableRow productInfoTableRow = (TableRow) this.tableB.getChildAt(0);

		int rowAHeight = this.viewHeight(productNameHeaderTableRow);
		int rowBHeight = this.viewHeight(productInfoTableRow);

		TableRow tableRow = rowAHeight < rowBHeight ? productNameHeaderTableRow
				: productInfoTableRow;
		int finalHeight = rowAHeight > rowBHeight ? rowAHeight : rowBHeight;

		this.matchLayoutHeight(tableRow, finalHeight);
	}

	void getTableRowHeaderCellWidth() {

		int tableAChildCount = ((TableRow) this.tableA.getChildAt(0))
				.getChildCount();
		int tableBChildCount = ((TableRow) this.tableB.getChildAt(0))
				.getChildCount();

		for (int x = 0; x < (tableAChildCount + tableBChildCount); x++) {

			if (x == 0) {
				this.headerCellsWidth[x] = this
						.viewWidth(((TableRow) this.tableA.getChildAt(0))
								.getChildAt(x));
			} else {
				this.headerCellsWidth[x] = this
						.viewWidth(((TableRow) this.tableB.getChildAt(0))
								.getChildAt(x - 1));
			}

		}
	}

	// resize body table row height
	void resizeBodyTableRowHeight() {

		int tableC_ChildCount = this.tableC.getChildCount();

		for (int x = 0; x < tableC_ChildCount; x++) {

			TableRow productNameHeaderTableRow = (TableRow) this.tableC
					.getChildAt(x);
			TableRow productInfoTableRow = (TableRow) this.tableD.getChildAt(x);

			int rowAHeight = this.viewHeight(productNameHeaderTableRow);
			int rowBHeight = this.viewHeight(productInfoTableRow);

			TableRow tableRow = rowAHeight < rowBHeight ? productNameHeaderTableRow
					: productInfoTableRow;
			int finalHeight = rowAHeight > rowBHeight ? rowAHeight : rowBHeight;

			this.matchLayoutHeight(tableRow, finalHeight);
		}

	}

	// match all height in a table row
	// to make a standard TableRow height
	private void matchLayoutHeight(TableRow tableRow, int height) {

		int tableRowChildCount = tableRow.getChildCount();

		// if a TableRow has only 1 child
		if (tableRow.getChildCount() == 1) {

			View view = tableRow.getChildAt(0);
			TableRow.LayoutParams params = (TableRow.LayoutParams) view
					.getLayoutParams();
			params.height = height - (params.bottomMargin + params.topMargin);

			return;
		}

		// if a TableRow has more than 1 child
		for (int x = 0; x < tableRowChildCount; x++) {

			View view = tableRow.getChildAt(x);

			TableRow.LayoutParams params = (TableRow.LayoutParams) view
					.getLayoutParams();

			if (!isTheHeighestLayout(tableRow, x)) {
				params.height = height
						- (params.bottomMargin + params.topMargin);
				return;
			}
		}

	}

	// check if the view has the highest height in a TableRow
	private boolean isTheHeighestLayout(TableRow tableRow, int layoutPosition) {

		int tableRowChildCount = tableRow.getChildCount();
		int heighestViewPosition = -1;
		int viewHeight = 0;

		for (int x = 0; x < tableRowChildCount; x++) {
			View view = tableRow.getChildAt(x);
			int height = this.viewHeight(view);

			if (viewHeight < height) {
				heighestViewPosition = x;
				viewHeight = height;
			}
		}

		return heighestViewPosition == layoutPosition;
	}

	// read a view's height
	private int viewHeight(View view) {
		view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
		return view.getMeasuredHeight();
	}

	// read a view's width
	private int viewWidth(View view) {
		// view.measure(View.MeasureSpec.UNSPECIFIED,
		// View.MeasureSpec.UNSPECIFIED);
		view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
		return view.getMeasuredWidth();

	}

	// horizontal scroll view custom class
	class MyHorizontalScrollView extends HorizontalScrollView {

		public MyHorizontalScrollView(Context context) {
			super(context);
		}

		@Override
		protected void onScrollChanged(int l, int t, int oldl, int oldt) {
			String tag = (String) this.getTag();

			if (tag.equalsIgnoreCase("horizontal scroll view b")) {
				horizontalScrollViewD.scrollTo(l, 0);
			} else {
				horizontalScrollViewB.scrollTo(l, 0);
			}
		}

	}

	// scroll view custom class
	class MyScrollView extends ScrollView {

		public MyScrollView(Context context) {
			super(context);
		}

		@Override
		protected void onScrollChanged(int l, int t, int oldl, int oldt) {

			String tag = (String) this.getTag();

			if (tag.equalsIgnoreCase("scroll view c")) {
				scrollViewD.scrollTo(0, t);
			} else {
				scrollViewC.scrollTo(0, t);
			}
		}
	}

}

package com.Table;

public class SampleObject {
	
	String header1;
	String header2;
	String header3;
	String header4;
	String header5;
	String header6;
	String header7;
	String header8;
	String header9;
	String header10;
	String header11;
	String header12;
	String header13;
	String header14;
	
	
	
	public SampleObject(String header1, String header2, String header3,
			String header4, String header5, String header6,
			String header7, String header8, String header9,String header10, String header11, String header12,String header13, String header14){
		
		this.header1 = header1;
		this.header2 = header2;
		this.header3 = header3;
		this.header4 = header4;
		this.header5 = header5;
		this.header6 = header6;
		this.header7 = header7;
		this.header8 = header8;
		this.header9 = header9;
		this.header10 = header10;
		this.header11= header11;
		this.header12 = header12;
		this.header13= header13;
		this.header14 = header14;
		
		
		
	}
}