2017-04-09 7 views
0

Ich habe eine sehr einfache "CustomButton" -Klasse, die die Standardklasse "Button" erweitert. Mein CustomButton verwendet onTouchEvent und ich möchte eine Funktion von meiner Aktivität an den CustomButton übergeben und sie beim Aufsetzen ausführen lassen.Implementieren von Rückruf in erweiterbare Button-Klasse

Die CustomButton-Klasse funktioniert gut, aber ich kann nicht herausfinden, wie Sie eine Funktion an sie übergeben.

Aktivität:

public class mainActivity extends Activity 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     Context context = getApplicationContext(); 
     setContentView(R.layout.main); 

     LinearLayout root = (LinearLayout) findViewById(R.id.myLayout ); 
     View child1 = getLayoutInflater().inflate(R.layout.child, null); 

     // Define the button 
     final CustomButtom myCustomButton = (CustomButtom)child1.findViewById(R.id.button_id); 

     myCustomButtom.setCallback(test); // <-- I want to pass my 'test' function to CustomButton class, 
              //  so it can get executed by the onTouchEvent 

     root.addView(myCustomButton); 

     super.onCreate(savedInstanceState); 
    } 

    private int test() 
    { 
     Log.d("test", "Callback executed!"); 
    } 
} 

Und das ist meine Custombutton Klasse:

public class CustomButtom extends Button 
{ 
    private Function callback; 

    public CustomButtom(Context context, AttributeSet attrs) { 
     super(context, attrs); 

     this.setOnTouchListener 
     (
      new OnTouchListener() 
      { 
       @Override 
       public boolean onTouch(View v, MotionEvent event) 
       { 
        if(event.getAction() == MotionEvent.ACTION_DOWN) 
        { 
         executeCallback(); // <-- My callback would get executed from here 
        } 

        return true; 
       } 
      } 
     ); 

    } 

    public void setCallback(Function function) 
    { 
     callbackFunction = function; // Save the callback in a local variable 
    } 

    private boolean executeCallback() 
    { 
     return callbackFunction.execute(); // execute the callback 
    } 
} 

Gibt es eine ‚Datentyp‘ wie ‚Funktion‘, die ich für diesen Zweck verwenden können, oder gibt es unterschiedliche Wie erreiche ich das? Vielen Dank!

Antwort

0

Normalerweise benötigen Sie ein Objekt und eine Funktion, wenn Sie eine Aktion in Java ausführen möchten. Dafür stehen Schnittstellen. Sie deklarieren eine Schnittstelle mit dem Namen Ihrer Funktion. Ihre Aktivität implementiert diese Schnittstelle und die Funktion und Sie geben dann die Instanz Ihrer Aktivität an die Schaltfläche weiter. In Ihrem Fall suchen Sie wahrscheinlich nach OnTouchListener oder OnClickListener? Wenn Sie eine spezielle Schnittstelle haben möchten, können Sie dies auf die gleiche Weise deklarieren.

public class mainActivity extends Activity implements OnClickListener 
{ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     // I do not see any reason to use the Application Context here. Your Activity has the right context for your UI 
     // Context context = getApplicationContext(); 
     setContentView(R.layout.main); 

     LinearLayout root = (LinearLayout) findViewById(R.id.myLayout ); 
     View child1 = getLayoutInflater().inflate(R.layout.child, null); 

     // Define the button 
     final CustomButtom myCustomButton = (CustomButtom)child1.findViewById(R.id.button_id); 

     myCustomButtom.setOnClickListener(this); 

     root.addView(myCustomButton); 

     // you did this already 
     //super.onCreate(savedInstanceState); 
    } 

    public void onClick(View v) 
    { 
     Log.d("test", "Callback executed!"); 
    } 
} 

EDIT:

die Logik innerhalb der Schaltfläche, um Sie Ihre eigene Schnittstelle erstellen (OnClickListener ist eine Schnittstelle) wie folgt aus:

public interface OnCustomActionListener { 
    // you can remove the button as parameter if you do not care which button the action came from 
    void onCustomAction(CustomButton button); 
} 

public class CustomButtom extends Button { 
    OnCustomActionListener onCustomActionListener; 

    public void setOnCustomActionListener(OnCustomActionListener listener) { 
     this.onCustomActionListener = listener; 
    } 

    /* Creator like in your question mentioned */ 

    private boolean executeCallback() { 
     if (this.onCustomActionListener != null) { 
      this.onCustomActionListener.onCustomAction(this); 
     } 
    } 
} 

in Ihrer Aktivität:

public class mainActivity extends Activity implements OnCustomActionListener { 
... 
    myCustomButtom.setOnCustomActionListener(this); 
... 
public void onCustomAction(CustomButton button) { 
    // do something 
} 
+0

Danke für die Antwort. Das Problem ist, dass ich auch benutzerdefinierte "longpress" - und animationsbezogene Ereignisse habe, die zu ungewöhnlichen Zeiten (die innerhalb der CustomButton-Klasse liegen) ausgelöst werden. Wenn ich die Funktion CustomButton weitergeben könnte, könnte ich sie zu diesen ungeraden Zeiten auslösen. Mit diesem Ansatz müsste ich die Logik von CustomButton in Activity-> onClick-Ereignis verschieben oder kopieren (wenn ich das richtig verstanden habe). Kannst du mir bitte sagen, wie kann ich das tun, indem ich die Funktion "verlasse", anstatt die Buttons bei Click/onTouch-Events innerhalb der Aktivität zu fangen? oder ist dieser Ansatz unlogisch? Vielen Dank! – user7841697

+0

Zum Beispiel, wenn in ButtonClass-> onTouchEvent ausgelöst wird, wenn Benutzer die Schaltfläche für 3500ms gedrückt hält, sollte es einen Rückruf ausführen, wenn Benutzer die Schaltfläche hält und nach rechts verschiebt, sollte es einen weiteren Rückruf auslösen. Es wäre sehr effizient in Bezug auf die Entwicklung, wenn ich einfach meiner CustomButton-Klasse mitteilen könnte, welche Funktionen von der Hauptaktivität ausgelöst werden, dann würde ich die gesamte Ereignislogik in der CustomButton-Klasse haben und diese Callbacks auslösen, sobald die Animation ist vervollständigen Sie zum Beispiel. – user7841697

+0

Wenn die Logik von CustomButton mit der Schaltfläche verknüpft ist und möglicherweise sogar mehrmals verwendet wird, ist es logisch, diese Logik innerhalb der Schaltfläche zu behalten und eine neue Schnittstelle zu erstellen (OnClickListener ist eine Schnittstelle), die eine definierte Funktion hat, die in Ihrer Aktivität ausgeführt wird . Ich habe meine Antwort geändert – Christian