我正在创建一个扫描并配对蓝牙设备的应用。我正在RecyclerView中显示设备,并通过为该设备着色ViewHolder来指示绑定状态。我的问题是ViewHolder的颜色只有在再次扫描设备后才会更改,我希望它立即更新配对或取消配对的颜色。我试图通过使用广播接收器来做到这一点,但我无法获得对正确的ViewHolder的引用。我怎么能实现这个目标?我将下面的代码包含在我的RecyclerView.Adapter和包含广播接收器的BluetoothUtils文件中。提前致谢。我的适配器:
getAllUsers
和我的BluetoothUtils:
class DeviceAdapter(val mContext : Context) : RecyclerView.Adapter<DeviceAdapter.DeviceHolder>() {
companion object {
val TAG = "Device Adapter"
fun DeviceHolder.setColor(bonded: Boolean):Unit{
val background = if (bonded)Color.CYAN else Color.TRANSPARENT
this.itemView.setBackgroundColor(background)
}
}
val mDevices = ArrayList<BluetoothDevice>()
fun updateItems(list: ArrayList<BluetoothDevice>) {
mDevices.clear()
mDevices.addAll(list)
Log.d(TAG, "updating items : $mDevices")
notifyDataSetChanged()
}
fun ViewGroup.inflate(@LayoutRes res: Int, attachToRoot: Boolean = false): View {
return LayoutInflater.from(mContext).inflate(res, this, attachToRoot)
}
override fun onBindViewHolder(holder: DeviceHolder, position: Int) {
Log.d(TAG, "onBindViewHolder called!")
holder.bindItems(mDevices.get(position))
if (mDevices.get(position).bondState==BluetoothDevice.BOND_BONDED) {
holder.itemView.setBackgroundColor(CYAN)
} else {
holder.itemView.setBackgroundColor(Color.TRANSPARENT)
}
}
override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): DeviceAdapter.DeviceHolder {
Log.d(TAG, "onCreateViewHolder called!")
val v = parent!!.inflate(R.layout.device_item, false)
return DeviceHolder(v)
}
override fun getItemCount(): Int {
return mDevices.size
}
inner class DeviceHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val nameView = itemView.findViewById(R.id.nameView) as TextView
val addrView = itemView.findViewById(R.id.addressView) as TextView
var dialog: AlertDialog? = null;
fun bindItems(btDevice: BluetoothDevice) {
Log.d(TAG, "holder created!")
nameView.text = btDevice.name ?: "Unknown"
addrView.text = btDevice.address
itemView.setOnClickListener {
dialog = AlertDialog.Builder(it.context)
.setTitle("Options")
.setView(R.layout.options_dialog_layout)
.setNegativeButton("Cancel", DialogInterface.OnClickListener { _, which -> })
.create()
dialog!!.show()
val ops = listOf(
dialog!!.findViewById(R.id.statOp),
dialog!!.findViewById(R.id.pairOp),
dialog!!.findViewById(R.id.connectOp),
dialog!!.findViewById(R.id.sendOp),
dialog!!.findViewById(R.id.unPairOp)
)
ops.forEach { it.setOnClickListener {
Toast.makeText(it.context, it.id.toString(), Toast.LENGTH_SHORT).show()
when(it.id){
R.id.statOp -> {}
R.id.connectOp -> {
Log.d(TAG, "connectOp reached")
BluetoothReflection.connectDevice(btDevice)
dialog!!.dismiss()
}// BluetoothUtils.connect(BluetoothAdapter.getDefaultAdapter(), btDevice)
R.id.pairOp -> {
Log.d(TAG, "pairOp reached")
BluetoothUtils.startPair(BluetoothAdapter.getDefaultAdapter(), btDevice)
if (btDevice.bondState==BluetoothDevice.BOND_BONDED){
this@DeviceHolder.itemView.setBackgroundColor(CYAN) //doesn't work
}
Log.d(TAG, "start pair complete")
dialog!!.dismiss()
}//
R.id.unPairOp -> {//no executable code found here
Log.d(TAG, "unPairOp reached")
BluetoothUtils.unPair(btDevice)
if (btDevice.bondState==BluetoothDevice.BOND_NONE){
this@DeviceHolder.itemView.setBackgroundColor(Color.TRANSPARENT) //doesn't work
}
Log.d(TAG, "unpair complete")
dialog!!.dismiss()
}
R.id.sendOp -> {}
}
} }
}
}
}
}
答案 0 :(得分:1)
将boolean
或int
添加到BluetoothDevice
模型以管理视图。
例如,
BluetoothDevice:添加了isOn
州。 (对不起,这是Java)
class BluetoothDevice {
boolean isOn;
public boolean isOn() {
return isOn;
}
public void setOn(boolean isOn) {
this.isOn = isOn;
}
}
DeviceHolder:更改了视图的颜色
fun bindItems(btDevice: BluetoothDevice) {
stateView.textColor = btDevice.isOn() ? Color.RED : Color.GREEN
}
DeviceAdapter:已添加getItems
fun getItems() {
return mDevices
}
如果您想更改isOn
州,请更改型号并通知它。
adapter.getItems().get(i).setOn(true);
adapter.notifyDataSetChanged();
答案 1 :(得分:0)
我也喜欢上面的答案,但我完成这项工作的方法是将BroadcastReceiver传递给DeviceAdapter:
class DeviceAdapter(val mContext:Context, val mReceiver:MainBTStatusReceiver) : RecyclerView.Adapter<DeviceAdapter.DeviceHolder>()
然后使ViewHolder成为BroadcastReceiver的成员,并将ViewHolder的setter函数命名为setFocus。在调用BluetoothUtils类中的任何函数之前,我调用setFocus函数,然后广播接收器修改当前设置焦点的视图的颜色。我确实有一些担心,这可能不是可靠的,因为每次修改正确的ViewHolder是最准确的方法。如果您发现此问题,请发表评论告诉我。
我更新的BroadcastReceiver:
class MainBTStatusReceiver(): BroadcastReceiver() {
val TAG = "MainBTStatusReceiver"
var holder: DeviceAdapter.DeviceHolder? = null
fun setFocus(holder: DeviceAdapter.DeviceHolder) {
this.holder = holder
}
override fun onReceive(context: Context?, intent: Intent) {
val action = intent.action
when (action) {
BluetoothDevice.ACTION_BOND_STATE_CHANGED -> {
val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
when (device.bondState) {
BluetoothDevice.BOND_BONDED -> {
holder!!.itemView.setBackgroundColor(Color.CYAN)
Log.d(TAG, "BONDED")
}
BluetoothDevice.BOND_BONDING -> {
Log.d(TAG, "BONDING")
}
BluetoothDevice.BOND_NONE -> {
holder!!.itemView.setBackgroundColor(Color.TRANSPARENT)
Log.d(TAG, "NONE")
}
}
}
}
}
}
和my表达式中的两个语句调用setFocus():
R.id.pairOp -> {
Log.d(TAG, "pairOp reached")
mReceiver.setFocus(this@DeviceHolder)
BluetoothUtils.startPair(BluetoothAdapter.getDefaultAdapter(), btDevice)
Log.d(TAG, "start pair complete")
dialog!!.dismiss()
}
R.id.unPairOp -> {
Log.d(TAG, "unPairOp reached")
mReceiver.setFocus(this@DeviceHolder)
BluetoothUtils.unPair(btDevice)
Log.d(TAG, "unpair complete")
dialog!!.dismiss()
}