我有两个列表在同一个活动布局中使用相同的扩展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()
返回正确的数字),但第一个没有得到刷新。
答案 0 :(得分:0)
在创建DeviceListBaseAdapter
等可重复使用的类时,请记住从不将局部变量设置为static
。 static
做的是在该对象的所有实例之间共享此特定变量,因此我有DeviceListBaseAdapter
的2个实例,但只有一个deviceArrayList
,这就是为什么一次只能处理一个列表的原因。小心快速复制粘贴。