Я не могу понять, как передать параметры из деятельности в пользовательский вид - PullRequest
0 голосов
/ 12 июня 2019

Я новичок в программировании на Android и не могу понять, как передавать параметры между действием и пользовательским представлением. Моя деятельность реализует только пользовательское представление, я использую метод get в пользовательском представлении для передачи строки. Строка используется для установки имени игрока в текстовом представлении. Печать строки в методе setPlayerName, кажется, передана правильно, но в действительности, когда я иду выполнять метод changeTurn (), переменная mPlayerName имеет значение null. Я не могу понять почему.

Это моя деятельность

public class GameActivity extends AppCompatActivity {
    private GameMap gameMap;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        gameMap = new GameMap(this, "MYNAME");
        gameMap.setPlayerName("MYNAME");
        setContentView(R.layout.activity_game);
    }
}

Это мой пользовательский вид

public class GameMap extends RelativeLayout {
    private String mPlayerName;
    private TextView tv;
    private int turn;


    public GameMap(Context context, String playerName) {
        super(context);
        init(context,playerName);
    }

    public GameMap(Context context, AttributeSet attrs, String playerName) {
        super(context, attrs);
        init(context, playerName);
    }

    public GameMap(Context context, AttributeSet attrs, int defStyleAttr, String playerName) {
        super(context, attrs, defStyleAttr);
        init(context, playerName);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public GameMap(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, String playerName) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context, playerName);
    }

    private void init(Context context){
        View rootView = inflate(context,R.layout.game_custom_layout,this);
        tv = rootView.findViewById(R.id.turno);
        turn = 0;
        if(turn == 0) {
            //here mPLayerName is null
            tv.setText(mPlayerName);
        }
        else {
            tv.setText("CPU");
        }

        createMap();
    }


    private void createMap(){
        //I don't change mPLayerName here.
    }

    public void setPlayerName(String playerName){
        this.mPlayerName = playerName;
        System.out.println("string " + playerName + "mPLayerName " +mPlayerName);
        //here playerName and mPlayerName are not null but there is the correct string
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        //draw the map, don't edit mPlayerName
    }



    private void changeTurn(){
        if(turn == 0) {
            turn = 1;
            tv.setText("CPU");

        }
        else {
            turn = 0;
            System.out.println("player name " + mPlayerName);
            tv.setText(mPlayerName); 
            //here mPlayerName is null
        }
    }

    private void movePlayer(int x, int y, float newX, float newY){
      if(/*a specific condition */){
        invalidate();
        return;
      }
      changeTurn();
      invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            movePlayer(cellX, cellY, newX, newY);
            return true;
        }
        if(event.getAction() == MotionEvent.ACTION_MOVE)
            return false;

        return super.onTouchEvent(event);
    }
}

Я изменил код конструктора и получаю сообщение об ошибке

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.game.project, PID: 24310
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.game.project/com.game.project.GameActivity}: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class com.crossthebox.progetto.GameMap
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
 Caused by: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class com.game.project.GameMap
 Caused by: android.view.InflateException: Binary XML file line #10: Error inflating class com.game.project.GameMap
 Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
    at java.lang.Class.getConstructor0(Class.java:2327)
    at java.lang.Class.getConstructor(Class.java:1725)
    at android.view.LayoutInflater.createView(LayoutInflater.java:615)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:790)
    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:730)
    at android.view.LayoutInflater.rInflate(LayoutInflater.java:863)
    at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:824)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:515)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:423)
    at android.view.LayoutInflater.inflate(LayoutInflater.java:374)
    at android.support.v7.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:469)
    at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:140)
    at com.game.project.GameActivity.onCreate(GameActivity.java:22) // this is setContentView(R.layout.activity_game);
    at android.app.Activity.performCreate(Activity.java:7136)
    at android.app.Activity.performCreate(Activity.java:7127)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loop(Looper.java:193)
    at android.app.ActivityThread.main(ActivityThread.java:6669)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

это макет

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"
    tools:context=".GameActivity">


    <com.game.project.GameMap
        android:id="@+id/gameMapView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

1 Ответ

0 голосов
/ 12 июня 2019

В вашем методе init вы вызываете переменную mPlayerName до того, как mPlayerName будет установлено, так что вы получите ноль String.

Чтобы решить эту проблему, вы можете создать конструктор, который принимает другой параметр, который является playerName.

public GameMap(Context context, String playerName) {
    super(context);
    mPlayerName = playerName;
    init(context);
}

С помощью приведенного выше кода ваш mPlayerName будет установлен до вызова метода init, поэтому tv установит правильное значение String.

...