Umgang mit Schaltflächenklicks mit XML onClick in Fragmenten

440

Vor Honeycomb (Android 3) wurde jede Aktivität registriert, um Schaltflächenklicks über das onClickTag in der XML-Datei eines Layouts zu verarbeiten:

android:onClick="myClickMethod"

Innerhalb dieser Methode können Sie view.getId()eine switch-Anweisung verwenden, um die Schaltflächenlogik auszuführen.

Mit der Einführung von Honeycomb zerlege ich diese Aktivitäten in Fragmente, die in vielen verschiedenen Aktivitäten wiederverwendet werden können. Das meiste Verhalten der Schaltflächen ist aktivitätsunabhängig, und ich möchte, dass sich der Code in der Fragmentdatei befindet, ohne die alte (vor 1.6) Methode zum Registrieren der OnClickListenerfür jede Schaltfläche zu verwenden.

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 beim Aufblasen meines Layouts immer noch die Hosting-Aktivität die Schaltflächenklicks erhält, nicht die einzelnen Fragmente. Gibt es einen guten Ansatz für beide

  • Registrieren Sie das Fragment, um die Schaltflächenklicks zu erhalten?
  • Übergeben Sie die Klickereignisse aus der Aktivität an das Fragment, zu dem sie gehören.
smith324
quelle
1
Können Sie nicht mit der Registrierung von Listenern im onCreate des Fragments umgehen?
CL22
24
@jodes Ja, aber ich möchte nicht verwenden müssen setOnClickListenerund findViewByIdfür jede Schaltfläche wurde deshalb onClickhinzugefügt, um die Dinge einfacher zu machen.
Smith 324
4
Wenn ich mir die akzeptierte Antwort anschaue, denke ich, dass die Verwendung von setOnClickListener lockerer gekoppelt ist als das Festhalten am XML onClick-Ansatz. Wenn die Aktivität jeden Klick auf das richtige Fragment weiterleiten muss, bedeutet dies, dass sich der Code jedes Mal ändern muss, wenn ein Fragment hinzugefügt wird. Die Verwendung einer Schnittstelle zum Entkoppeln von der Basisklasse des Fragments hilft dabei nicht. Wenn sich das Fragment mit der richtigen Schaltfläche selbst registriert, bleibt die Aktivität völlig agnostisch, was IMO besser ist. Siehe auch die Antwort von Adorjan Princz.
Adriaan Koster
@ smith324 muss Adriaan in diesem Punkt zustimmen. Probieren Sie Adorjans Antwort aus und sehen Sie, ob das Leben danach nicht besser ist.
user1567453

Antworten:

175

Sie könnten dies einfach tun:

Aktivität:

Fragment someFragment;    

//...onCreate etc instantiating your fragments

public void myClickMethod(View v) {
    someFragment.myClickMethod(v);
}

Fragment:

public void myClickMethod(View v) {
    switch(v.getId()) {
        // Just like you were doing
    }
}    

Als Antwort auf @Ameen, der weniger Kopplung wollte, sind Fragmente wiederverwendbar

Schnittstelle:

public interface XmlClickable {
    void myClickMethod(View v);
}

Aktivität:

XmlClickable someFragment;    

//...onCreate, etc. instantiating your fragments casting to your interface.
public void myClickMethod(View v) {
    someFragment.myClickMethod(v);
}

Fragment:

