将回调函数作为参数传递给抽象的 setOnClickListener 方法在 Android 中。

huangapple 未分类评论60阅读模式
英文:

Pass a callback as a parameter to abstract setOnClickListener in Android

问题

public interface Callback {
    void execute(Button button);
}

protected void addClickListener(final Button button, final Callback callback) {
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            callback.execute(button);
        }
    });
}

protected Callback numberActions(Button button) {
    return new Callback() {
        @Override
        public void execute(Button button) {
            String value = button.getText().toString();
            setDisplay(value);
        }
    };
}

protected void setDisplay(String value) {
    String newValue;
    displayValue = resultDisplay.getText().toString();
    if (displayValue.length() < 10) {
        newValue = resultDisplay.getText() + value;
        resultDisplay.setText(newValue);
        displayValue = newValue;
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button numberButtons[] = new Button[11];
    numberButtons[0] = (Button) findViewById(R.id.numberOne);
    numberButtons[1] = (Button) findViewById(R.id.numberTwo);
    numberButtons[2] = (Button) findViewById(R.id.numberTwo);
    numberButtons[3] = (Button) findViewById(R.id.numberThree);
    numberButtons[4] = (Button) findViewById(R.id.numberFour);
    numberButtons[5] = (Button) findViewById(R.id.numberFive);
    numberButtons[6] = (Button) findViewById(R.id.numberSix);
    numberButtons[7] = (Button) findViewById(R.id.numberSeven);
    numberButtons[8] = (Button) findViewById(R.id.numberEight);
    numberButtons[9] = (Button) findViewById(R.id.numberNine);
    numberButtons[10] = (Button) findViewById(R.id.numberZero);

    resultDisplay = (TextView) findViewById(R.id.resultDisplay);

    for (Button button : numberButtons) {
        addClickListener(button, numberActions(button));
    }
}

(Note: I've corrected the duplication in numbering the buttons, and I've added the missing return statement in the numberActions method by creating an anonymous class implementing the Callback interface.)

英文:
 public interface Callback {
    void execute(Button button);
}

protected void addClickListener(final Button button, final Callback callback) {
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            callback.execute(button);
        }
    });
}

protected Callback numberActions(Button button) {
    String value = button.getText().toString();
    setDisplay(value);
}

protected void setDisplay (String value) {
        String newValue;
        displayValue = resultDisplay.getText().toString();
        if (displayValue.length() &lt; 10){
            newValue = resultDisplay.getText() + value;
            resultDisplay.setText(newValue);
            displayValue = newValue;
        }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button numberButtons[] = new Button[11];
        numberButtons[0] = (Button) findViewById(R.id.numberOne);
        numberButtons[1] = (Button) findViewById(R.id.numberTwo);
        numberButtons[2] = (Button) findViewById(R.id.numberTwo);
        numberButtons[3] = (Button) findViewById(R.id.numberThree);
        numberButtons[4] = (Button) findViewById(R.id.numberFour);
        numberButtons[5] = (Button) findViewById(R.id.numberFive);
        numberButtons[6] = (Button) findViewById(R.id.numberSix);
        numberButtons[7] = (Button) findViewById(R.id.numberSeven);
        numberButtons[8] = (Button) findViewById(R.id.numberEight);
        numberButtons[9] = (Button) findViewById(R.id.numberNine);
        numberButtons[10] = (Button) findViewById(R.id.numberZero);

        resultDisplay = (TextView) findViewById(R.id.resultDisplay);

        for (Button button: numberButtons) {
            addClickListener(button, numberActions(button));
        }
}

I'm building a simple calculator on Android Studio with Java.

Instead of calling setOnClickListener to each instance of a button, I have created addClickListiner to abstract it. So for example, I create an array of number buttons and on the onClick function I define that they should change Input display as an action. My goal is to use addClickListener to each button, then I can pass an action as a second parameter (callback) which will define what action that button will perform.

