Android:扩展BaseAdapter,列表不更新

时间:2012-09-08 13:52:24

标签: android android-listview

我有两个列表在同一个活动布局中使用相同的扩展BaseAdapter,但在我调用notifyDataSetChanged时只有一个更新(我当然称之为两个)。我一直在寻找几天,但找不到问题。

该活动获取配对且可用的蓝牙设备并单独列出,我使用BluetoothChat示例,但我需要自定义行并且必须更改一些。

主要问题是注释“这只适用于其他(仅在下方)被评论”, Ctrl + F 以更快地到达目的地。

这是我的特别BaseAdapter(可能没用,但无论如何我发布了):

/**
 * Device list base adapter to show the devices in a custom ListView.
 */
public class DeviceListBaseAdapter extends BaseAdapter
{
    private static ArrayList<Device> deviceArrayList;

    private LayoutInflater mInflater;

    public DeviceListBaseAdapter(Context context, ArrayList<Device> results)
    {
        deviceArrayList = results;
        mInflater = LayoutInflater.from(context);
    }

    public int getCount()
    {
        return deviceArrayList.size();
    }

    public Object getItem(int position)
    {
        return deviceArrayList.get(position);
    }

    public long getItemId(int position)
    {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent)
    {
        ViewHolder holder;

        if(convertView == null)
        {
            convertView = mInflater.inflate(R.layout.device_row_view, null);
            holder = new ViewHolder();
            holder.tvName = (TextView) convertView.findViewById(R.id.tvName);
            holder.tvAddress = (TextView) convertView.findViewById(R.id.tvAddress);
            holder.tvSignal = (TextView) convertView.findViewById(R.id.tvSignal);

            convertView.setTag(holder);
        }
        else
        {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.tvName.setText(deviceArrayList.get(position).getName());
        holder.tvAddress.setText(deviceArrayList.get(position).getAddress());
        if(!deviceArrayList.get(position).getSignal().equals("0"))
        {
            holder.tvSignal.setText(deviceArrayList.get(position).getSignal() + "dBm");
        }

        return convertView;
    }

    static class ViewHolder
    {
        TextView tvName;
        TextView tvAddress;
        TextView tvSignal;
    }
}

使用它的活动:

public class DeviceSelectActivity extends Activity
{
    private ArrayList<Device> devAvailableList, devPairedList;
    private DeviceListBaseAdapter devAvailableListAdapter, devPairedListAdapter;
    private ListView devAvailableListView, devPairedListView;

    private Button bFindDevices;
    private BluetoothAdapter bluetoothAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.device_select);

        // Setup Bluetooth devices lists with custom rows
        devPairedListView = (ListView) findViewById(R.id.lvPairedDevices);
        devPairedList = new ArrayList<Device>();
        devPairedListAdapter = new DeviceListBaseAdapter(this, devPairedList);
        devPairedListView.setAdapter(devPairedListAdapter);

        // I commented this to see the behavior with only the first list    
//      devAvailableListView = (ListView) findViewById(R.id.lvAvailableDevices);
//      devAvailableList = new ArrayList<Device>();
//      devAvailableListAdapter = new DeviceListBaseAdapter(this, devAvailableList);
//      devAvailableListView.setAdapter(devAvailableListAdapter);

        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        // Register a receiver to handle Bluetooth actions
        registerReceiver(Receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
        registerReceiver(Receiver, new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));

        startDiscovery();
    }

    public void startDiscovery()
    {
        // Show search progress
        bFindDevices.setText(R.string.searching);
        bFindDevices.setEnabled(false);

        // Remove title for available devices
        findViewById(R.id.tvAvailableDevices).setVisibility(View.GONE);

        // Get a set of currently paired devices
        devPairedList.clear();
        devPairedListAdapter.notifyDataSetChanged();

        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
        if(pairedDevices.size() > 0)
        {
            findViewById(R.id.tvPairedDevices).setVisibility(View.VISIBLE);
            for(BluetoothDevice device : pairedDevices)
            {
                devPairedList.add(new Device(device.getName(), device.getAddress(), (short) 0));
                // This only works when the other (just below) is commented
                devPairedListAdapter.notifyDataSetChanged();
            }
        }

//      devAvailableList.clear();
//      devAvailableListAdapter.notifyDataSetChanged();

        bluetoothAdapter.startDiscovery();
    }

    // add found device to the devices list
    private final BroadcastReceiver Receiver = new BroadcastReceiver()
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_FOUND.equals(action))
            {
                // Found a device in range
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Device foundDevice = new Device(device.getName(), device.getAddress(), intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE));
                // If it's not a paired device add it to the list
                if(device.getBondState() != BluetoothDevice.BOND_BONDED)
                {
//                  devAvailableList.add(foundDevice);
                    // Signal list content change
//                  devAvailableListAdapter.notifyDataSetChanged();
                    // Make the available devices title visible
                    findViewById(R.id.tvAvailableDevices).setVisibility(View.VISIBLE);
                }
            }
            else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
            {
                // When finished (timeout) remove the progress indicator
                bFindDevices.setText(R.string.search);
                bFindDevices.setEnabled(true);
            }
        }
    };
}

我评论了可用设备列表中的所有内容,以确保填充配对设备列表。猜猜我会说可能会有一些丢失的引用,但由于我不完全理解列表如何工作但我找不到它。

问题是,当我尝试填充两个lits并且在调用.add()时,设备实际上被添加到列表中(.size()返回正确的数字),但第一个没有得到刷新。

1 个答案:

答案 0 :(得分:0)

解决方案

在创建DeviceListBaseAdapter等可重复使用的类时,请记住从不将局部变量设置为staticstatic做的是在该对象的所有实例之间共享此特定变量,因此我有DeviceListBaseAdapter的2个实例,但只有一个deviceArrayList,这就是为什么一次只能处理一个列表的原因。小心快速复制粘贴。