我知道这个问题出现了很多次,但由于某种原因,我似乎无法让它发挥作用。 在某些情况下,getView被多次调用的事实。
但是,在此处给出的示例中:http://android.amberfog.com/?p=296 它表示对数据中每一行的第一次调用应该在currentView中得到一个空值。 这种情况没有发生。
对我来说,当position为0时的调用将currentView设置为null,而position为1的调用将currentView设置为现有对象。
总共有16次调用“getView”但我得到的行重复一次(即每行两次)。 第0行 第1行 第0行 第1行
我可能只是从那篇文章中听不懂。
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/title_paired_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title_paired_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/paired_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="1"
/>
<TextView android:id="@+id/title_new_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title_other_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/new_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="2"
/>
<Button android:id="@+id/button_scan"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button_scan"
/>
</LinearLayout>
Listview行:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.
android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/list_selector"
android:orientation="horizontal"
android:padding="5dip" >
<!-- ListRow Left side Thumbnail image -->
<LinearLayout android:id="@+id/thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="3dip"
android:layout_alignParentLeft="true"
android:background="@drawable/image_bg"
android:layout_marginRight="5dip">
<ImageView
android:id="@+id/list_image"
android:layout_width="50dip"
android:layout_height="50dip"
android:src="@drawable/icon"/>
</LinearLayout>
<!-- Device Address -->
<TextView
android:id="@+id/tvwDeviceAddress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/thumbnail"
android:layout_toRightOf="@+id/thumbnail"
android:textColor="#040404"
android:typeface="sans"
android:textSize="15dip"
android:textStyle="bold"/>
<!-- Display Name -->
<TextView
android:id="@+id/tvwDisplayName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tvwDeviceAddress"
android:textColor="#343434"
android:textSize="10dip"
android:layout_marginTop="1dip"
android:layout_toRightOf="@+id/thumbnail"/>
</RelativeLayout>
适配器:
private class LazyAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<MPGDeviceDetails> data;
private LayoutInflater inflater=null;
public LazyAdapter(Activity a, ArrayList<MPGDeviceDetails> d) {
activity = a;
data=d;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
View vi=convertView;
Log.e("MPG","Position = " + position + ". ConvertView = " + convertView);
if(convertView==null)
vi = inflater.inflate(R.layout.device_name, null);
TextView address = (TextView)vi.findViewById(R.id.tvwDeviceAddress); // Device Address
TextView name = (TextView)vi.findViewById(R.id.tvwDisplayName); // Display name
ImageView thumb_image=(ImageView)vi.findViewById(R.id.list_image); // thumb image
address.setText(data.get(position).deviceAddress);
name.setText(data.get(position).getDisplayName());
Bitmap photo = data.get(position).getContactPhoto();
if (photo != null)
thumb_image.setImageBitmap(photo);
return vi;
}
}
用法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup the window
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.device_list);
// Set result CANCELED incase the user backs out
setResult(Activity.RESULT_CANCELED);
// Initialize the button to perform device discovery
Button scanButton = (Button) findViewById(R.id.button_scan);
scanButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
doDiscovery();
v.setVisibility(View.GONE);
}
});
// Initialize array adapters. One for already paired devices and
// one for newly discovered devices
// Find and set up the ListView for paired devices
pairedListView = (ListView) findViewById(R.id.paired_devices);
pairedDevicesList = new ArrayList<MPGDeviceDetails>();
pairedListView.setAdapter((mPairedDevicesArrayAdapter = new LazyAdapter(this,pairedDevicesList)));
pairedListView.setOnItemClickListener(mDeviceClickListener);
registerForContextMenu(pairedListView);
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
pairedDevicesList.add(MPGDeviceDetailsControl.getDeviceDetails(this, device.getAddress(), device.getName()));
}
}
}
MPGDeviceDetails是一个保存特定设备的所有数据的对象。
这是“debug”命令的输出:
03-27 10:03:30.730: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.742: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@4062d608.
03-27 10:03:30.746: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.750: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@40628d78.
03-27 10:03:30.750: E/MPG(2841): Position = 0. ConvertView = android.widget.RelativeLayout@4062d608.
03-27 10:03:30.753: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@4062d608.
03-27 10:03:30.753: E/MPG(2841): Position = 0. ConvertView = android.widget.RelativeLayout@40628d78.
03-27 10:03:30.753: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@40628d78.
03-27 10:03:30.761: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@4062d608.
03-27 10:03:30.761: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.769: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@40628d78.
03-27 10:03:30.769: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.777: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.781: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@406d4af8.
03-27 10:03:30.781: E/MPG(2841): Position = 0. ConvertView = null.
03-27 10:03:30.785: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@40694970.
03-27 10:03:30.789: E/MPG(2841): Position = 0. ConvertView = android.widget.RelativeLayout@406d4af8.
03-27 10:03:30.789: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@406d4af8.
03-27 10:03:30.789: E/MPG(2841): Position = 0. ConvertView = android.widget.RelativeLayout@40694970.
03-27 10:03:30.792: E/MPG(2841): Position = 1. ConvertView = android.widget.RelativeLayout@40694970.
这就是屏幕的样子:
有趣的是,虽然所有4个按钮都有效,但上下文菜单仅适用于前两个按钮!
答案 0 :(得分:2)
填写notifyDataSetChanged()
后,请尝试在适配器上调用pairedDevicesList
:
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
pairedDevicesList.add(MPGDeviceDetailsControl.getDeviceDetails(this, device.getAddress(), device.getName()));
}
}
((BaseAdapder)getListAdapter()).notifyDataSetChanged();
填写pairedDevicesList
后创建适配器。
还尝试声明适配器的数据具有稳定的ID:
@Override
public boolean hasStableIds() {
return true;
}
答案 1 :(得分:0)
一般情况下,除了对每个项目进行常规的getView调用之外,它还要调用大约3倍,因为它需要计算滚动条大小,布局等视图的测量值。关于重复行,我认为你应该粘贴你的代码。你可能做错了什么。
答案 2 :(得分:0)
currentView
值应用于优化问题。 Android建议重用视图以节省内存并更快地响应。
当yor currentView
不为null时,您可以使用它来显示当前项目
看看例子:
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
// we can't reuse view and must read it from layout
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.whatever, null);
}
// ... use v as view for row
}
答案 3 :(得分:0)
在向其添加值之前,您只需要clear
ArrayList。
此处为if
条件
if (pairedDevices.size() > 0) {
pairedDevicesList.clear();
// other code as it is
}
你也可以在清除ArrayList之前放一个日志。
Log.i("Size","ArrayList Size = "+pairedDevicesList.size());
所以你会得到更多的想法。