In a simple app project at GitHub I have only 2 custom Java-files:
Adapter
and ViewHolder
for displaying Bluetooth devices in a RecyclerView
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
}
}
findViewById(yourButtonId); btn. setOnClickListener(new Button. OnClickListener() { @Override public void onClick(View v) { if (mContext instanceof YourActivityName) { ((YourActivityName)mContext). yourDesiredMethod(); } } });
A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View. findViewById(int) results.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With