java - Android Canvas 和监听器

标签 java android canvas

我正在使用一个扩展 View 的类来创建 Canvas 。它的名称是 MyBringBack 类。在我的 MainActivity 类中,我以编程方式定义了一个布局。 MyBringBack 类中有一个公共(public)静态变量,我在 MyBringBack 类的某些部分更改了它的值。 是否可以知道该变量何时发生变化?我想通过使用此更改来更改 MainActivitiy 类中的某些内容。

在MainActivity类中

    setContentView(R.layout.activity_main);
    li = (LinearLayout) findViewById(R.id.canvasLayout);
    //This is where i have to bring the canvas  

    MyBringBack pcc = new MyBringBack (this);
    li.addView(pcc);

在 MyBringBack 类中

public static int score =0 ;

最佳答案

您可以(而且实际上应该)使用观察者模式来做到这一点。

您不需要将值设置为静态值,这实际上违反了封装原则。

我认为一些代码可能会让您更轻松,所以我将为您提供一个代码示例,但首先,一些解释:

  • 实现观察者模式的常见方法是使用接口(interface)作为观察者和可观察对象之间的契约者。
  • Observable 类将定义接口(interface)并创建一个 setter,允许任何实现此接口(interface)的类将自身注册为监听器。
  • 在观察者方面,我们实现了可观察对象的接口(interface),这样我们就可以实现一些方法。
  • 可观察对象将简单地检查是否有监听器,如果有,将通过接口(interface)方法通知所需的信息。

这里有一个例子来说明它是如何工作的:

public class MyBringBack extends View {

    // ----------------------------------
    // INTERFACES
    // ----------------------------------

    public interface BringBackListener {
        public abstract void onObservableValueChanged(int value);
    }

    // ----------------------------------
    // CONSTANTS
    // ----------------------------------

    private static final int VALUE_UPDATE_TIMEOUT = 1000;

    // ----------------------------------
    // ATTRIBUTES
    // ----------------------------------

    private int mObservableValue = 0;

    private static Handler mHandler;
    private static UpdateObservableValueRunnable mUpdateObservableValueRunnable;

    private BringBackListener mListener;

    // ----------------------------------
    // CONSTRUCTORS
    // ----------------------------------

    public MyBringBack(Context context) {
        super(context);
        initializeView();
    }

    public MyBringBack(Context context, AttributeSet attrs) {
        super(context, attrs);
        initializeView();
    }

    public MyBringBack(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initializeView();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public MyBringBack(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initializeView();
    }

    // ----------------------------------
    // PUBLIC METHODS
    // ----------------------------------

    public void setBringBackListener(BringBackListener listener) {
        mListener = listener;
    }

    // ----------------------------------
    // PRIVATE METHODS
    // ----------------------------------

    private void initializeView() {
        mHandler = new Handler();
        mUpdateObservableValueRunnable = new UpdateObservableValueRunnable();

        mHandler.postDelayed(mUpdateObservableValueRunnable, VALUE_UPDATE_TIMEOUT);
    }

    // ----------------------------------
    // NESTED CLASSES
    // ----------------------------------

    private class UpdateObservableValueRunnable implements Runnable {
        public void run() {
            mObservableValue++;
            if (mListener != null) {
                mListener.onObservableValueChanged(mObservableValue);
            }

            mHandler.postDelayed(mUpdateObservableValueRunnable, VALUE_UPDATE_TIMEOUT);
        }
    }; // UpdateObservableValue

}

在此自定义 View 中,我设置了每秒运行的可运行对象。它做了两件事:

  • 增加一个整数
  • 检查监听器是否设置为用此 int 的新值通知它。

现在这是一个示例 Activity ,它将观察此 View 的变化:

public class MainActivity extends ActionBarActivity implements BringBackListener {

    // ----------------------------------
    // ATTRIBUTES
    // ----------------------------------

    private TextView mResultTextView;

    // ----------------------------------
    // LYFECYCLE
    // ----------------------------------

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

        mResultTextView = (TextView) findViewById(R.id.resultTextView);
        LinearLayout li = (LinearLayout) findViewById(R.id.canvasLayout);

        MyBringBack pcc = new MyBringBack(this);
        li.addView(pcc);

        // Do not forget to set the listener (here it is the MainActivity 
        // since it implements BringBackListener)
        pcc.setBringBackListener(this);
    }

    // ----------------------------------
    // IMPLEMENTED METHODS
    // ----------------------------------

    @Override
    public void onObservableValueChanged(int value) {
        mResultTextView.setText(value + "");
    }
}

此 Activity 实现了 BringBackListener,因此我们必须实现 onObservableValueChanged(int value)。通过这个方法,Activity 能够观察到变化。

请注意, Activity 必须通过 MyBringBack 中定义的监听器 setter 来注册自身:setBringBackListener();

关于java - Android Canvas 和监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31095832/

相关文章:

java - 我知道 HashSet 内部工作方式与 HashMap 和 HashMap 内部工作方式相同

java - 无法在 opencv 4.1.0 中解析 DescriptorExtractor 和 FeatureDetector 的导入

java - 为什么我的 Spring Boot Autowiring JPA 存储库未能通过 JUnit 测试?

java - 有没有一种好方法可以将视频从 Android 流式传输到 RTSP 服务器?

android - 自定义 View 中的 EventBus

javascript - 在 Canvas View 上处理滚动 - paperjs

javascript - html2canvas 教程?

javascript - HTML5 Canvas 垂直翻转功能在 Firefox 中有效,但在 Chrome 或 Safari 中无效。为什么?

JavaFX 嵌套 GridPane 对齐

java - 我正在通过 Youtube 教程创建 map 搜索应用程序,但我的应用程序崩溃了