public class SomeFragment implements XmlClickable {

//...onCreateView, etc.

@Override
public void myClickMethod(View v) {
    switch(v.getId()){
        // Just like you were doing
    }
}    
Blundell
quelle
52
Das ist es, was ich jetzt im Wesentlichen mache, aber es ist viel chaotischer, wenn Sie mehrere Fragmente haben, die jeweils Klickereignisse empfangen müssen. Ich bin nur mit Fragmenten im Allgemeinen erschwert, weil sich Paradigmen um sie herum aufgelöst haben.
Smith324
128
Ich stoße auf dasselbe Problem, und obwohl ich Ihre Antwort schätze, ist dies aus Sicht der Softwareentwicklung kein sauberer Code. Dieser Code führt dazu, dass die Aktivität eng mit dem Fragment gekoppelt ist. Sie sollten in der Lage sein, dasselbe Fragment in mehreren Aktivitäten wiederzuverwenden, ohne dass die Aktivitäten die Implementierungsdetails der Fragmente kennen.
Ameen
1
Sollte "switch (v.getId ()) {" und nicht "switch (v.getid ()) {" sein
eb80
5
Anstatt Ihre eigene Schnittstelle zu definieren, können Sie den bereits vorhandenen OnClickListener verwenden, wie von Euporie erwähnt.
fr00tyl00p
1
Ich habe ungefähr geweint, als ich das gelesen habe, es ist SO VIEL BOILERPLATE ... Die folgende Antwort von @AdorjanPrincz ist der richtige Weg.
Wjdavis5
603

Ich bevorzuge die Verwendung der folgenden Lösung für die Behandlung von onClick-Ereignissen. Dies funktioniert auch für Aktivitäten und Fragmente.

public class StartFragment extends Fragment implements OnClickListener{

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

        View v = inflater.inflate(R.layout.fragment_start, container, false);

        Button b = (Button) v.findViewById(R.id.StartButton);
        b.setOnClickListener(this);
        return v;
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.StartButton:

            ...

            break;
        }
    }
}
Adorjan Princz
quelle
9
In onCreateView durchlaufe ich alle untergeordneten Elemente der ViewGroup v und setze den onclicklistener für alle gefundenen Button-Instanzen. Es ist viel besser, als den Listener für alle Tasten manuell einzustellen.
Eine Person
17
Gewählt. Dies macht die Fragmente wiederverwendbar. Warum sonst Fragmente verwenden?
Boreas
44
Ist dies nicht dieselbe Technik, die 1987 von der Programmierung von Windows befürwortet wurde ? Keine Sorgen machen. Google bewegt sich schnell und dreht sich alles um Entwicklerproduktivität. Ich bin sicher, es wird nicht lange dauern, bis die Ereignisbehandlung so gut ist wie 1991-eara Visual Basic.
Edward Brey
7
Welchen Import haben Sie für OnClickListener verwendet? Intellij schlägt mir android.view.View.OnClickListener vor und es funktioniert nicht: / (onClick läuft nie)
Lucas Jota
4
@ NathanOsman Ich denke, die Frage bezog sich auf die XML-Datei onClick, daher bieten die akzeptierten und die genaue Lösung.
Naveed Ahmad
29

Das Problem, denke ich, ist, dass die Ansicht immer noch die Aktivität ist, nicht das Fragment. Die Fragmente haben keine eigene unabhängige Ansicht und sind an die Ansicht der übergeordneten Aktivitäten angehängt. Deshalb endet das Ereignis in der Aktivität, nicht im Fragment. Es ist unglücklich, aber ich denke, Sie werden Code brauchen, damit dies funktioniert.

Während der Konvertierungen habe ich einfach einen Klick-Listener hinzugefügt, der den alten Ereignishandler aufruft.

zum Beispiel:

final Button loginButton = (Button) view.findViewById(R.id.loginButton);
loginButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(final View v) {
        onLoginClicked(v);
    }
});
Brill Pappin
quelle
1
Danke - Ich habe dies mit einer geringfügigen Änderung verwendet, indem ich die Fragmentansicht (dh das Ergebnis von inflater.inflate (R.layout.my_fragment_xml_resource)) an onLoginClicked () übergebe, damit sie auf die Fragment-Unteransichten zugreifen kann. Beispiel: Ein EditText über view.findViewById () (Wenn ich einfach die Aktivitätsansicht durchlaufe, geben Aufrufe von view.findViewById (R.id.myfragmentwidget_id) null zurück.)
Michael Nelson
Dies funktioniert nicht mit API 21 in meinem Projekt. Irgendwelche Gedanken zur Verwendung dieses Ansatzes?
Darth Coder
Es ist ein ziemlich einfacher Code, der in so ziemlich jeder App verwendet wird. Können Sie beschreiben, was für Sie passiert?
Brill Pappin
1
Stimmen Sie dieser Antwort zu, um das Problem zu erklären, das aufgetreten ist, weil das Layout des Fragments an die Ansicht der Aktivität angehängt ist.
fllo
25

