459 Stimmen

Behandlung von Schaltflächenklicks mit XML onClick in Fragmenten

Vor Honeycomb (Android 3) wurde jede Aktivität registriert, um Schaltflächenklicks über die onClick Tag in der XML-Datei eines Layouts:

android:onClick="myClickMethod"

Innerhalb dieser Methode können Sie Folgendes verwenden view.getId() und eine switch-Anweisung für die Logik der Schaltfläche.

Mit der Einführung von Honeycomb zerlege ich diese Aktivitäten in Fragmente, die in vielen verschiedenen Aktivitäten wiederverwendet werden können. Das Verhalten der Schaltflächen ist größtenteils Activity-unabhängig, und ich möchte, dass der Code in der Fragment-Datei enthalten ist ohne mit der alten (vor 1.6) Methode der Registrierung der OnClickListener für jede Taste.

final Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        // Perform action on click
    }
});

Das Problem ist, dass, wenn meine Layouts aufgeblasen werden, ist es immer noch die Hosting-Aktivität, die die Schaltfläche Klicks erhält, nicht die einzelnen Fragmente. Gibt es einen guten Ansatz für entweder

  • Das Fragment registrieren, um die Schaltflächenklicks zu empfangen?
  • Die Klick-Ereignisse von der Aktivität an das Fragment weitergeben, zu dem sie gehören?

1 Stimmen

Können Sie die Registrierung von Zuhörern nicht innerhalb des onCreate des Fragments vornehmen?

26 Stimmen

@jodes Ja, aber ich möchte nicht die setOnClickListener y findViewById für jede Schaltfläche, deshalb onClick wurde hinzugefügt, um die Dinge zu vereinfachen.

4 Stimmen

Wenn ich mir die akzeptierte Antwort ansehe, denke ich, dass die Verwendung von setOnClickListener lockerer gekoppelt ist als das Festhalten am XML onClick-Ansatz. Wenn die Aktivität jeden Klick an das richtige Fragment "weiterleiten" muss, bedeutet dies, dass der Code jedes Mal geändert werden muss, wenn ein Fragment hinzugefügt wird. Die Verwendung einer Schnittstelle zur Entkopplung von der Basisklasse des Fragments ist dabei nicht hilfreich. Wenn das Fragment mit der richtigen Schaltfläche selbst registriert, bleibt die Aktivität völlig agnostisch, die besser Stil IMO ist. Siehe auch die Antwort von Adorjan Princz.

0voto

sadat Punkte 3218

Die folgende Lösung könnte besser sein. Das Layout ist in fragment_my.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>
        <variable
            name="listener"
            type="my_package.MyListener" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/moreTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="@{() -> listener.onClick()}"
            android:text="@string/login"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Und das Fragment würde wie folgt aussehen

class MyFragment : Fragment(), MyListener {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
            return FragmentMyBinding.inflate(
                inflater,
                container,
                false
            ).apply {
                lifecycleOwner = viewLifecycleOwner
                listener = this@MyFragment
            }.root
    }

    override fun onClick() {
        TODO("Not yet implemented")
    }

}

interface MyListener{
    fun onClick()
}

0voto

JAAD Punkte 12289

Ihre Aktivität empfängt den Rückruf, den Sie verwendet haben müssen:

mViewPagerCloth.setOnClickListener((YourActivityName)getActivity());

Wenn Sie möchten, dass Ihr Fragment einen Rückruf erhält, tun Sie dies:

mViewPagerCloth.setOnClickListener(this);

und umsetzen onClickListener Schnittstelle auf Fragment

0voto

user4806368 Punkte 1

IMHO die beste Lösung:

in Fragmenten:

protected void addClick(int id) {
    try {
        getView().findViewById(id).setOnClickListener(this);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void onClick(View v) {
    if (v.getId()==R.id.myButton) {
        onMyButtonClick(v);
    }
}

dann in der onViewStateRestored-Funktion des Fragments:

addClick(R.id.myButton);

0voto

Vinod Joshi Punkte 7388

So hat es bei mir funktioniert: (Android Studio)

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.update_credential, container, false);
        Button bt_login = (Button) rootView.findViewById(R.id.btnSend);

        bt_login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                System.out.println("Hi its me");

            }// end onClick
        });

        return rootView;

    }// end onCreateView

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X