How to identify id of a view for a range of table

2019-07-20 21:28发布

I am working with a table grid built using custom list view with the fixed headers row.
When user clicks on one of the fixed header cells, the whole data table is sorted on that particular column.
I have worked out how to alter the text of the clicked header cell, by adding the ascending or descending arrow to the existing header / column title (see code below).
However, I also need to change the text of all other column header cells in the data table, in order to remove any existing ascending or descending arrows from those other header cells.

The problem I am having is: how to find the view IDs of those other column header cells at runtime.

Please note that it is not possible to find those view IDs by searching for a specific TextView ID from the xml layout, as all table header cells are created using a generic TextView id called text1 (see linear layout code used for the table header below):

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_table1_header"
android:gravity="center"
android:orientation="vertical" >

<TextView
    android:id="@android:id/text1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Below is the getView code used to create the table cells, which also includes the built-in OnClickListener. Note that the fixed table header row is numbered -1.

I would need to add the code to change the text of the existing header cells in the section marked "TODO", once I can identify their existing TextView IDs:

@Override
public View getView(final int row, final int column, View converView, ViewGroup parent) {
    if (converView == null) {
        converView = inflater.inflate(getLayoutResource(row, column), parent, false);
    }
    setText(converView, getCellString(row, column));    
    converView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (row == -1) {        // clicked on header row cell
                for(int col=0; col<=getColumnCount(); col++){
                    if (col == column+1) {  
                      if (getColOrder(col) == 0  ||  getColOrder(col) == 2) {    
                          setText(v, getCellString(row, column) + " ↑");   // reset selected column header to ASC order
                          setColOrder(col, 1);
                      } else {    
                          setText(v, getCellString(row, column) + " ↓");   // reset selected column header to DESC order
                          setColOrder(col, 2);
                      }
                    } else {
                        setColOrder(col, 0);   // reset all other column headers to 0 (not ordered)
                        // TODO:
                        // here we need to change the text of all other header cells, using their view ids
                    }
                }
            } 
        }
    });     

    return converView;
}

2条回答
神经病院院长
2楼-- · 2019-07-20 22:04

I have found a solution to the above issue of assigning, storing and identifying the view ids, in order to update the table header title cells. Here is the updated working code with the solution:

@Override
public View getView(final int row, final int column, View converView, ViewGroup parent) {
    if (converView == null) {
        converView = inflater.inflate(getLayoutResource(row, column), parent, false);
        if (row == -1){
            converView.setId(column+2);         // assign new id to the cell view
            setHeaderId(column);        // store that view id in the header array
        }  
    }
    setText(converView, getCellString(row, column));
    converView.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (row == -1) {        // clicked on header row cell                   
                for(int col=0; col<=getColumnCount(); col++){
                    if (col == column+1) {  // check if col = clicked column
                      if (getColOrder(col) == 0  ||  getColOrder(col) == 2) {    // 0 = not ordered, 1 = +" ↑"  ASC,  2 = +" ↓"  DESC
                          setText(v, getCellString(row, column) + " ↑");   // reset selected column header to ASC order
                          setColOrder(col, 1);
                      } else {    
                          setText(v, getCellString(row, column) + " ↓");   // reset selected column header to DESC order
                          setColOrder(col, 2);
                      }
                    } else {                    
                        int viewId = getHeaderId(col);                              // extract view id from the header array
                        if (viewId > 0) {                                           // to prevent updating header cells with unassigned view Id's
                            ViewGroup parent = (ViewGroup)v.getParent();            // parent = TableFixHeaders
                            View tv = parent.findViewById(viewId);                      
                            setText(tv, getCellString(row, col-1));      // update the header cell text with the original text string (from header text array)
                            setColOrder(col, 0);   // reset all other column headers to 0 (= not ordered)
                        }
                    }
                }

        }
    });     

    return converView;
}
查看更多
你好瞎i
3楼-- · 2019-07-20 22:09

I would make your layout its own custom subclass of View. Keep track of it's original state so you can reset it later. Then add a public reset() function to your new class that replaces the text with whatever the initial value was. Lastly, now you do not need to access the internal properties of your view from your adapter. Instead you can just call reset() on the headers and they will take care of their internal state.

查看更多
登录 后发表回答