如何识别线性布局中一系列表格单元格的视图ID

Posted

技术标签:

【中文标题】如何识别线性布局中一系列表格单元格的视图ID【英文标题】:How to identify id of a view for a range of table cells within linear layout 【发布时间】:2013-02-10 12:11:30 【问题描述】:

我正在使用带有固定标题行的自定义列表视图构建的表格网格。 当用户单击其中一个固定标题单元格时,整个数据表将按该特定列排序。 我已经研究出如何通过将升序或降序箭头添加到现有标题/列标题来更改单击的标题单元格的文本(请参见下面的代码)。 但是,我还需要更改数据表中所有其他列标题单元格的文本,以便从其他标题单元格中删除任何现有的升序或降序箭头。

我遇到的问题是:如何在运行时找到其他列标题单元格的视图 ID。

请注意,无法通过在 xml 布局中搜索特定的 TextView ID 来找到这些视图 ID,因为所有表头单元格都是使用名为 text1 的通用 TextView id 创建的(请参阅用于表格的线性布局代码下面的标题):

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

<TextView
    android:id="@android:id/text1"
    android:layout_
    android:layout_ />

以下是用于创建表格单元格的 getView 代码,其中还包括内置的 OnClickListener。 请注意,固定表标题行编号为 -1。

一旦我可以识别它们现有的 TextView ID,我需要添加代码以更改标记为“TODO”的部分中现有标题单元格的文本:

@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;

【问题讨论】:

【参考方案1】:

我会让你的布局成为 View 的自定义子类。跟踪它的原始状态,以便您以后可以重置它。然后向您的新类添加一个公共 reset() 函数,该函数将文本替换为初始值。最后,现在您不需要从适配器访问视图的内部属性。相反,您只需在标头上调用 reset() ,它们就会处理它们的内部状态。

【讨论】:

我正在使用特殊的小部件 [github.com/InQBarna/TableFixHeaders],它将标题视图的创建与表格主体单元格视图的创建紧密集成在一起。使用 reset() 将需要替换所有表格单元格的文本,这将是非常昂贵的性能明智。我唯一的选择似乎是找到已经创建的标题单元格范围的 TextView id,然后我可以用原始标题字符串替换它们的文本。任何其他如何以编程方式执行此操作的想法将不胜感激。【参考方案2】:

我找到了解决上述分配、存储和识别视图 ID 问题的方法,以便更新表头标题单元格。 这是解决方案的更新工作代码:

@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;

【讨论】:

以上是关于如何识别线性布局中一系列表格单元格的视图ID的主要内容,如果未能解决你的问题,请参考以下文章

列表视图滚动时在屏幕底部隐藏线性布局

使用自动布局约束动态调整表格视图单元格的大小

如何在不丢失表格视图单元格的情况下将现有集合视图添加到表格视图

如何在自动布局中滑动表格视图单元格?

在 Swift 中,当方向发生时如何更改表格单元格布局?

设置表格视图单元格的动态高度