如何从自定义视图的类中更改textview

时间:2016-02-05 13:54:03

标签: android view textview android-custom-view

我们假设我在一个活动中有一个自定义视图,而在该自定义视图下方有一个TextView。我想在点击自定义视图后更改TextView的文本但我在使用findViewById()时似乎得到一个空指针,那么我该怎么办呢?

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.yuvaleliav1gmail.quoridor_ye.MainActivity"
    android:background="#dd7d23">


    <com.yuvaleliav1gmail.quoridor_ye.ComBoardView
        android:layout_width="900px"
        android:layout_height="900px"
        android:id="@+id/bview"
        android:background="@drawable/game_board"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

    <RadioGroup
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/radioGroup"
        android:layout_below="@+id/bview"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true">

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Move Pawn"
            android:id="@+id/radioPawn"
            android:checked="true"
            android:onClick="radioButtonClick"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Set VERTICAL Wall"
            android:id="@+id/verticalRdio"
            android:checked="false"
            android:onClick="radioButtonClick"/>

        <RadioButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Set HORIZONTAL Wall"
            android:id="@+id/horizontalRdio"
            android:checked="false"
            android:onClick="radioButtonClick"/>

    </RadioGroup>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Your turn"
        android:id="@+id/turnText34"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/radioGroup"
        android:layout_alignLeft="@+id/bview"
        android:layout_alignStart="@+id/bview" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Your walls left: "
        android:id="@+id/yourWallsText"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/turnText34"
        android:layout_alignLeft="@+id/turnText34"
        android:layout_alignStart="@+id/turnText34" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="10"
        android:id="@+id/yourNumText"
        android:layout_gravity="center_horizontal"
        android:layout_alignTop="@+id/yourWallsText"
        android:layout_toRightOf="@+id/yourWallsText"
        android:layout_toEndOf="@+id/yourWallsText" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Opponent&apos;s walls left:"
        android:id="@+id/opWallsText"
        android:layout_gravity="center_horizontal"
        android:layout_below="@+id/yourWallsText"
        android:layout_alignLeft="@+id/yourWallsText"
        android:layout_alignStart="@+id/yourWallsText" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="10"
        android:id="@+id/opNumText"
        android:layout_gravity="center_horizontal"
        android:layout_alignTop="@+id/opWallsText"
        android:layout_toRightOf="@+id/opWallsText"
        android:layout_toEndOf="@+id/opWallsText" />


</RelativeLayout>

comBoardView是自定义视图的类

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.CountDownTimer;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

public class ComBoardView extends View {

      private static final int ROWS = 9;
      private static final int COLUMNS = 9;
      public static Context con;
      Paint paint;
      GameService game;
      TextView turns;
      public static Point size = new Point();
      /*
       * constructor
       */
      public ComBoardView(Context context, AttributeSet attrs) {
          super(context, attrs);
          con = context;
          paint = new Paint();
          WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
          Display display = wm.getDefaultDisplay();
          display.getSize(size);
          turns = (TextView) findViewById(R.id.turnText34);



      }
      /*

       */
      public boolean onTouchEvent( MotionEvent event ) {
          game = GameService.getInstance();
          int x = (int)event.getX() / 100;
          int y = (int)event.getY() / 100;
          if ( event.getAction() != MotionEvent.ACTION_UP )
                return true;
          if(game.movePawn){
              if(game.turn % 2 == 0){
                  if(game.isLegalMove(game.ai.MyLocation , y * ROWS + x)){
                      game.board.ClrPlayer(game.ai);
                      game.ai.MyLocation = y * ROWS + x;
                      game.board.SetPlayer(game.ai);
                      if(turns != null){
                          turns.setText("white's turn");
                      }
                      game.turn++;
                  }
              }
              else{
                  if(game.isLegalMove(game.player.MyLocation , y * ROWS + x)){
                      game.board.ClrPlayer(game.player);
                      game.player.MyLocation = y * ROWS + x;
                      game.board.SetPlayer(game.player);
                      if(turns != null){
                          turns.setText("black's turn");
                      }
                      game.turn++;
                  }
              }
          }
          else {
              if(((int)event.getX() % 100) < 50) x--;
              if(((int)event.getY() % 100) < 50) y--;
              if(game.setHWall){
                  game.board.SetHWall(y,x);
                  game.turn++;
              }
              else{
                  game.board.SetVWall(y,x);
                  game.turn++;
              }
          }

          return true;
      }

    public void RestartTimer() {
          new CountDownTimer(3500, 1000) {
                 public void onTick(long millisUntilFinished) {
                     final Toast toast = Toast.makeText(con, "restarting in: " + millisUntilFinished / 1000, Toast.LENGTH_LONG);
                        toast.show();
                            new Handler().postDelayed(new Runnable() {
                               @Override
                               public void run() {
                                   toast.cancel();
                               }
                        }, 1000);
                 }
                 public void onFinish() {

                 }
              }.start();
      }

      protected void onDraw(Canvas canvas) {
          paint.setAntiAlias(true);
          paint.setColor(Color.BLACK);
          GameService.getInstance().onDraw(canvas, paint);
      }

}

游戏是活动的类

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.RadioButton;

import java.util.Timer;

public class Game extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        Timer timer = new Timer();
        GameUpdateTimer ut = new GameUpdateTimer();
        ut.boardView = (ComBoardView)this.findViewById(R.id.bview);
        timer.schedule(ut, 200, 200);
        RadioButton pawn = (RadioButton)findViewById(R.id.radioPawn);
        RadioButton hWall = (RadioButton)findViewById(R.id.horizontalRdio);
        RadioButton vWall = (RadioButton)findViewById(R.id.verticalRdio);
        final GameService g = GameService.getInstance();


        pawn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                g.movePawn = true;
                g.setHWall = false;
        }});

        hWall.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                g.movePawn = false;
                g.setHWall = true;
            }
        });

        vWall.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                g.movePawn = false;
                g.setHWall = false;
            }
        });
    }
}

1 个答案:

答案 0 :(得分:1)

您无法从自定义视图中调用turns = (TextView) findViewById(R.id.turnText34);,因为TextView存在于活动xml中,而不是ComBoardView中,因此它将始终返回Null。

您可以做的是在活动中实例化TextView,然后将clickListener添加到ComBoardView

TextView turns;

@Override
protected void onCreate(Bundle savedInstanceState) {
     //...

     turns = (TextView) findViewById(R.id.turnText34);

     ut.boardView.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            turns.setText("ComBoardView was clicked!");
     }});

    //...

}