Ich habe dieses Problem kürzlich gelöst, ohne der Kontextaktivität eine Methode hinzufügen oder OnClickListener implementieren zu müssen. Ich bin mir nicht sicher, ob es auch keine "gültige" Lösung ist, aber es funktioniert.

Beyogen auf: https://developer.android.com/tools/data-binding/guide.html#binding_events

Dies kann mit Datenbindungen erfolgen: Fügen Sie einfach Ihre Fragmentinstanz als Variable hinzu, und Sie können eine beliebige Methode mit onClick verknüpfen.

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.testapp.fragments.CustomFragment">

    <data>
        <variable android:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
    </data>
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_place_black_24dp"
            android:onClick="@{() -> fragment.buttonClicked()}"/>
    </LinearLayout>
</layout>

Und der Fragmentverknüpfungscode wäre ...

public class CustomFragment extends Fragment {

    ...

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_person_profile, container, false);
        FragmentCustomBinding binding = DataBindingUtil.bind(view);
        binding.setFragment(this);
        return view;
    }

    ...

}
Aldo Canepa
quelle
1
Ich habe nur das Gefühl, einige Details fehlen, da ich diese Lösung nicht zum
Laufen bringen kann
Vielleicht fehlt Ihnen etwas aus der "Build-Umgebung" in der Dokumentation: developer.android.com/tools/data-binding/…
Aldo Canepa
@Aldo Für die onClick-Methode in XML sollten Sie stattdessen Android haben: onClick = "@ {() -> fragment. ButtonClicked ()}". Auch für andere sollten Sie die Funktion buttonClicked () innerhalb des Fragments deklarieren und Ihre Logik darin einfügen.
Hayk Nahapetyan
in der xml sollte es seinandroid:name="fragment" android:type="com.example.testapp.fragments.CustomFragment"/>
COYG
1
Ich habe es gerade versucht und die Attribute nameund typedes variableTags sollten nicht das android:Präfix haben. Vielleicht gibt es eine alte Version von Android-Layouts, die dies erfordert?
Johnny Lambada
6

ButterKnife ist wahrscheinlich die beste Lösung für das Problem der Unordnung. Es verwendet Anmerkungsprozessoren, um den so genannten Boilerplate-Code der "alten Methode" zu generieren.

Die onClick-Methode kann jedoch weiterhin mit einem benutzerdefinierten Inflator verwendet werden.

Wie benutzt man

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup cnt, Bundle state) {
    inflater = FragmentInflatorFactory.inflatorFor(inflater, this);
    return inflater.inflate(R.layout.fragment_main, cnt, false);
}

Implementierung

public class FragmentInflatorFactory implements LayoutInflater.Factory {

    private static final int[] sWantedAttrs = { android.R.attr.onClick };

    private static final Method sOnCreateViewMethod;
    static {
        // We could duplicate its functionallity.. or just ignore its a protected method.
        try {
            Method method = LayoutInflater.class.getDeclaredMethod(
                    "onCreateView", String.class, AttributeSet.class);
            method.setAccessible(true);
            sOnCreateViewMethod = method;
        } catch (NoSuchMethodException e) {
            // Public API: Should not happen.
            throw new RuntimeException(e);
        }
    }

    private final LayoutInflater mInflator;
    private final Object mFragment;

    public FragmentInflatorFactory(LayoutInflater delegate, Object fragment) {
        if (delegate == null || fragment == null) {
            throw new NullPointerException();
        }
        mInflator = delegate;
        mFragment = fragment;
    }

    public static LayoutInflater inflatorFor(LayoutInflater original, Object fragment) {
        LayoutInflater inflator = original.cloneInContext(original.getContext());
        FragmentInflatorFactory factory = new FragmentInflatorFactory(inflator, fragment);
        inflator.setFactory(factory);
        return inflator;
    }

