android - 在 ListView 中重复的行

标签 android listview

我知道这个问题已经出现过很多次,但出于某种原因我似乎无法让它发挥作用。 事实上,在某些情况下会多次调用 getView。

但是,在此处给出的示例中:http://android.amberfog.com/?p=296 它说对数据中每一行的第一次调用应该在 currentView 中得到一个空值。 这不会发生。

我遇到的情况是,position 为 0 时的调用将 currentView 设置为 null,而 position 为 1 的调用将 currentView 设置为现有对象。

总共对“getView”进行了 16 次调用,但我得到了重复的行一次(即每行两个)。 第 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 是一个包含特定设备所有数据的对象。

这是“调试”命令的输出:

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. 

这是屏幕的样子: enter image description here

有趣的是,虽然所有 4 个按钮都有效,但上下文菜单仅适用于前两个按钮!

最佳答案

当您完成填充 pairedDevicesList 时,尝试在您的适配器上调用 notifyDataSetChanged():

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

关于android - 在 ListView 中重复的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9875488/

相关文章:

android - 如何减少嵌入式 android 操作系统的启动时间?

android - 如何在ActionMode override中获取webview的选中文本

listview - 如何用Flutter在同屏显示两个ListView?

c# - 如何增加 WinForms 中 ListViewItems 的 AutoPopDelay 值?

android - ListView 多选问题?

java - jTidy 在整理 HTML 后不返回任何内容

Android IllegalArgumentException : The tag for fragment_XXX is invalid. 收到:layout-sw600dp/fragment_XXX_0

android - 阻止应用程序在使用时自行更新

android - 从其 ItemClickListener 的 ListView 中删除项目

java - Android:为 ListView 项目添加边框