首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >滚动时ListView非常慢(使用ViewHolder/回收)

滚动时ListView非常慢(使用ViewHolder/回收)
EN

Stack Overflow用户
提问于 2011-08-28 21:57:20
回答 10查看 32.5K关注 0票数 14

我又开始尝试安卓开发了。我有一部“老”的HTC英雄手机,所以我启动了其中一部,做了一些更新,现在又重新运行了Eclipse和其他版本。

我在设备上运行了Android2.1。

我制作了一个非常简单的测试应用程序,除了显示一些活动之类的东西之外,什么也不做。即使没有数据库连接,也没有从任何网络获取的数据--应用程序非常慢。

例如,我有一个带有一些自定义布局项的ListView。当只添加6-7项(因此我得到滚动)时,滚动的速度非常慢。另外,我有一些按钮可以更改活动,而且非常慢:

代码语言:javascript
运行
复制
mButtonListenerUPP = new OnClickListener() {
    @Override
    public void onClick(View v)
    {
        Intent myIntent = new Intent(BaseActivity.this, ActivityMain.class);
        BaseActivity.this.startActivity(myIntent);
    }
};

我搞不懂为什么。

适配器,NodeRowAdapter

代码语言:javascript
运行
复制
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.view.*;
import android.widget.ArrayAdapter;

import android.widget.TextView;

public class NodeRowAdapter extends ArrayAdapter 
{
    private Activity context;
    private ArrayList<Node> mList;
    private LayoutInflater inflater;

    NodeRowAdapter(Activity context, ArrayList<Node> objects) 
    {
        super(context, R.layout.nodepickup, objects);
        this.context=context;
        mList = objects;
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    class ViewHolder 
    {
        TextView name;
        TextView time;
        TextView road;
        Node node;
    }

    public Node getNode(int position)
    {
        if (mList != null && mList.size() > position)
            return mList.get(position);
        else
            return null;
    }
    public View getView(int position, View convertView, ViewGroup parent) 
    {
        View view = convertView;
        ViewHolder holder;
        if (view == null)
        {
            view = inflater.inflate(R.layout.nodepickup, parent, false);
            holder = new ViewHolder();
            holder.name =(TextView)view.findViewById(R.id.name);
            holder.time =(TextView)view.findViewById(R.id.time);
            holder.road =(TextView)view.findViewById(R.id.road);
            view.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        Node node = mList.get(position);
        holder.name.setText(node.name);
        holder.time.setText(node.time);
        holder.road.setText(node.road);

        return(view);
    }
}

主要活动,ActivityMain

代码语言:javascript
运行
复制
public class ActivityMain extends BaseActivity 
{
    private NodeRowAdapter _nodeRowAdapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        SICApplication._myContext = this;
        SICApplication._myContext = this;

        _nodeRowAdapter = new NodeRowAdapter(this, SICApplication.dataHolder_activityMain._nodes);
        ListView listView1 = (ListView) findViewById(R.id.ListViewNodes);
        listView1.setOnItemClickListener(new OnItemClickListener() 
        {
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
            {
                Node node = _nodeRowAdapter.getNode(position);
                Log.v("MyApp", "Node=" + node.name);
            } 
        });
        listView1.setAdapter(_nodeRowAdapter);  

    }

    /* Handles item selections */
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        switch (item.getItemId()) 
        {
            case R.id.add_item:
                addNodeItem();
                return true;
        }
        return false;
    }



    private void addNodeItem()
    {
        _nodeRowAdapter.add(new Node("Test", "asd asd ", "14:00", 1));

    }
}

自定义列表项NodePickup

代码语言:javascript
运行
复制
public class NodePickup extends LinearLayout
{
    public NodePickup(Context context, AttributeSet attributeSet)
    {
        super(context, attributeSet);

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.nodepickup, this);

        this.setOnClickListener(new OnClickListener() 
        {
            @Override
            public void onClick(View v)
            {
                AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
                builder.setMessage("Ajabaja!")
                .setCancelable(true)
                .setPositiveButton("JA!", new DialogInterface.OnClickListener() 
                {
                   public void onClick(DialogInterface dialog, int id) 
                   {
                       dialog.cancel();
                   }
                });
                builder.show();
            }

        });
    }
}

最后,NodePickup XML布局