    @Override
    public View onCreateView(String name, Context context, AttributeSet attrs) {
        if ("fragment".equals(name)) {
            // Let the Activity ("private factory") handle it
            return null;
        }

        View view = null;

        if (name.indexOf('.') == -1) {
            try {
                view = (View) sOnCreateViewMethod.invoke(mInflator, name, attrs);
            } catch (IllegalAccessException e) {
                throw new AssertionError(e);
            } catch (InvocationTargetException e) {
                if (e.getCause() instanceof ClassNotFoundException) {
                    return null;
                }
                throw new RuntimeException(e);
            }
        } else {
            try {
                view = mInflator.createView(name, null, attrs);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        TypedArray a = context.obtainStyledAttributes(attrs, sWantedAttrs);
        String methodName = a.getString(0);
        a.recycle();

        if (methodName != null) {
            view.setOnClickListener(new FragmentClickListener(mFragment, methodName));
        }
        return view;
    }

    private static class FragmentClickListener implements OnClickListener {

        private final Object mFragment;
        private final String mMethodName;
        private Method mMethod;

        public FragmentClickListener(Object fragment, String methodName) {
            mFragment = fragment;
            mMethodName = methodName;
        }

        @Override
        public void onClick(View v) {
            if (mMethod == null) {
                Class<?> clazz = mFragment.getClass();
                try {
                    mMethod = clazz.getMethod(mMethodName, View.class);
                } catch (NoSuchMethodException e) {
                    throw new IllegalStateException(
                            "Cannot find public method " + mMethodName + "(View) on "
                                    + clazz + " for onClick");
                }
            }

            try {
                mMethod.invoke(mFragment, v);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new AssertionError(e);
            }
        }
    }
}
sergio91pt
quelle
6

Ich würde mich lieber für die Klickbehandlung im Code entscheiden, als das onClickAttribut in XML zu verwenden, wenn ich mit Fragmenten arbeite.

Dies wird noch einfacher, wenn Sie Ihre Aktivitäten in Fragmente migrieren. Sie können den Click-Handler (zuvor android:onClickin XML festgelegt) direkt von jedem caseBlock aus aufrufen .

findViewById(R.id.button_login).setOnClickListener(clickListener);
...

OnClickListener clickListener = new OnClickListener() {
    @Override
    public void onClick(final View v) {
        switch(v.getId()) {
           case R.id.button_login:
              // Which is supposed to be called automatically in your
              // activity, which has now changed to a fragment.
              onLoginClick(v);
              break;

           case R.id.button_logout:
              ...
        }
    }
}

Wenn es darum geht, Klicks in Fragmenten zu verarbeiten, sieht das für mich einfacher aus als android:onClick.

Ronnie
quelle
5

Dies ist ein anderer Weg:

1.Erstellen Sie ein BaseFragment wie folgt:

public abstract class BaseFragment extends Fragment implements OnClickListener

2.Verwenden

public class FragmentA extends BaseFragment 

anstatt

public class FragmentA extends Fragment

3.In Ihrer Tätigkeit:

public class MainActivity extends ActionBarActivity implements OnClickListener

und

BaseFragment fragment = new FragmentA;

public void onClick(View v){
    fragment.onClick(v);
}

Ich hoffe es hilft.

Euporie
quelle
1 Jahr, 1 Monat und 1 Tag nach Ihrer Antwort: Gibt es einen anderen Grund, als die Implementierung von OnClickListener für jede Fragment-Klasse nicht zu wiederholen, um das abstrakte BaseFragment zu erstellen?
Dimitrios K.
5

In meinem Anwendungsfall habe ich 50 ungerade ImageViews, die ich zum Einbinden in eine einzelne onClick-Methode benötigte. Meine Lösung besteht darin, die Ansichten innerhalb des Fragments zu durchlaufen und für jeden den gleichen On-Click-Listener festzulegen:

    final View.OnClickListener imageOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            chosenImage = ((ImageButton)v).getDrawable();
        }
    };

    ViewGroup root = (ViewGroup) getView().findViewById(R.id.imagesParentView);
    int childViewCount = root.getChildCount();
    for (int i=0; i < childViewCount; i++){
        View image = root.getChildAt(i);
        if (image instanceof ImageButton) {
            ((ImageButton)image).setOnClickListener(imageOnClickListener);
        }
    }
