Android layout - How to implement a fixed/freezed header and column

前端 未结 7 1454
轮回少年
轮回少年 2020-12-24 07:46

I would like to create a table-like view that contains a large number of columns (7-10) while the headers row is always visible (even when scrolling down) and the first colu

相关标签:
7条回答
  • 2020-12-24 08:10

    I found two working examples. http://justsimpleinfo.blogspot.com/2015/04/android-scrolling-table-with-fixed.html

    and

    https://www.codeofaninja.com/2013/08/android-scroll-table-fixed-header-column.html (https://www.youtube.com/watch?v=VCjlcV20ftE). In the second case a warning is shown, so it can be fixed with Android - Expected Resource of type ID.

    A code from the first link.

    MainActivity.java

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            Table table = new Table(this);
            setContentView(table);
        }
    }
    

    Table.java

    public class Table extends LinearLayout {
    
    
     public static final String PREVIOUS_ARROW = "\u2190";
     public static final String NEXT_ARROW = "\u2192";
     public static final  int HEADER_BACKROUND_COLOR = Color.parseColor("#339999");
     public static final  int BODY_BACKROUND_COLOR = Color.parseColor("#99cccc");
     public static String LEFT_BODY_SCROLLVIEW_TAG = "LEFT_BODY_SCROLLVIEW_TAG";
     public static String RIGHT_BODY_SCROLLVIEW_TAG = "RIGHT_BODY_SCROLLVIEW_TAG";
     /**
      * @IS_TWO_COLUMN_HEADER = set this to true if you want two column header with span.
      */
     public static final  boolean IS_TWO_COLUMN_HEADER = true;
    
     LinkedHashMap<Object, Object[]> leftHeaders = new LinkedHashMap<Object, Object[]>();
     LinkedHashMap<Object, Object[]> rightHeaders = new LinkedHashMap<Object, Object[]>();
    
     BodyTable rightTable;
     BodyTable leftTable;
     /**
      * @leftHeaderChildrenWidht = value will be set on adjust header width to match in screen width
      */
     Integer[] leftHeaderChildrenWidth ;
     /**
      * rightHeaderChildrenWidht = value will be set on adjust header width to match in screen width
      */
     Integer[] rightHeaderChildrenWidht ;
    
    
     LoadingDialog loadingDialog;
    
     public Table(Context context) {
      super(context);
    
      this.headers();
      this.properties();
      this.init();
    
      this.resizeFirstLvlHeaderHeight();
      this.resizeSecondLvlHeaderHeight();
      this.resizeHeaderSecondLvlWidhtToMatchInScreen();
    
      this.leftTable.setHeaderChildrenWidth(this.leftHeaderChildrenWidth);
      this.rightTable.setHeaderChildrenWidth(this.rightHeaderChildrenWidht);
    
    
      this.createTestData();
      this.loadData();
    
    
     }
    
     public final static String NAME = "Name";
     public final static String GENDER = "Gender";
     public final static String TICKET_SET_SEQUENCE = "Set Sequence";
     public final static String TICKET_NUMBER = "Ticket Number";
     public final static String TICKET_VALID_UNTIL = "    Valid Until    ";
     public final static String COUNTRY_FROM = "  Country From  ";
     public final static String COUNTRY_TO = "  Country To  ";
     public void headers(){
      leftHeaders.put("Passenger Info", new String[]{NAME,GENDER});
      rightHeaders.put("Ticket Info", new String[]{TICKET_VALID_UNTIL,TICKET_NUMBER,TICKET_SET_SEQUENCE});
      rightHeaders.put("Country Info", new String[]{COUNTRY_FROM,COUNTRY_TO});
    
     }
    
    
     List<Passenger> testData = new ArrayList<Table.Passenger>();
     List<Passenger> dataToBeLoad = new ArrayList<Table.Passenger>();
     int pagination = 20;
     int totalPage = 0;
     int pageNumber = 1;
    
     public void loadData() {
    
    
    
      // TODO Auto-generated method stub
      this.dataToBeLoad = this.getDataToBeLoad();
    
      leftTable.loadData(dataToBeLoad);
      rightTable.loadData(dataToBeLoad);
    
    
      this.resizeBodyChildrenHeight();
    
     }
    
     private void createTestData(){
      for(int x = 0 ; x < 102; x++){
       Passenger passenger = new Passenger();
       passenger.name = "Passenger "+x;
       passenger.gender = x%2 == 0 ? 'F':'M';
       passenger.ticketNum = x;
       passenger.setSequence = "Set "+x;
       passenger.validUntil = "May 01, 2015";
       passenger.countryFrom = "Country "+x;
       passenger.countryTo = x%2 == 0 ? "Philippines" :"Country "+x;
    
       testData.add(passenger);
      }
    
      this.totalPage = this.totalPage(testData, pagination);
      /*this.dataToBeLoad = this.getDataToBeLoad();*/
     }
     private List<Passenger> getDataToBeLoad(){
      List<Passenger> passengers = new ArrayList<Table.Passenger>();
      int startingIndex = (pageNumber -1) * pagination;
    
      int totalPassenger = testData.size();
      //dataToBeLoad.clear();
    
      for(int x = 0 ; x < pagination ; x++){
    
       int index = startingIndex + x;
    
       if(index < totalPassenger){
    
        passengers.add(testData.get(index));
    
       }else{
        Log.e("no data","no data");
       }
    
      }
    
    
    
      return passengers;
     }
     private int totalPage(List<Passenger> testData,int pagination){
    
      int totalPage = testData.size() / pagination;
      totalPage = totalPage + (testData.size() % 20 == 0 ? 0 : 1);
    
      return totalPage;
    
     }
     private void properties(){ 
      this.setBackgroundColor(Color.WHITE);
      this.setOrientation(LinearLayout.HORIZONTAL);
     }
    
     private void init(){
    
      this.loadingDialog = new LoadingDialog(this.getContext());
      this.rightTable = new BodyTable(this.getContext(),this, rightHeaders, RIGHT_BODY_SCROLLVIEW_TAG);
      this.leftTable = new BodyTable(this.getContext(),this,leftHeaders, LEFT_BODY_SCROLLVIEW_TAG);
    
    
    
      this.addView(this.leftTable);
      this.addView(this.rightTable);
     }
     private void resizeFirstLvlHeaderHeight(){
      int rightHeaderLinearLayoutChildCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      int rightHeaderFirstLvlHeighestHeight = 0;
      int rightHeaderFirstLvlHighestHeightIndex = 0;
    
      for(int x = 0 ; x < rightHeaderLinearLayoutChildCount; x++){
    
       HeaderRow row = (HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x);
    
       int height = ViewSizeUtils.getViewHeight(row.firtLvlLinearLayout);
    
       if(rightHeaderFirstLvlHeighestHeight  <= height){
    
        rightHeaderFirstLvlHeighestHeight = height;
        rightHeaderFirstLvlHighestHeightIndex = x;
       }
      }
    
      int leftHeaderLinearLayoutChildCount = leftTable.headerHorizontalLinearLayout.getChildCount();
    
      int leftHeaderFirstLvlHeighestHeight = 0;
      int leftHeaderFirstLvlHighestHeightIndex = 0;
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount; x++){
    
       HeaderRow row = (HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x);
    
       int height = ViewSizeUtils.getViewHeight(row.firtLvlLinearLayout);
    
       if(leftHeaderFirstLvlHeighestHeight  <= height){
    
        leftHeaderFirstLvlHeighestHeight = height;
        leftHeaderFirstLvlHighestHeightIndex = x;
       }
      }
    
      boolean isHighestHighInLeft = false;
    
    
    
      if(leftHeaderFirstLvlHeighestHeight < rightHeaderFirstLvlHeighestHeight){
       // apply right header height in left and right except for the index in highest height
    
       isHighestHighInLeft = false;
    
    
      }else{
    
       isHighestHighInLeft = true;
    
      }
    
      for(int x = 0 ; x < rightHeaderLinearLayoutChildCount; x++){
    
       LinearLayout firstLvlLinearLayout = ((HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x)).firtLvlLinearLayout;
    
    
       if(isHighestHighInLeft){
    
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,leftHeaderFirstLvlHeighestHeight);
        params.weight = 1;
    
        firstLvlLinearLayout.setLayoutParams(params);
    
       }else{
    
        if(rightHeaderFirstLvlHeighestHeight  != rightHeaderFirstLvlHighestHeightIndex){
         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,rightHeaderFirstLvlHeighestHeight);
         params.weight = 1;
    
         firstLvlLinearLayout.setLayoutParams(params);
    
        }
    
       }
    
    
      }
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount; x++){
    
       LinearLayout firstLvlLinearLayout = ((HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x)).firtLvlLinearLayout;
    
    
       if(isHighestHighInLeft){
    
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,leftHeaderFirstLvlHeighestHeight);
        params.weight = 1;
    
        firstLvlLinearLayout.setLayoutParams(params);
    
       }else{
    
        if(leftHeaderFirstLvlHeighestHeight  != leftHeaderFirstLvlHighestHeightIndex){
         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,rightHeaderFirstLvlHeighestHeight);
         params.weight = 1;
    
         firstLvlLinearLayout.setLayoutParams(params);
    
        }
    
       }
    
    
      }
    
     }
    
     private void resizeSecondLvlHeaderHeight(){
      int rightHeaderLinearLayoutChildCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      int rightHeaderFirstLvlHeighestHeight = 0;
      int rightHeaderFirstLvlHighestHeightIndex = 0;
    
      for(int x = 0 ; x < rightHeaderLinearLayoutChildCount; x++){
    
       HeaderRow row = (HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x);
    
       int height = ViewSizeUtils.getViewHeight(row.secondLvlLinearLayout);
    
       if(rightHeaderFirstLvlHeighestHeight  <= height){
    
        rightHeaderFirstLvlHeighestHeight = height;
        rightHeaderFirstLvlHighestHeightIndex = x;
       }
      }
    
      int leftHeaderLinearLayoutChildCount = leftTable.headerHorizontalLinearLayout.getChildCount();
    
      int leftHeaderFirstLvlHeighestHeight = 0;
      int leftHeaderFirstLvlHighestHeightIndex = 0;
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount; x++){
    
       HeaderRow row = (HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x);
    
       int height = ViewSizeUtils.getViewHeight(row.secondLvlLinearLayout);
    
       if(leftHeaderFirstLvlHeighestHeight  <= height){
    
        leftHeaderFirstLvlHeighestHeight = height;
        leftHeaderFirstLvlHighestHeightIndex = x;
       }
      }
    
      boolean isHighestHighInLeft = false;
    
    
    
      if(leftHeaderFirstLvlHeighestHeight < rightHeaderFirstLvlHeighestHeight){
       // apply right header height in left and right except for the index in highest height
    
       isHighestHighInLeft = false;
    
    
      }else{
    
       isHighestHighInLeft = true;
    
      }
    
    
      for(int x = 0 ; x < rightHeaderLinearLayoutChildCount; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
    
    
       if(isHighestHighInLeft){
    
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,leftHeaderFirstLvlHeighestHeight);
        params.weight = 1;
    
        secondLvlLinearLayout.setLayoutParams(params);
    
       }else{
    
        if(rightHeaderFirstLvlHeighestHeight  != rightHeaderFirstLvlHighestHeightIndex){
         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,rightHeaderFirstLvlHeighestHeight);
         params.weight = 1;
    
         secondLvlLinearLayout.setLayoutParams(params);
    
        }
    
       }
    
    
      }
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
    
    
       if(isHighestHighInLeft){
    
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,leftHeaderFirstLvlHeighestHeight);
        params.weight = 1;
    
        secondLvlLinearLayout.setLayoutParams(params);
    
       }else{
    
        if(leftHeaderFirstLvlHeighestHeight  != leftHeaderFirstLvlHighestHeightIndex){
         LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,rightHeaderFirstLvlHeighestHeight);
         params.weight = 1;
    
         secondLvlLinearLayout.setLayoutParams(params);
    
        }
    
       }
    
    
      }
    
     }
    
     private void resizeHeaderSecondLvlWidhtToMatchInScreen(){
      int screenWidth = ScreenUtils.getScreenWidth(this.getContext());
      int leftHeaderChildrenTotalWidth = this.leftSecondLvlHeaderChildrenTotalWidth();
      int rightHeaderChildrenTotalWidth = this.rightHeaderChildrenTotalWidth();
      int leftHeaderSecondLvlChildrenCount = this.leftSecondLvlHeaderChildrenCount();
      int rightHeaderSecondLvlChildrenCount = this.rightSecondLvlHeaderChildrenCount();
      float availableWidth = screenWidth - (leftHeaderChildrenTotalWidth + rightHeaderChildrenTotalWidth);
    
      if(availableWidth <=0){
       // set the header width
       this.leftHeaderChildrenWidth = this.getLeftHeaderChildrenWidth();
       this.rightHeaderChildrenWidht = this.getRightHeaderChildrenWidth();
    
       return;
      }
    
      int widthForEachHeaderChild = (int) Math.ceil(availableWidth / (leftHeaderSecondLvlChildrenCount + rightHeaderSecondLvlChildrenCount));
    
    
      this.addWidthForEachHeaderLeftAndRightChild(widthForEachHeaderChild);
      // set the header width
      this.leftHeaderChildrenWidth = this.getLeftHeaderChildrenWidth();
      this.rightHeaderChildrenWidht = this.getRightHeaderChildrenWidth();
    
     }
     /**
      * get children count in left header
      * @return
      */
     private int leftSecondLvlHeaderChildrenCount(){
      int totalChildren = 0;
      int leftHeaderLinearLayoutChildCount = leftTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount ; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
       totalChildren += secondLvlLinearLayout.getChildCount();
    
    
      }
    
      return totalChildren;
     }
     /**
      * get children count in right header
      * @return
      */
     private int rightSecondLvlHeaderChildrenCount(){
      int totalChildren = 0;
      int leftHeaderLinearLayoutChildCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount ; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
       totalChildren += secondLvlLinearLayout.getChildCount();
    
    
      }
    
      return totalChildren;
     }
     /**
      * Compute total header width in left header
      * @return
      */
     private int leftSecondLvlHeaderChildrenTotalWidth(){
      int totalWidth = 0;
      int leftHeaderLinearLayoutChildCount = leftTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount ; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
       int leftColumnChildrenCount = secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < leftColumnChildrenCount ; y++){
        View view  = secondLvlLinearLayout.getChildAt(y);
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view) : params.width;
    
        totalWidth += width;
    
       }
    
      }
    
      return totalWidth;
     }
     /**
      * Compute total right header children width
      * @return
      */
     private int rightHeaderChildrenTotalWidth(){
      int totalWidth = 0;
      int leftHeaderLinearLayoutChildCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < leftHeaderLinearLayoutChildCount ; x++){
    
       LinearLayout secondLvlLinearLayout = ((HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x)).secondLvlLinearLayout;
       int leftColumnChildrenCount = secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < leftColumnChildrenCount ; y++){
        View view  = secondLvlLinearLayout.getChildAt(y);
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view) : params.width;
    
        totalWidth += width;
    
       }
    
      }
    
      return totalWidth;
     }
     /**
      * Add width in left and right children width if needed to match screen width.
      * @param widthToBeAdded
      */
     private void addWidthForEachHeaderLeftAndRightChild(int widthToBeAdded){
    
      int leftHeaderColumnCount = leftTable.headerHorizontalLinearLayout.getChildCount();
      int rightHeaderColumnCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < leftHeaderColumnCount ; x++){
    
       HeaderRow tableRow =  (HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x);
       int headerRowChildCount = tableRow.secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < headerRowChildCount ; y++){
    
        View view = tableRow.secondLvlLinearLayout.getChildAt(y);
    
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view) + widthToBeAdded : params.width +widthToBeAdded;
        params.width = width;
       }
    
    
      }
    
      for(int x = 0 ; x < rightHeaderColumnCount ; x++){
    
       HeaderRow tableRow =  (HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x);
       int headerRowChildCount = tableRow.secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < headerRowChildCount ; y++){
    
        View view = tableRow.secondLvlLinearLayout.getChildAt(y);
    
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view) + widthToBeAdded : params.width +widthToBeAdded;
        params.width = width;
       }
    
    
      }
    
     }
     /**
      * Get each width of left header child
      * @return
      */
     private Integer[] getLeftHeaderChildrenWidth(){
    
      List<Integer> headerChildrenWidth = new ArrayList<Integer>();
    
      int leftHeaderColumnCount = leftTable.headerHorizontalLinearLayout.getChildCount();
    
    
      for(int x = 0 ; x < leftHeaderColumnCount ; x++){
    
       HeaderRow tableRow =  (HeaderRow) leftTable.headerHorizontalLinearLayout.getChildAt(x);
       int headerRowChildCount = tableRow.secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < headerRowChildCount ; y++){
    
        View view = tableRow.secondLvlLinearLayout.getChildAt(y);
    
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view): params.width ;
    
        headerChildrenWidth.add(width);
    
       }
    
    
      }
    
    
      return headerChildrenWidth.toArray(new Integer[headerChildrenWidth.size()]);
     }
     /**
      * Get each width of right header child
      * @return
      */
     private Integer[] getRightHeaderChildrenWidth(){
    
      List<Integer> headerChildrenWidth = new ArrayList<Integer>();
    
      int rightHeaderColumnCount = rightTable.headerHorizontalLinearLayout.getChildCount();
    
      for(int x = 0 ; x < rightHeaderColumnCount ; x++){
    
       HeaderRow tableRow =  (HeaderRow) rightTable.headerHorizontalLinearLayout.getChildAt(x);
       int headerRowChildCount = tableRow.secondLvlLinearLayout.getChildCount();
    
       for(int y = 0 ; y < headerRowChildCount ; y++){
    
        View view = tableRow.secondLvlLinearLayout.getChildAt(y);
    
        LinearLayout.LayoutParams params = (LayoutParams) view.getLayoutParams();
    
        int width = params.width <=0 ? ViewSizeUtils.getViewWidth(view) : params.width ;
    
        headerChildrenWidth.add(width);
       }
    
    
      }
    
      return headerChildrenWidth.toArray(new Integer[headerChildrenWidth.size()]);
     }
     /**
      * Resize each body column to match each other
      */
     private  void resizeBodyChildrenHeight(){
    
      int leftHeaderFirstLvlHighestHeight = 0;
    
    
      for(LinearLayout lin : leftTable.bodyLinearLayoutTempMem){
    
       int childCount = lin.getChildCount();
    
       for(int x = 0 ; x < childCount; x++){
        int width = ViewSizeUtils.getViewHeight(lin.getChildAt(x));
        if(leftHeaderFirstLvlHighestHeight < width){
         leftHeaderFirstLvlHighestHeight = width;
    
        }
       }
    
    
      }
    
      int rightHeaderFirstLvlHighestHeight = 0;
      //int rightHeaderFirstLvlHighestHeightIndex = 0;
      for(LinearLayout lin : rightTable.bodyLinearLayoutTempMem){
    
       int childCount = lin.getChildCount();
    
       for(int x = 0 ; x < childCount; x++){
        int width = ViewSizeUtils.getViewHeight(lin.getChildAt(x));
        if(rightHeaderFirstLvlHighestHeight < width){
         rightHeaderFirstLvlHighestHeight = width;
         //rightHeaderFirstLvlHighestHeightIndex = x;
        }
       }
    
    
      }
    
      boolean isHighestHighInLeft = leftHeaderFirstLvlHighestHeight > rightHeaderFirstLvlHighestHeight;
    
    
      for(LinearLayout lin : leftTable.bodyLinearLayoutTempMem){
    
       int childCount = lin.getChildCount();
    
       for(int x = 0 ; x < childCount; x++){
        LinearLayout.LayoutParams params = (LayoutParams) lin.getChildAt(x).getLayoutParams();
        params.height = isHighestHighInLeft ? leftHeaderFirstLvlHighestHeight : rightHeaderFirstLvlHighestHeight;
    
       }
    
    
      }
    
      for(LinearLayout lin : rightTable.bodyLinearLayoutTempMem){
    
       int childCount = lin.getChildCount();
    
       for(int x = 0 ; x < childCount; x++){
        LinearLayout.LayoutParams params = (LayoutParams) lin.getChildAt(x).getLayoutParams();
        params.height = isHighestHighInLeft ? leftHeaderFirstLvlHighestHeight : rightHeaderFirstLvlHighestHeight;
    
       }
    
    
      }
    
     }
     /**
      * 
      * @author lau
      *
      */
     class LoadingDialog extends Dialog{
    
       LoadingDialog(Context context) {
       super(context);
       this.setCancelable(false);
       this.requestWindowFeature(Window.FEATURE_NO_TITLE);
       this.init(context);
      }
    
       private void init(Context context){
        TextView textView = new TextView(context);
        textView.setText("Please wait loading data..");
    
        this.setContentView(textView);
    
       }
     }
     class Passenger{
      String name;
      char gender;
      int ticketNum;
      String validUntil;
      String setSequence;
      String countryFrom;
      String countryTo;
     }
    }
    

    And so on, sorry, an answer is limited to 30 000 characters.

    0 讨论(0)
  • 2020-12-24 08:20

    github link

    Recently I came across a situation where I need first two row & first column freeze. I got this library I modified it according to my requirement & fixed some bugs. Now work smoothly.

    0 讨论(0)
  • 2020-12-24 08:23

    I would go with TableLayout populated by TableRow's.

    The following code demonstrates how to achieve that.

    package com.test;
    
    import android.app.Activity;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.view.Gravity;
    import android.widget.TableLayout;
    import android.widget.TableRow;
    import android.widget.TableRow.LayoutParams;
    import android.widget.TextView;
    
    public class TableLayoutTest extends Activity {
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.table_layout);
    
            TableRow.LayoutParams wrapWrapTableRowParams = new TableRow.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
            int[] fixedColumnWidths = new int[]{20, 20, 20, 20, 20};
            int[] scrollableColumnWidths = new int[]{20, 20, 20, 30, 30};
            int fixedRowHeight = 50;
            int fixedHeaderHeight = 60;
    
            TableRow row = new TableRow(this);
            //header (fixed vertically)
            TableLayout header = (TableLayout) findViewById(R.id.table_header);
            row.setLayoutParams(wrapWrapTableRowParams);
            row.setGravity(Gravity.CENTER);
            row.setBackgroundColor(Color.YELLOW);
            row.addView(makeTableRowWithText("col 1", fixedColumnWidths[0], fixedHeaderHeight));
            row.addView(makeTableRowWithText("col 2", fixedColumnWidths[1], fixedHeaderHeight));
            row.addView(makeTableRowWithText("col 3", fixedColumnWidths[2], fixedHeaderHeight));
            row.addView(makeTableRowWithText("col 4", fixedColumnWidths[3], fixedHeaderHeight));
            row.addView(makeTableRowWithText("col 5", fixedColumnWidths[4], fixedHeaderHeight));
            header.addView(row);
            //header (fixed horizontally)
            TableLayout fixedColumn = (TableLayout) findViewById(R.id.fixed_column);
            //rest of the table (within a scroll view)
            TableLayout scrollablePart = (TableLayout) findViewById(R.id.scrollable_part);
            for(int i = 0; i < 10; i++) {
                TextView fixedView = makeTableRowWithText("row number " + i, scrollableColumnWidths[0], fixedRowHeight);
                fixedView.setBackgroundColor(Color.BLUE);
                fixedColumn.addView(fixedView);
                row = new TableRow(this);
                row.setLayoutParams(wrapWrapTableRowParams);
                row.setGravity(Gravity.CENTER);
                row.setBackgroundColor(Color.WHITE);
                row.addView(makeTableRowWithText("value 2", scrollableColumnWidths[1], fixedRowHeight));
                row.addView(makeTableRowWithText("value 3", scrollableColumnWidths[2], fixedRowHeight));
                row.addView(makeTableRowWithText("value 4", scrollableColumnWidths[3], fixedRowHeight));
                row.addView(makeTableRowWithText("value 5", scrollableColumnWidths[4], fixedRowHeight));
                scrollablePart.addView(row);
            }
    
        }
    
    
        //util method
        private TextView recyclableTextView;
    
        public TextView makeTableRowWithText(String text, int widthInPercentOfScreenWidth, int fixedHeightInPixels) {
            int screenWidth = getResources().getDisplayMetrics().widthPixels;
            recyclableTextView = new TextView(this);
            recyclableTextView.setText(text);
            recyclableTextView.setTextColor(Color.BLACK);
            recyclableTextView.setTextSize(20);
            recyclableTextView.setWidth(widthInPercentOfScreenWidth * screenWidth / 100);
            recyclableTextView.setHeight(fixedHeightInPixels);
            return recyclableTextView;
        }
    
    }
    

    Header is the part that doesn't scroll vertically; that's the reason you need to set fixed width on columns. As of the first column that you don't want to scroll, you'll have to set a fixed height on rows for that purpose.

    Here's the layout XML

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:gravity="center_horizontal"
        android:id="@+id/fillable_area">
        <TableLayout
            android:id="@+id/table_header"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"/>
        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <LinearLayout android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:gravity="center_horizontal"
                android:id="@+id/fillable_area">
                <TableLayout
                    android:id="@+id/fixed_column"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"/>
                <HorizontalScrollView
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content">
                    <TableLayout
                        android:id="@+id/scrollable_part"
                        android:layout_width="fill_parent"
                        android:layout_height="fill_parent"/>
                </HorizontalScrollView>
            </LinearLayout>
        </ScrollView>
    </LinearLayout>
    

    And the output looks like this when just loaded

    enter image description here

    and like this when scrolled to the right and to the bottom

    enter image description here

    0 讨论(0)
  • 2020-12-24 08:29

    Create TableLayout that will be a header and under it place a Table itself within a ScrollView like this:

    <TableLayout
            android:id="@+id/tbl_header"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:divider="@drawable/table_divider"
            android:showDividers="middle"
            android:background="@drawable/table_header_backdround"
            />
    
        <ScrollView android:layout_width="fill_parent"
                    android:layout_height="wrap_content">
            <TableLayout
                    android:id="@+id/tbl_relesed_wake_locks"
                    android:orientation="horizontal"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:divider="@drawable/table_divider"
                    android:showDividers="middle"
                    android:stretchColumns="1,2"
                    android:background="@drawable/table_backdround"
    
                    />
        </ScrollView>
    

    When you will populate your header with data add next code:

    table.post(new Runnable() {
            @Override
            public void run() {
                TableRow tableRow = (TableRow)table.getChildAt(0);
                for(int i = 0; i < headerRow.getChildCount(); i++){
                    headerRow.getChildAt(i).setLayoutParams(new TableRow.LayoutParams(tableRow.getChildAt(i).getMeasuredWidth(), tableRow.getChildAt(i).getMeasuredHeight()));
                }
            }
        });
    

    That's it.

    0 讨论(0)
  • 2020-12-24 08:30

    If wanna fix first column, you can try the following layout:

    <TableLayout
        android:id="@+id/tbl_header"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:background="@drawable/cell_shape_header"
        android:divider="?android:dividerHorizontal"
        android:orientation="horizontal"
        android:showDividers="middle">
    
        <TableRow
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="0.5dp">
    
            <TextView
                style="@style/TextViewStyle"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Fragment A" />
    
        </TableRow>
    
        <TableRow
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="0.5dp">
    
            <TextView
                style="@style/TextViewStyle"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Fragment A" />
    
        </TableRow>
    
        <TableRow
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="0.5dp">
    
            <TextView
                style="@style/TextViewStyle"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="Fragment A" />
    
        </TableRow>
    </TableLayout>
    
    <HorizontalScrollView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@+id/tbl_header">
    
        <TableLayout
            android:id="@+id/tbl_relesed_wake_locks"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/cell_shape_header"
            android:divider="?android:dividerHorizontal"
            android:orientation="horizontal"
            android:showDividers="middle"
            android:stretchColumns="1,2">
    
            <TableRow
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="0.5dp">
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
            </TableRow>
    
            <TableRow
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="0.5dp">
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
            </TableRow>
    
            <TableRow
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="0.5dp">
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
                <TextView
                    style="@style/TextViewStyle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="Fragment 01" />
    
            </TableRow>
        </TableLayout>
    </HorizontalScrollView>
    
    0 讨论(0)
  • 2020-12-24 08:33

    You can check this library that I made: https://github.com/InQBarna/TableFixHeaders

    I think that it implements the widget you're looking for.

    0 讨论(0)
提交回复
热议问题