gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 18:49:59 26 4
gpt4 key购买 nike

我又回来尝试一些 Android 开发了。我身边有一部“旧”HTC Hero 手机,所以我启动了那部手机,进行了一些更新,现在可以再次运行 Eclipse 和其他手机。

我的设备上运行的是 Android 2.1。

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

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

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

我不知道为什么。

适配器,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);
}
}

主要 Activity ,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));

}
}

自定义列表项 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();
}

});
}
}

最后,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>

更新

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

最佳答案

UPDATE 2011-08-29 If I remove the image in the NodePickup, the lagginess is gone.

View 很难确定应该如何呈现布局。您发布的 xml 没有多大帮助。如果删除 ImageView,则 LinearLayout02 将占用父级的所有宽度。但是让 imageView 具有标准尺寸和右侧布局将使 fill_parent 混淆 View 很多。再次请求 imageView 的大小以“将边距向右推”(有点)。看看我下面的建议

技巧一

使用LinearLayout 属性权重。也制作 imageView fill_parent 和 LinearLayout(用于宽度)并使用权重属性。对 TextView 的垂直布局也这样做。最好的解决方案是将固定大小设置为 TextViews 思想的高度。还要考虑将顶 View 更改为 RelativeLayout。使用标准尺寸制作图像,AlignParentLeft 并将 LinearLayout02 放在 RightOf imageView 上。您将减轻 ViewGroup 的 onMeasure 很多。

技巧2

似乎当文本改变高度时,整个 View 需要重新膨胀。避免这种情况的常见技术是使列表项的高度固定。因此 ListView 可以重用回收的 View 而无需重新膨胀。

技巧 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
*/
}
}

现在像这样将 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 >

关于android - 滚动时 ListView 非常慢(使用 ViewHolder/回收),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7224244/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com