如何从 RecyclerView.Adapter 中的 ViewHolder 调用 MainActivity 方法? [英] How to call a MainActivity method from ViewHolder in RecyclerView.Adapter?
问题描述
在
MainActivity.java 包含一个要调用的方法,当用户在 RecyclerView
中点击蓝牙设备时:
public void confirmConnection(String address) {最终的蓝牙设备设备 = mBluetoothAdapter.getRemoteDevice(address);AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage("你要配对到" + device + "吗?");builder.setPositiveButton(R.string.button_ok,新 DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int id) {device.createBond();}});builder.setNegativeButton(R.string.button_cancel, null);builder.show();}
在 ViewHolder
类中(在 DeviceListAdapter.java) 点击监听器定义:
public class DeviceListAdapter extendsRecyclerView.Adapter{私有 ArrayListmDevices = new ArrayList();受保护的静态类 ViewHolder扩展 RecyclerView.ViewHolder实现 View.OnClickListener {私有 TextView 设备地址;公共 ViewHolder(View v) {超级(五);v.setOnClickListener(this);}@覆盖public void onClick(View v) {字符串地址 = deviceAddress.getText().toString();Toast.makeText(v.getContext(),"如何调用 MainActivity.confirmConnection(address)?",Toast.LENGTH_SHORT).show();}}
我的问题:
如何从ViewHolder
的onClick
方法调用confirmConnection(address)
方法?
我一直在 2 个 Java 文件之间移动 ViewHolder
类声明,并尝试将其放入自己的文件中 - 只是找不到正确的方法.
我是否应该向 ViewHolder
类添加一个字段并(何时?)在那里存储对 MainActivity
实例的引用?
更新:
这对我有用,但似乎是一种解决方法(而且我也在考虑使用 LocalBroadcastReceiver
- 这将是一种更加hackish 的解决方法)-
@Overridepublic void onClick(View v) {字符串地址 = deviceAddress.getText().toString();尝试 {((MainActivity) v.getContext()).confirmConnection(address);} 捕获(异常 e){//忽略}}
为了保持类解耦,我建议在适配器上定义一个接口,例如:
公共接口 OnBluetoothDeviceClickedListener {void onBluetoothDeviceClicked(String deviceAddress);}
然后在您的适配器中为此添加一个 setter:
private OnBluetoothDeviceClickedListener mBluetoothClickListener;public void setOnBluetoothDeviceClickedListener(OnBluetoothDeviceClickedListener l) {mBluetoothClickListener = l;}
然后在内部,在您的 ViewHolder
的 onClick()
中:
if (mBluetoothClickListener != null) {最终字符串地址 = deviceAddress.getText().toString();mBluetoothClickListener.onBluetoothDeviceClicked(地址);}
然后让您的 MainActivity
将侦听器传递给 Adapter
:
mDeviceListAdapter.setOnBluetoothDeviceClickedListener(new OnBluetoothDeviceClickedListener() {@覆盖public void onBluetoothDeviceClicked(String deviceAddress) {确认连接(设备地址);}});
通过这种方式,您可以稍后重用适配器,而无需将其绑定到特定行为.
In a simple app project at GitHub I have only 2 custom Java-files:
- MainActivity.java contains Bluetooth- and UI-related source code
- DeviceListAdapter.java contains an
Adapter
andViewHolder
for displaying Bluetooth devices in aRecyclerView
The MainActivity.java contains a method to be called, when user taps on a Bluetooth device in the RecyclerView
:
public void confirmConnection(String address) {
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Do you want to pair to " + device + "?");
builder.setPositiveButton(R.string.button_ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
device.createBond();
}
});
builder.setNegativeButton(R.string.button_cancel, null);
builder.show();
}
And in the ViewHolder
class (in the DeviceListAdapter.java) the click listener is defined:
public class DeviceListAdapter extends
RecyclerView.Adapter<DeviceListAdapter.ViewHolder> {
private ArrayList<BluetoothDevice> mDevices = new ArrayList<BluetoothDevice>();
protected static class ViewHolder
extends RecyclerView.ViewHolder
implements View.OnClickListener {
private TextView deviceAddress;
public ViewHolder(View v) {
super(v);
v.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String address = deviceAddress.getText().toString();
Toast.makeText(v.getContext(),
"How to call MainActivity.confirmConnection(address)?",
Toast.LENGTH_SHORT).show();
}
}
My problem:
How to call confirmConnection(address)
method from ViewHolder
s onClick
method?
I keep moving ViewHolder
class declaration between the 2 Java files and also tried putting it into its own file - and just can't find the right way.
Should I maybe add a field to ViewHolder
class and (when?) store a reference to MainActivity
instance there?
UPDATE:
This works for me, but seems to be a workaround (and also I was thinking of using LocalBroadcastReceiver
- which would be an even more hackish workaround) -
@Override
public void onClick(View v) {
String address = deviceAddress.getText().toString();
try {
((MainActivity) v.getContext()).confirmConnection(address);
} catch (Exception e) {
// ignore
}
}
To keep your classes decoupled, I'd suggest defining an interface on your adapter, something like:
public interface OnBluetoothDeviceClickedListener {
void onBluetoothDeviceClicked(String deviceAddress);
}
Then add a setter for this in your adapter:
private OnBluetoothDeviceClickedListener mBluetoothClickListener;
public void setOnBluetoothDeviceClickedListener(OnBluetoothDeviceClickedListener l) {
mBluetoothClickListener = l;
}
Then internally, in your ViewHolder
's onClick()
:
if (mBluetoothClickListener != null) {
final String addresss = deviceAddress.getText().toString();
mBluetoothClickListener.onBluetoothDeviceClicked(address);
}
Then just have your MainActivity
pass in a listener to the Adapter
:
mDeviceListAdapter.setOnBluetoothDeviceClickedListener(new OnBluetoothDeviceClickedListener() {
@Override
public void onBluetoothDeviceClicked(String deviceAddress) {
confirmConnection(deviceAddress);
}
});
This way you can reuse the adapter later without it being tied to that particular behavior.
这篇关于如何从 RecyclerView.Adapter 中的 ViewHolder 调用 MainActivity 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!