代码语言:javascript
运行
复制
<LinearLayout 
    android:id="@+id/LinearLayout01" 
    android:layout_width="fill_parent" 
    android:layout_height="64dip"
    android:orientation="horizontal" 
    android:background="@drawable/stateful_background"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ImageView 
        android:id="@+id/ImageView01" 
        android:layout_width="40dip" 
        android:layout_height="40dip"
        android:src="@drawable/arrow_up_green"
        android:background="@android:color/transparent">
    </ImageView>

    <LinearLayout 
        android:id="@+id/LinearLayout02"
        android:background="@android:color/transparent"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:orientation="vertical"
        xmlns:android="http://schemas.android.com/apk/res/android">

        <TextView
            android:text="14:46 (15 min)"
            android:id="@+id/time"
            android:textSize="12dip"
            android:textColor = "#000000"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent">
        </TextView>

        <TextView
            android:text="test"
            android:id="@+id/road"
            android:textSize="12dip"
            android:textColor = "#000000"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent">
        </TextView>

        <TextView
            android:text="test test"
            android:id="@+id/name"
            android:textSize="12dip"
            android:textColor = "#000000"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent">
        </TextView>
    </LinearLayout>
</LinearLayout>

更新

如果我删除NodePickup中的图像,落后的状态就会消失。问题是-为什么?

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2011-09-03 14:32:26

更新2011-08-29如果我删除NodePickup中的图像,落后就消失了。

视图很难理解布局应该如何呈现。您发布的xml并没有多大帮助。如果删除ImageView,则LinearLayout02将占用父级的所有宽度。但是,拥有标准尺寸的imageView和右边的布局将fill_parent混淆了很多视图。再次请求imageView的大小以“向右推边距”(类似)。看一看下面的建议

Tip1

使用LinearLayout属性权重。使用imageView fill_parent和LinearLayout (对于宽度),并使用权重属性。对于TextViews的垂直布局,也要这样做。最好的解决办法应该是在TextViews思想的高度上设置一个固定的大小。还可以考虑将顶部视图更改为RelativeLayout。用标准尺寸制作图像,AlignParentLeft和LinearLayout02 toRightOf imageView。您将大大减轻onMeasure of ViewGroup的负担。

Tip2

似乎当文本改变高度时,整个视图需要重新膨胀,这是一种避免将列表项固定在高度上的常见技术。因此,listview可以重用回收的视图,而不需要重新膨胀。

Tip3

您的LinearLayout02的固定高度为64 it或Fill_Parent,因为您没有任何左空间,但是布局不知道,并且每次都尝试重新排列它,因为文本也是Wrap_content。

你还说过,如果你删除ImageView,一切都是快速的。,如果上面没有任何效果,,你能试试这个吗?因为你知道imageView大小是固定的。

扩展imageView并重写requestLayout()方法。

代码语言:javascript
运行
复制
public class MyImageView extends ImageView {

public PImageView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

public PImageView(Context context, AttributeSet attrs) {
    super(context, attrs);

}

public PImageView(Context context) {
    super(context);

}

@Override
    public void requestLayout() {
        /*
         * Do nothing here
         */
    }
}

现在,像这样将MyImageView小部件包含到XML中。

代码语言:javascript
运行
复制
<com.package_name.MyImageView 
        android:id="@+id/ImageView01" 
        android:layout_width="40dip" 
        android:layout_height="40dip"
        android:src="@drawable/arrow_up_green"
        android:background="@android:color/transparent">
 </com.package_name.MyImageView >
票数 17
EN

Stack Overflow用户

发布于 2012-03-15 04:08:08

在优化了getView()方法以使用holder并在不为null的情况下重用convertView之后,我的listview仍然非常滞后。然后,我试过

代码语言:javascript
运行
复制
listView.setScrollingCacheEnabled(false);

很快就解决了。

希望这能帮上忙。

票数 16
EN

Stack Overflow用户

发布于 2014-01-13 15:19:36

我刚发现这个我想和你们分享。

我尝试了所有的解决方案,但都没有效果。造成这个问题的原因是我输入的一个TextView视图的文本长度,因为我正在使用

代码语言:javascript
运行
复制
mTextView.SetText(theLongString)

在我的getView方法的适配器中。现在我缩小了字符串,listview非常平滑:)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7224244

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档