So rufen Sie eine MainActivity die Methode von ViewHolder in RecyclerView.Adapter?
In eine einfache app-Projekt auf GitHub ich habe nur 2 benutzerdefinierte Java-Dateien:
- MainActivity.java enthält Bluetooth - und UI-bezogene Quell-code
- DeviceListAdapter.java enthält eine
Adapter
undViewHolder
für die Anzeige von Bluetooth-Geräten in einemRecyclerView
Den MainActivity.java enthält eine Methode aufgerufen werden, wenn der Benutzer tippt auf ein Bluetooth-Gerät in der 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();
}
Und in der ViewHolder
Klasse (in der DeviceListAdapter.java) der Klick-listener definiert ist:
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();
}
}
Mein problem:
Wie nennen confirmConnection(address)
Methode von ViewHolder
s onClick
Methode?
Ich in Bewegung bleiben ViewHolder
Klasse Erklärung zwischen 2 Java-Dateien und auch versucht, indem es in seine eigene Datei - und kann einfach nicht den richtigen Weg finden.
Sollte ich vielleicht hinzufügen eines Felds zu ViewHolder
Klasse und (Wann?) speichern Sie einen Verweis auf MainActivity
Instanz gibt?
UPDATE:
Dies funktioniert für mich, aber scheint ein workaround (und auch ich war denken mit LocalBroadcastReceiver
- das wäre ein noch mehr hackish workaround) -
@Override
public void onClick(View v) {
String address = deviceAddress.getText().toString();
try {
((MainActivity) v.getContext()).confirmConnection(address);
} catch (Exception e) {
//ignore
}
}
- Ihre ViewHolder enthält eine Ansicht. Diese Ansicht hat einen Kontext. Dieser Zusammenhang ist den meisten vermutlich Ihre Aktivität. So warf der Kontext zu MainActivity und Sie sollten in Ordnung sein. Über Schnittstellen ist die bessere Vorgehensweise aber. ((MainActivity)v. getContext()).confirmConnection() sollte es sein.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Halten Ihre Klassen entkoppelt, würde ich vorschlagen, die Definition einer Schnittstelle auf dem adapter, so etwas wie:
Dann fügen Sie eine Set-Methode für diese in den adapter:
Dann intern, in Ihrem
ViewHolder
'sonClick()
:Dann müssen nur Ihre
MainActivity
pass in einen listener auf dieAdapter
:Diese Weise können Sie die Wiederverwendung der adapter später, ohne das es gebunden, dass ein bestimmtes Verhalten.
Für diejenigen, die für den Aufruf einer callback-von einem statischen ViewHolder tun die folgende.
Lassen Sie noch einen adapter:
Dann sollten Sie einen setCallback Methode und rufen Sie es von activity/fragment. Auch Sie sollten nicht einen Rückruf statische (es kann zu Problemen führen, wenn Sie das gleiche adapter in vielen Klassen). Erstellen Sie ein Feld innerhalb der ViewHolder. Also:
Nachdem Sie haben die adapter-Sie können es aufrufen, also:
Könnte passieren Sie die MainActivity als Konstruktor-parameter für den Adapter und speichern Sie es in ein Feld. Oder Sie verwenden einen Ereignis-bus - es gibt mehrere Möglichkeiten, es zu tun - ich würde für das Feld
In den adapter, eine Schnittstelle erstellen, wird ein Rückruf zu der Haupttätigkeit
Haben Ihre Haupttätigkeit umzusetzen.
implementieren Sie die callback -
dann setzen Sie einfach den Rückruf aus dem adapter
Können Sie die Anruf-Aktivität Methode durch die Verwendung von Instanz-Aktivitäten wie diese, innen MainActivity schreiben Sie folgenden code
Innen Adapter
In Ihrem onClick-Methode