Chris Knight
quelle
2

Wie ich Antworten sehe, sind sie irgendwie alt. Kürzlich Google vorstellen Databinding , die viel einfacher zu handhaben onClick oder Zuweisung in Ihrem xml.

Hier ist ein gutes Beispiel, wie Sie damit umgehen können:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="handlers" type="com.example.Handlers"/>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
           android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
           android:onClick="@{user.isFriend ? handlers.onClickFriend : handlers.onClickEnemy}"/>
   </LinearLayout>
</layout>

Es gibt auch sehr schön Tutorial über Databinding Sie sie finden können hier .

Amir
quelle
2

Sie können einen Rückruf als Attribut Ihres XML-Layouts definieren. Der Artikel Benutzerdefinierte XML-Attribute für Ihre benutzerdefinierten Android-Widgets zeigt Ihnen, wie Sie dies für ein benutzerdefiniertes Widget tun. Gutschrift geht an Kevin Dion :)

Ich untersuche, ob ich der Basisfragmentklasse stilbare Attribute hinzufügen kann.

Die Grundidee besteht darin, dieselbe Funktionalität zu haben, die View beim Umgang mit dem onClick-Rückruf implementiert.

Nelson Ramirez
quelle
1

Hinzufügen zu Blundells Antwort:
Wenn Sie mehr Fragmente haben, mit vielen onClicks:

Aktivität:

Fragment someFragment1 = (Fragment)getFragmentManager().findFragmentByTag("someFragment1 "); 
Fragment someFragment2 = (Fragment)getFragmentManager().findFragmentByTag("someFragment2 "); 
Fragment someFragment3 = (Fragment)getFragmentManager().findFragmentByTag("someFragment3 "); 

...onCreate etc instantiating your fragments

public void myClickMethod(View v){
  if (someFragment1.isVisible()) {
       someFragment1.myClickMethod(v);
  }else if(someFragment2.isVisible()){
       someFragment2.myClickMethod(v);
  }else if(someFragment3.isVisible()){
       someFragment3.myClickMethod(v); 
  }

} 

In deinem Fragment:

  public void myClickMethod(View v){
     switch(v.getid()){
       // Just like you were doing
     }
  } 
amalBit
quelle
1

Wenn Sie sich mit android in Onml registrieren: Onclick = "", wird die respektierte Aktivität zurückgerufen, zu deren Kontext Ihr Fragment gehört (getActivity ()). Wenn eine solche Methode in der Aktivität nicht gefunden wird, löst das System eine Ausnahme aus.

Isham
quelle
danke, niemand anderes hat erklärt, warum der Absturz aufgetreten ist
1

Möglicherweise möchten Sie EventBus für entkoppelte Ereignisse verwenden. Sie können sehr einfach auf Ereignisse warten. Sie können auch sicherstellen, dass das Ereignis im UI-Thread empfangen wird (anstatt runOnUiThread .. für jedes Ereignisabonnement selbst aufzurufen).

https://github.com/greenrobot/EventBus

von Github:

Android-optimierter Ereignisbus, der die Kommunikation zwischen Aktivitäten, Fragmenten, Threads, Diensten usw. vereinfacht. Weniger Code, bessere Qualität

Programmierer
quelle
1

Ich möchte die Antwort von Adjorn Linkz ergänzen .

Wenn Sie mehrere Handler benötigen, können Sie einfach Lambda-Referenzen verwenden

void onViewCreated(View view, Bundle savedInstanceState)
{
    view.setOnClickListener(this::handler);
}
void handler(View v)
{
    ...
}

Der Trick dabei ist, dass handlerdie Signatur der Methode mit der Signatur übereinstimmt View.OnClickListener.onClick. Auf diese Weise benötigen Sie die View.OnClickListenerSchnittstelle nicht.

Außerdem benötigen Sie keine switch-Anweisungen.

