Android ListView刷新单行

Thy*_*hys 76 performance android listview

在获得单行a的数据后ListView,我想更新该行.

目前我正在使用,notifyDataSetChanged();但这使得View反应非常缓慢.还有其他解决方案吗?

Gri*_*nRL 88

正如Romain Guy 在Google I/O会话期间解释的那样,仅在列表视图中更新一个视图的最有效方法是如下(此更新整个视图数据):

ListView list = getListView();
int start = list.getFirstVisiblePosition();
for(int i=start, j=list.getLastVisiblePosition();i<=j;i++)
    if(target==list.getItemAtPosition(i)){
        View view = list.getChildAt(i-start);
        list.getAdapter().getView(i, view, list);
        break;
    }
Run Code Online (Sandbox Code Playgroud)

假设target是适配器的一个项目.

此代码检索ListView,然后浏览当前显示的视图,将target您要查找的项目与每个显示的视图项目进行比较,如果您的目标位于其中,请获取封闭视图并getView在该视图上执行适配器以刷新显示.

由于旁注invalidate不像某些人期望的那样工作,并且不会像getView那样刷新视图,因此notifyDataSetChanged会重建整个列表并最终调用getview每个显示的项目,并且invalidateViews还会影响一堆.

最后一件事,如果他只需要改变行视图的子节点而不是整个行,就可以获得额外的性能getView.在这种情况下,可以替换以下代码list.getAdapter().getView(i, view, list);(例如更改TextView文本):

((TextView)view.findViewById(R.id.myid)).setText("some new text");
Run Code Online (Sandbox Code Playgroud)

在我们信任的代码中.

  • 你应该只是链接你的其他答案http://stackoverflow.com/a/9987616/1026132,而不是在这里复制和粘贴.这有助于减少SO中重复内容的数量. (16认同)
  • 如何用不同的视图类型实现这个? (2认同)

Dan*_*kov 30

一种选择是ListView直接操纵.首先检查更新行的索引是否在getFirstVisiblePosition()和之间getLastVisiblePosition(),这两个给出了适配器中屏幕上可见的第一个和最后一个位置.然后你就可以得到该行ViewgetChildAt(int index)和改变它.

  • 谢谢.如果我**编辑**当前孩子的布局,这将有效.但是,如果我想**完全改变布局**(通过膨胀不同的xml)怎么办?如果我在适配器上调用`newView(...)`,它会给我一个不同的视图,但不会放在`listView`中. (3认同)

Joh*_*war 27

这个更简单的方法对我很有用,你只需知道位置索引就可以得到视图:

// mListView is an instance variable

private void updateItemAtPosition(int position) {
    int visiblePosition = mListView.getFirstVisiblePosition();
    View view = mListView.getChildAt(position - visiblePosition);
    mListView.getAdapter().getView(position, view, mListView);
}
Run Code Online (Sandbox Code Playgroud)

  • 像魅力一样,+1 (2认同)

Sko*_*Guy 6

以下代码对我有用.请注意,在调用GetChild()时,您必须通过列表中的第一项来抵消它,因为它相对于该项.

int iFirst = getFirstVisiblePosition();
int iLast = getLastVisiblePosition();

if ( indexToChange >= numberOfRowsInSection() ) {
    Log.i( "MyApp", "Invalid index. Row Count = " + numberOfRowsInSection() );
}
else {      
    if ( ( index >= iFirst ) && ( index <= iLast ) ) {
        // get the view at the position being updated - need to adjust index based on first in the list
        View vw = getChildAt( sysvar_index - iFirst );
        if ( null != vw ) {
            // get the text view for the view
            TextView tv = (TextView) vw.findViewById(com.android.myapp.R.id.scrollingListRowTextView );
            if ( tv != null ) {
                // update the text, invalidation seems to be automatic
                tv.setText( "Item = " + myAppGetItem( index ) + ". Index = " + index + ". First = " + iFirst + ". Last = " + iLast );
            }
        }
    }
}  
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

60553 次

最近记录:

9 年,5 月 前