【问题标题】:Can anyone shed some light on why I cant get a variable from this class? [duplicate]任何人都可以解释为什么我不能从这个类中得到一个变量吗? [复制]
【发布时间】:2017-11-29 12:25:47
【问题描述】:

一段时间以来,我一直在尝试从 MySurfaceView 中获取一个变量以在我的 Player 类中使用。我似乎无法让它工作......我尝试从我的 MainActivity 类中获取触摸信息,但它并不是我真正想要的地方,而且似乎也无法让它工作。任何帮助表示赞赏!

MySurfaceView.java

package com.Frenchie.SurfaceView;

import ...

public class MySurfaceView extends SurfaceView implements Runnable {

    Bitmap bitmap;
    SurfaceHolder surfaceHolder;
    int LastTouchx;

    Player player;

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

        player = new Player(context);

        surfaceHolder = getHolder();

        //Starts the run()
        Thread TestThread = new Thread(this);
        TestThread.start();
    }


    @Override
    public void run() {
        //TODO movement here when display is working
        while (true){
            Update();
            DrawPlayer();
        }
    }

    public void Update(){
        player.Update();
    }

    public void DrawPlayer(){

        Canvas canvas = surfaceHolder.lockCanvas();

        if (surfaceHolder.getSurface().isValid()) {

            canvas.drawColor(Color.BLUE);
            canvas.drawBitmap(player.getBitmap(), player.getX(), player.getY(), null);
            surfaceHolder.unlockCanvasAndPost(canvas);
        }
        else{

            Log.d("DrawPlayer", "Surface Not Valid");
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        LastTouchx = (int)event.getX();
        //LastTouchy= (int)event.getY();
        Log.d("Touch Value ",LastTouchx+"");
        return false;
    }

    public int getLastTouchx() {
        return LastTouchx;
    }

}

Player.java

package com.Frenchie.SurfaceView;

import ...

public class Player {
    //Bitmap to get character from image
    private Bitmap bitmap;

    //coordinates
    private int x;
    private int y;

    //motion speed of the character
    private int speed = 0;

    MySurfaceView mySurfaceView;

    //constructor
    public Player(Context context) {
        x = 75;
        y = 500;

        //Getting bitmap from drawable resource
        bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.player);
    }

    //Method to update coordinate of character
    public void Update(){

        //updating x coordinate

        if (x > mySurfaceView.getLastTouchx()){
            x++;
        }
        else if (x < mySurfaceView.getLastTouchx()){
            x--;
        }
        else{

            Log.d("Update","Else triggered");
        }

    }

    public Bitmap getBitmap() {
        return bitmap;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }
}

消息

E/AndroidRuntime: FATAL EXCEPTION: Thread-4
    Process: com.Frenchie.SurfaceView, PID: 26348
    java.lang.NullPointerException: Attempt to invoke virtual method 'int com.Frenchie.SurfaceView.MySurfaceView.getLastTouchx()' on a null object reference
        at com.Frenchie.SurfaceView.Player.Update(Player.java:36)
        at com.Frenchie.SurfaceView.MySurfaceView.Update(MySurfaceView.java:68)
        at com.Frenchie.SurfaceView.MySurfaceView.run(MySurfaceView.java:62)
        at java.lang.Thread.run(Thread.java:762)

这不是建议的帖子的副本。

【问题讨论】:

    标签: java android class setter getter


    【解决方案1】:

    覆盖 MySurfaceView 中的另一个构造函数:

        public class MySurfaceView extends SurfaceView
        ...
        public MySurfaceView(Context context) {
            this(context, (AttributeSet)null)
        }
    
        public MySurfaceView(Context context, AttributeSet attributeSet) {
                super(context, attributeSet);
                player = new Player(context, this);
                bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.player);
                surfaceHolder = getHolder();
                //Starts the run()
                Thread TestThread = new Thread(this);
                TestThread.start();
            }
            ...
    

    在你的播放器的构造函数中你可以传递一个surfaceView:所以不需要初始化:

    MySurfaceView mySurfaceView;
    
        //constructor
        public Player(Context context, MySurfaceView surfaceView) {
            this.mySurfaceView = surfaceView;
            x = 75;
            ...
    

    【讨论】:

    • 非常感谢您!你能解释一下这是如何工作的吗?标记为正确答案。
    • @Frenchie 视图本身需要覆盖父级的构造函数。如果您在 xml 中声明了自定义视图,那么 OS 将调用具有两个或更多参数的构造函数之一。以编程方式,您使用简单的构造函数 View(context) 创建视图并使用 setter 设置属性。
    • @Frenchie 您的播放器类取决于您的表面视图,因此表面视图应该在您的播放器类中创建或使用构造函数注入,就像我在上面所做的那样。可能最好的方法是更改​​顺序并将您的逻辑放入 Player 并使 SurfaceView 简单
    【解决方案2】:

    试试:

     MySurfaceView mySurfaceView = new MySurfaceView();
    

    【讨论】:

    • 当我用这个替换我的播放器类中的原始调用时,我收到以下错误:错误:(19、35)错误:MySurfaceView 类中的构造函数 MySurfaceView 不能应用于给定类型;必需:上下文,找到属性集:没有参数原因:实际参数列表和正式参数列表的长度不同
    • 尝试在MySurfaceView.java中定义一个空的构造函数
    • 无论何时覆盖视图,都应该覆盖构造函数。在您的播放器中,您没有初始化 mySurfaceView
    • 你介意详细说明维克多吗,我不太明白。当我向 MySurfaceView 添加一个空的构造函数时,我也会收到以下消息:“'android.view.SurfaceView' 中没有可用的默认构造函数”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 2011-08-25
    • 1970-01-01
    • 2011-08-19
    • 2022-01-22
    • 2017-05-09
    相关资源
    最近更新 更多