Actually I'm a javascript developer, and that would be as simple as just passing a function as a parameter. As I'm learning Java, I don't know how to perform it... My goal is to pass a void function as a parameter to perform it whenever the button is clicked.

I have tried to create a public interface... But when I try to build it, it breaks saying that I should have a return statement on numberActions method. Can anyone help me with how to pass a callback function as params on this case?

答案1

得分: 0

你可以尝试这样做:

for (Button button : numberButtons) {
    button.setOnClickListener(this);
}

实现View.OnClickListener接口。然后在你的activity/fragment中:

@Override
public void onClick(View v) {

    Button button = (Button) v;

    switch (v.getId()) {

    case R.id.numberOne:
        String value = button.getText().toString();
        setDisplay(value);
        break;
    }
}
英文:

You can try this

for (Button button : numberButtons) {
       button.setOnClickListener = this;
}

Implement the View.OnClickListener interface. Then in your activity/fragment

@Override
public void onClick(View v) {

    Button button= (Button) v

    switch(v.getId()){
    
    case R.id.numberOne:
       String value = button.getText().toString();
       setDisplay(value);
       break;
    }
}

答案2

得分: 0

// 使用一个 Consumer<Button> 作为回调函数,以便在按钮被点击时执行相应操作

您可以通过使用 [`Consumer<Button>`][1] 作为回调来实现这一目标如果您有一些动作按钮例如 "+""-"以及带有数字的按钮那么您的 `numberActions()` 方法可以按照以下方式工作

```java
private Consumer<Button> add = new Consumer<Button>() {
    @Override
    public void accept(Button button) {
        Toast.makeText(MainActivity.this, "'Add' 尚未实现", Toast.LENGTH_SHORT).show();
    }
};

private Consumer<Button> subtract = new Consumer<Button>() {
    @Override
    public void accept(Button button) {
        Toast.makeText(MainActivity.this, "'Subtract' 尚未实现", Toast.LENGTH_SHORT).show();
    }
};

protected Consumer<Button> numberActions(Button button) {
    final String value = button.getText().toString();
    switch (value){
        case "+":
            return add;
        case "-":
            return subtract;
        default: // 必须是数字
            return new Consumer<Button>(){
                @Override
                public void accept(Button button) {
                    setDisplay(value);
                }
            };
    }
}

<details>
<summary>英文:</summary>

&gt;My goal is to pass a void function as a parameter to perform it whenever the button is clicked

You can achieve this by using a [`Consumer&lt;Button&gt;`][1] as callback. If you have some action buttons (e.g. &quot;+&quot;, &quot;-&quot;) as well as buttons with digits then your method `numberActions()` could work like this:

    private Consumer&lt;Button&gt; add = new Consumer&lt;Button&gt;() {
        @Override
        public void accept(Button button) {
            Toast.makeText(MainActivity.this, &quot;&#39;Add&#39; not yet implemented&quot;, Toast.LENGTH_SHORT).show();
        }
    };

    private Consumer&lt;Button&gt; subtract = new Consumer&lt;Button&gt;() {
        @Override
        public void accept(Button button) {
            Toast.makeText(MainActivity.this, &quot;&#39;Subtract&#39; not yet implemented&quot;, Toast.LENGTH_SHORT).show();
        }
    };

    protected Consumer&lt;Button&gt; numberActions(Button button) {
        final String value = button.getText().toString();
        switch (value){
            case &quot;+&quot;:
                return add;
            case &quot;-&quot;:
                return subtract;
            default: // must be a digit
                return new Consumer&lt;Button&gt;(){
                    @Override
                    public void accept(Button button) {
                        setDisplay(value);
                    }
                };
        }
    }

  [1]: https://developer.android.com/reference/androidx/core/util/Consumer

</details>



huangapple
  • 本文由 发表于 2020年4月6日 01:46:27
  • 转载请务必保留本文链接:https://java.coder-hub.com/61046851.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定