【问题标题】:Implementing callback in extendable button class在可扩展按钮类中实现回调
【发布时间】:2017-04-09 20:58:53
【问题描述】:

我有一个非常简单的“CustomButton”类,它扩展了默认的“Button”类。我的 CustomButton 使用 onTouchEvent 并且我想将一个函数从我的 Activity 传递给 CustomButton 并让它在触地时执行。

CustomButton 类工作正常,但我似乎不知道如何将函数传递给它。

活动:

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!" );
    }
}

这是我的 CustomButton 类:

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
    }
}

是否有我可以用于此目的的“数据类型”,例如“功能”,或者有不同的方法来实现这一点?谢谢!

【问题讨论】:

    标签: java android extends


    【解决方案1】:

    当你想在 Java 中执行一个动作时,你通常需要一个对象和一个函数。这就是接口的用途。你用你的函数名声明一个接口。你的 Activity 实现了这个接口和函数,然后你将你的 Activity 实例传递给按钮。在您的情况下,您可能正在寻找 OnTouchListener 或 OnClickListener?如果你想有一个特殊的接口,你可以用同样的方式声明它。

    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!" );
        }
    }
    

    编辑:

    要保留按钮内部的逻辑,您可以创建自己的界面(OnClickListener 是一个界面),如下所示:

    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);
            }
        }
    }
    

    在您的活动中:

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

    【讨论】:

    • 感谢您的回复。问题是我还有自定义的“长按”和动画相关事件,这些事件在奇数时间触发(在 CustomButton 类中)。如果我可以传递函数 CustomButton,那么我可以在这些奇怪的时间触发它。使用这种方法,我必须将逻辑从 CustomButton 移动或复制到 Activity->onClick 事件(如果我理解正确的话)。您能否告诉我如何通过“传递”功能而不是在活动中捕获按钮 onClick/onTouch 事件来做到这一点?还是这种方法不合逻辑?谢谢!
    • 例如在ButtonClass->onTouchEvent内部触发时,如果用户按住按钮3500ms,那么它应该执行一个回调,如果用户按住按钮并向右滑动,它应该触发另一个打回来。这将是非常有效的开发方式,如果我可以简单地告诉我的 CustomButton 类从哪些事件的主要活动中触发哪些函数,那么我将在 CustomButton 类中拥有所有事件逻辑,并且一旦动画完成就会触发这些回调例如完成。
    • 如果 CustomButton 的逻辑与按钮相关,甚至可能被多次使用,那么将逻辑保留在按钮内部并创建一个定义了一个新接口(OnClickListener 是一个接口)是合乎逻辑的在您的活动中执行的功能。我修改了答案
    猜你喜欢
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 2012-06-06
    • 2018-04-29
    相关资源
    最近更新 更多