ListView 非常滞后 - Android

发布于 2024-12-29 21:24:54 字数 8546 浏览 2 评论 0原文

我创建了一个自定义 ListView。我尝试优化 ListView 适配器的 getView 方法,但仍然遇到延迟。

我在适配器中做错了什么导致我的 ListView 滞后?

或者,如果看起来不错,那么是什么原因导致了延迟?

ListView 中一行的 xml 是:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:background="@color/all_white"
android:orientation="vertical">
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="6dip"
    android:background="@color/all_white"
    android:gravity="center">
   <TextView
    android:layout_width="40dip"
    android:layout_height="wrap_content"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip"
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"     
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"     
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"        
    />    
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"        
    />   
</LinearLayout>
</LinearLayout>

我的适配器的代码是:

public class MultiWorkspaceAdapter2 extends BaseAdapter {

/*
 * A map of the workspaces of a user, with key == first letter of the workspace title
 * and value == the list of WorkspaceInfos for that key.
 */
private LinkedHashMap<String, List<WorkspaceInfo>> _workspacesMap;

/*
 * Array of keys in order to get the values in getItem.
 */
private String[] _keys;

private Activity _activity;

public MultiWorkspaceAdapter2(Activity activity, LinkedHashMap<String,     List<WorkspaceInfo>> map) {
    _workspacesMap = map;
    _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
    _activity = activity;
}

public int getCount() {
    return _workspacesMap.size();
}

public Object getItem(int position) {
    _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
    List<WorkspaceInfo> list = new ArrayList<WorkspaceInfo>();
    try {
        if (_keys[position] != null) {
        list = _workspacesMap.get(_keys[position]);
        }
    } catch (ArrayIndexOutOfBoundsException e) {
        list = null;
    }
    return list;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewGroup viewGroup = null;
    int numRows = 0;

    if (convertView != null) {
        viewGroup = (ViewGroup) convertView; 
    } else {
        LayoutInflater inflater = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        viewGroup = (ViewGroup) inflater.inflate(R.layout.multi_workspace_layout, parent, false);

        _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
        List<WorkspaceInfo> workspaces = new ArrayList<WorkspaceInfo>();
        try {
            if (_keys[position] != null) {
                workspaces = _workspacesMap.get(_keys[position]);
                //Collections.sort(workspaces, new InfoNameComparator());
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            //
        }

        numRows = viewGroup.getChildCount();

        //Find how many buttons are in a row.
        int buttonsInRow = ((ViewGroup) viewGroup.getChildAt(0)).getChildCount();

        int totalRows = 0;
        int size = workspaces.size();
        if (size > 0) {
            totalRows = size / buttonsInRow + 1;
        }

        if (numRows < totalRows) {
            for (int i = numRows; i < totalRows; i++) {
                View view;
                LayoutInflater inflater2 = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = (View) inflater2.inflate(R.layout.list_row_multi_ws, viewGroup, false);
                viewGroup.addView(view, i);
            }
        } else if (numRows > totalRows) {
            for (int i = numRows; i > totalRows; i--) {
                viewGroup.removeViewAt(totalRows);
            }
        }

        //Iterate over workspaces
        Iterator<WorkspaceInfo> iterator = workspaces.iterator();
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            //Linear layout child containing buttons and textview.
            ViewGroup temp = (ViewGroup) viewGroup.getChildAt(i);
            for (int j = 0; j < temp.getChildCount(); j++) {
                if (j == 0) {
                    //The letter these workspaces start with
                    TextView textview = (TextView) temp.getChildAt(j);
                    String letter = _keys[position];
                    textview.setText(_keys[position]);
                    if (i != 0 && temp.getId() != R.id.workspaces_portrait) {
                        textview.setVisibility(View.INVISIBLE);
                    } else if (i != 0) {
                        textview.setVisibility(View.GONE);
                    }
                } else {
                    //A workspace button
                    Button button = (Button) temp.getChildAt(j);
                    if (iterator.hasNext()) {
                        //Get the next workspace
                        final WorkspaceInfo workspace = iterator.next();
                        //Get the title of the workspace and set as text.
                        String buttonText = workspace.getTitle();
                        button.setText(buttonText);
                        button.setVisibility(View.VISIBLE);
                        //Add OnClickListener
                        button.setOnClickListener(new OnClickListener() {
                            public void onClick(View v) {
                                //If the workspace is pending,  handle the invitation.
                                if (workspace.getStatus() == StaticFields.PENDING_WORKSPACE) {
                                    ((SkootWorkspacesActivity) _activity).handleInvitation(workspace);
                                } else {
                                    //open the workspace
                                    ((SkootWorkspacesActivity) _activity).openWorkspace(workspace);
                                }
                            }
                          });
                        button.setOnLongClickListener(new OnLongClickListener() {
                            public boolean onLongClick(View v) {
                                ((SkootWorkspacesActivity) _activity).makeDeleteDialog(workspace);
                                return true;
                            }
                          });
                    } else {
                        button.setVisibility(View.GONE);
                    }
                }
            }
        }

    }
    return viewGroup;
}

我将此适配器添加到 MergeAdapter 并使用 MergeAdapter 在 ListView 上执行 setAdapter。

谢谢

I've created a custom ListView. I've tried to optimize the getView method of my ListView's Adapter but I'm still experiencing lag.

What am I doing wrong in the Adapter that causes my ListView to lag?

Or if it looks good, what could be causing the lag?

The xml of a row in the ListView is:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="6dip"
android:background="@color/all_white"
android:orientation="vertical">
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="6dip"
    android:background="@color/all_white"
    android:gravity="center">
   <TextView
    android:layout_width="40dip"
    android:layout_height="wrap_content"
    android:paddingTop="10dip"
    android:paddingBottom="10dip"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip"
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"     
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"     
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"        
    />    
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"
    />
<Button
    android:layout_width="197dip"
    android:layout_height="wrap_content"
    android:layout_marginRight="8dip"
    android:paddingTop="10dip"  
    android:paddingBottom="10dip" 
    android:background="@drawable/button_300"
    android:textColor="@color/all_white"        
    />   
</LinearLayout>
</LinearLayout>

The code for my Adapter is:

public class MultiWorkspaceAdapter2 extends BaseAdapter {

/*
 * A map of the workspaces of a user, with key == first letter of the workspace title
 * and value == the list of WorkspaceInfos for that key.
 */
private LinkedHashMap<String, List<WorkspaceInfo>> _workspacesMap;

/*
 * Array of keys in order to get the values in getItem.
 */
private String[] _keys;

private Activity _activity;

public MultiWorkspaceAdapter2(Activity activity, LinkedHashMap<String,     List<WorkspaceInfo>> map) {
    _workspacesMap = map;
    _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
    _activity = activity;
}

public int getCount() {
    return _workspacesMap.size();
}

public Object getItem(int position) {
    _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
    List<WorkspaceInfo> list = new ArrayList<WorkspaceInfo>();
    try {
        if (_keys[position] != null) {
        list = _workspacesMap.get(_keys[position]);
        }
    } catch (ArrayIndexOutOfBoundsException e) {
        list = null;
    }
    return list;
}

public long getItemId(int position) {
    return position;
}

public View getView(int position, View convertView, ViewGroup parent) {
    ViewGroup viewGroup = null;
    int numRows = 0;

    if (convertView != null) {
        viewGroup = (ViewGroup) convertView; 
    } else {
        LayoutInflater inflater = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        viewGroup = (ViewGroup) inflater.inflate(R.layout.multi_workspace_layout, parent, false);

        _keys = (String[]) _workspacesMap.keySet().toArray(new String[_workspacesMap.size()]);
        List<WorkspaceInfo> workspaces = new ArrayList<WorkspaceInfo>();
        try {
            if (_keys[position] != null) {
                workspaces = _workspacesMap.get(_keys[position]);
                //Collections.sort(workspaces, new InfoNameComparator());
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            //
        }

        numRows = viewGroup.getChildCount();

        //Find how many buttons are in a row.
        int buttonsInRow = ((ViewGroup) viewGroup.getChildAt(0)).getChildCount();

        int totalRows = 0;
        int size = workspaces.size();
        if (size > 0) {
            totalRows = size / buttonsInRow + 1;
        }

        if (numRows < totalRows) {
            for (int i = numRows; i < totalRows; i++) {
                View view;
                LayoutInflater inflater2 = (LayoutInflater) _activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = (View) inflater2.inflate(R.layout.list_row_multi_ws, viewGroup, false);
                viewGroup.addView(view, i);
            }
        } else if (numRows > totalRows) {
            for (int i = numRows; i > totalRows; i--) {
                viewGroup.removeViewAt(totalRows);
            }
        }

        //Iterate over workspaces
        Iterator<WorkspaceInfo> iterator = workspaces.iterator();
        for (int i = 0; i < viewGroup.getChildCount(); i++) {
            //Linear layout child containing buttons and textview.
            ViewGroup temp = (ViewGroup) viewGroup.getChildAt(i);
            for (int j = 0; j < temp.getChildCount(); j++) {
                if (j == 0) {
                    //The letter these workspaces start with
                    TextView textview = (TextView) temp.getChildAt(j);
                    String letter = _keys[position];
                    textview.setText(_keys[position]);
                    if (i != 0 && temp.getId() != R.id.workspaces_portrait) {
                        textview.setVisibility(View.INVISIBLE);
                    } else if (i != 0) {
                        textview.setVisibility(View.GONE);
                    }
                } else {
                    //A workspace button
                    Button button = (Button) temp.getChildAt(j);
                    if (iterator.hasNext()) {
                        //Get the next workspace
                        final WorkspaceInfo workspace = iterator.next();
                        //Get the title of the workspace and set as text.
                        String buttonText = workspace.getTitle();
                        button.setText(buttonText);
                        button.setVisibility(View.VISIBLE);
                        //Add OnClickListener
                        button.setOnClickListener(new OnClickListener() {
                            public void onClick(View v) {
                                //If the workspace is pending,  handle the invitation.
                                if (workspace.getStatus() == StaticFields.PENDING_WORKSPACE) {
                                    ((SkootWorkspacesActivity) _activity).handleInvitation(workspace);
                                } else {
                                    //open the workspace
                                    ((SkootWorkspacesActivity) _activity).openWorkspace(workspace);
                                }
                            }
                          });
                        button.setOnLongClickListener(new OnLongClickListener() {
                            public boolean onLongClick(View v) {
                                ((SkootWorkspacesActivity) _activity).makeDeleteDialog(workspace);
                                return true;
                            }
                          });
                    } else {
                        button.setVisibility(View.GONE);
                    }
                }
            }
        }

    }
    return viewGroup;
}

I add this adapter to a MergeAdapter and do setAdapter on the ListView with the MergeAdapter.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

骑趴 2025-01-05 21:24:54

解决您的问题(ListView 滞后)的最佳解决方案是 Holder
即使用Holder类

示例代码

在Adapter类构造函数中为ViewHolder类创建一个对象

ViewHolder holder=new ViewHolder(); 

public View getView(int position, View convertView, ViewGroup parent) {
        AppInfo entry = mListAppInfo.get(position);
        ViewHolder holder = null;

        if(convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(R.layout.layout_appinfo, null);
            holder = new ViewHolder();
            holder.ivIcon = (ImageView)convertView.findViewById(R.id.ivIcon);
            holder.tvName = (TextView)convertView.findViewById(R.id.tvName);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder)convertView.getTag();
        }

        holder.ivIcon.setImageBitmap(entry.getIcon());
        holder.tvName.setText(entry.getName());

        return convertView;
    }

    static class ViewHolder {
        ImageView ivIcon;
        TextView tvName;
    }

The Best solution for your problem (ListView to lag) is Holder
i.e using Holder class

Sample code

Create an object for ViewHolder class in the Adapter class Constructor

ViewHolder holder=new ViewHolder(); 

public View getView(int position, View convertView, ViewGroup parent) {
        AppInfo entry = mListAppInfo.get(position);
        ViewHolder holder = null;

        if(convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            convertView = inflater.inflate(R.layout.layout_appinfo, null);
            holder = new ViewHolder();
            holder.ivIcon = (ImageView)convertView.findViewById(R.id.ivIcon);
            holder.tvName = (TextView)convertView.findViewById(R.id.tvName);
            convertView.setTag(holder);
        }
        else {
            holder = (ViewHolder)convertView.getTag();
        }

        holder.ivIcon.setImageBitmap(entry.getIcon());
        holder.tvName.setText(entry.getName());

        return convertView;
    }

    static class ViewHolder {
        ImageView ivIcon;
        TextView tvName;
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文