Android-invalidate()不会在CustomView中调用我的onDraw

时间:2019-08-07 06:57:47

标签: android

我有一个content_main.xml:

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <com.example.CustomView
        android:id="@+id/customView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout >

在MainActivity.java中的onCreate中,我称为CustomView:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    customView = new CustomView(this, attributeSet);
    customView.init();
}

在CustomView中,我有一个onDraw:

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.BLUE);
    drawValidMoves(canvas, squareSize);
}

在MainActivity中,onTouch

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN) {
        int x = (int)event.getX();
        int y = (int)event.getY();

        String text = customView.isTouched(x, y, customView.getSquareSize());
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }
    return super.onTouchEvent(event);
}

正在从CustomView.java中调用一个方法-isTouched,它会更改绘制的元素矩阵中的某些内容,然后,我要做一些:

  setWillNotDraw(false);
  invalidate();

但是我的游戏再也无法达到onDraw了... 如果我直接在onCreate上调用CustomView,则无效方法起作用:

customView = new CustomView(this, attributeSet);
customView.init();
setContentView(customView);

但是我没有工具栏了,我需要

最新编辑:

content_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linearLayoutId"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <com.example.clotz.CustomView
        android:id="@+id/customView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout >

MainActivity.java-onCreate-我将数据从init方法移到了构造函数中,并摆脱了init。

public class MainActivity extends AppCompatActivity {

    CustomView customView;

    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        customView = findViewById(R.id.customView);
    }

但是onTouchEvent中的customView现在为空:

@Override
public boolean onTouchEvent(MotionEvent event) {
    if(event.getAction() == MotionEvent.ACTION_DOWN) {
        int x = (int)event.getX();
        int y = (int)event.getY();

        String text = customView.isTouched(x, y, customView.getSquareSize());
        Toast.makeText(this, text, Toast.LENGTH_LONG).show();
    }
    return super.onTouchEvent(event);
}

2 个答案:

答案 0 :(得分:1)

@Mike M为此提供了帮助,我将linearLayout的ID放在content_main.xml中。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/linearLayoutId"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:context=".MainActivity"
    tools:showIn="@layout/activity_main">

    <com.example.clotz.CustomView
        android:id="@+id/customView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout >

在MainActivity.java中-onCreate(我将数据从init方法移至构造函数中并摆脱了init),并使用findViewById(R.id.customView)创建了customview;

public class MainActivity extends AppCompatActivity {

    CustomView customView;

    @SuppressLint("WrongViewCast")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        customView = findViewById(R.id.customView);
    }

问题出在CustomView.java中,我忘了将attributeSet传递给超类:

public CustomView(Context context, AttributeSet attributeSet) {
    super(context);

    initializeMovedMatrix();
    setInitialPositionForPieces();
    // create the Paint to set its color
    paint = new Paint();
    piecesMoves = new PiecesMoves(this);
}

并将其与customView = findViewById(R.id.customView);

结合在一起
super(context, attributeSet);

解决了问题。 再次感谢MikeM!

答案 1 :(得分:0)

您无法在onDraw方法中删除super.onDraw(canvas)

@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawColor(Color.BLUE);
    drawValidMoves(canvas, squareSize);
}