Leider ist diese Methode nur auf Schnittstellen beschränkt, für die eine einzelne Methode oder ein Lambda erforderlich ist.

Dragas
quelle
1

Obwohl ich einige nette Antworten gefunden habe, die sich auf die Datenbindung stützen, habe ich bei diesem Ansatz keine vollständigen Antworten gesehen - im Sinne einer Aktivierung der Fragmentauflösung bei gleichzeitiger Berücksichtigung fragmentfreier Layoutdefinitionen in XMLs.

Vorausgesetzt also Datenbindung ist aktiviert, ist hier eine generische Lösung , die ich vorschlagen kann; Ein bisschen lang, aber es funktioniert definitiv (mit einigen Einschränkungen):

Schritt 1: Benutzerdefinierte OnClick-Implementierung

Dadurch wird eine fragmentbezogene Suche in Kontexten ausgeführt, die mit der angeklickten Ansicht verknüpft sind (z. B. Schaltfläche):


// CustomOnClick.kt

@file:JvmName("CustomOnClick")

package com.example

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import java.lang.reflect.Method

fun onClick(view: View, methodName: String) {
    resolveOnClickInvocation(view, methodName)?.invoke(view)
}

private data class OnClickInvocation(val obj: Any, val method: Method) {
    fun invoke(view: View) {
        method.invoke(obj, view)
    }
}

private fun resolveOnClickInvocation(view: View, methodName: String): OnClickInvocation? =
    searchContexts(view) { context ->
        var invocation: OnClickInvocation? = null
        if (context is Activity) {
            val activity = context as? FragmentActivity
                    ?: throw IllegalStateException("A non-FragmentActivity is not supported (looking up an onClick handler of $view)")

            invocation = getTopFragment(activity)?.let { fragment ->
                resolveInvocation(fragment, methodName)
            }?: resolveInvocation(context, methodName)
        }
        invocation
    }

private fun getTopFragment(activity: FragmentActivity): Fragment? {
    val fragments = activity.supportFragmentManager.fragments
    return if (fragments.isEmpty()) null else fragments.last()
}

private fun resolveInvocation(target: Any, methodName: String): OnClickInvocation? =
    try {
        val method = target.javaClass.getMethod(methodName, View::class.java)
        OnClickInvocation(target, method)
    } catch (e: NoSuchMethodException) {
        null
    }

private fun <T: Any> searchContexts(view: View, matcher: (context: Context) -> T?): T? {
    var context = view.context
    while (context != null && context is ContextWrapper) {
        val result = matcher(context)
        if (result == null) {
            context = context.baseContext
        } else {
            return result
        }
    }
    return null
}

Hinweis: basiert lose auf der ursprünglichen Android-Implementierung (siehe https://android.googlesource.com/platform/frameworks/base/+/a175a5b/core/java/android/view/View.java#3025 )

Schritt 2: Deklarative Anwendung in Layoutdateien

Dann in datenbindungsbewussten XMLs:

<layout>
  <data>
     <import type="com.example.CustomOnClick"/>
  </data>

  <Button
    android:onClick='@{(v) -> CustomOnClick.onClick(v, "myClickMethod")}'
  </Button>
</layout>

Vorsichtsmaßnahmen

  • Nimmt eine "moderne" FragmentActivityImplementierung an
  • Kann nur Lookup - Methode von „top-most“ (dh letzten ) Fragment in Stapeln (obwohl das kann festgelegt werden, wenn nötig)
d4vidi
quelle
0

Das hat 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
Vinod Joshi
quelle
1
Dies dupliziert die Antwort von @Brill Pappin .
NaXa
0

Beste Lösung IMHO:

im Fragment:

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 Fragment's onViewStateRestored:

addClick(R.id.myButton);
user4806368
quelle
0

Ihre Aktivität erhält den Rückruf wie folgt:

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

Wenn Sie möchten, dass Ihr Fragment einen Rückruf erhält, gehen Sie folgendermaßen vor:

mViewPagerCloth.setOnClickListener(this);

und onClickListenerSchnittstelle auf Fragment implementieren

ColdFusion
quelle