滚动时ListView非常慢(使用ViewHolder/recycle)

Ted*_*Ted 14 android listview

更新2011-08-29 如果我删除NodePickup中的图像,那么懒散就消失了.

问题是 - 为什么?

----

我又回来尝试一些Android开发了.我有一个"旧的"HTC Hero手机,所以我启动了一个,做了一些更新,现在又用Eclipse和其他人再次运行.

我在设备上运行了Android 2.1.

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

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

mButtonListenerUPP = new OnClickListener() {
    @Override
    public void onClick(View v)
    {
        Intent myIntent = new Intent(BaseActivity.this, ActivityMain.class);
        BaseActivity.this.startActivity(myIntent);
    }
};
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么,所以我只是在这里发布代码并希望有人给我一些提示=)

谢谢!

适配器,NodeRowAdapter

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

主要活动,ActivityMain

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

    }
}
Run Code Online (Sandbox Code Playgroud)

自定义列表项NodePickup

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();
            }

        });
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,NodePickup XML布局

<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>
Run Code Online (Sandbox Code Playgroud)

wea*_*ire 17

更新2011-08-29如果我删除NodePickup中的图像,那么懒散就消失了.

该视图很难确定应如何呈现布局.您发布的xml没有多大帮助.如果删除ImageView,则LinearLayout02将占用父级的所有宽度.但是使用带有标准尺寸的imageView和右边的布局会使fill_parent混淆视图.再次请求imageView的大小"将边距向右推"(种类).看看下面的建议

提示1

使用LinearLayout属性权重.同时制作imageView fill_parent和LinearLayout(宽度)并使用权重属性.也可以使用TextViews进行垂直布局.最好的解决方案是将固定大小放在TextViews思想的高度上.还要考虑将顶视图更改为RelativeLayout.使用标准尺寸,AlignParentLeft制作图像,并将LinearLayout02设置为RightOf imageView.你将会大量放宽ViewGroup的onMeasure.

提示2

看起来当文本改变高度时,整个视图需要重新充气.一种常见的技术,以避免它使列表项固定在高度.因此listview可以重复使用循环视图而无需重新填充.

提示3

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

另外你说如果你删除ImageView一切都很快.如果以上没有任何影响,请试试这个吗?因为您知道imageView大小是固定的.

扩展imageView并覆盖requestLayout()方法.

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
         */
    }
}
Run Code Online (Sandbox Code Playgroud)

现在将MyImageView小部件包含在XML中.

<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 >
Run Code Online (Sandbox Code Playgroud)


小智 16

在优化我的getView()方法以使用持有者并重用convertView后,如果它不为null,我的listview仍然相当迟钝.然后,我试过了

listView.setScrollingCacheEnabled(false);
Run Code Online (Sandbox Code Playgroud)

它立刻解决了.

希望这有助于某人.

  • 我在打字建议中看到过很多次。但一直不知道目的。+1 (2认同)

AlA*_*iri 6

我刚刚发现了这个,我想与你们分享.

我尝试了所有提供的解决方案但没有任何效果 导致问题的原因是我正在使用TextView视图中的文本的长度,因为我正在使用它

mTextView.SetText(theLongString)
Run Code Online (Sandbox Code Playgroud)

在我的getView方法的适配器中.现在我收缩了我的String,listview非常顺利:)