2016-02-05 74 views
0

假設我在自定義視圖下方有一個自定義視圖和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; 
      } 
     }); 
    } 
} 
+0

請放一些代碼! – Imdad

+0

向我們展示您的代碼,佈局和logcat。 –

+0

我不知道什麼或在哪裏lotcat):,這個想法是創造一個Quoridor遊戲。它只是與自定義視圖和文本視圖,我無法解決真的,所以我想通過解釋一切都會工作,因爲這麼多的代碼是不相關的問題.. –

回答

1

你不能從你的自定義視圖稱之爲turns = (TextView) findViewById(R.id.turnText34);,它總是返回null,因爲TextView存在於活動xml中,而不存在於ComBoardView中。

您可以做的是在活動中實例化您的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!"); 
    }}); 

    //... 

} 
+0

好吧..我看到這是如何可以工作,但你可以在comboardview中看到一個名爲OnTouchEvent的函數,它檢查玩家的某個移動女僕是否合法,以及要做出什麼樣的動作,我需要根據被更改的內容更改文本(否則它會不管玩家是否玩轉一回合,都會保持輪流玩轉) –

+0

您可以在活動中爲您的ComBoardView添加一個OnTouchListener,以處理觸摸事件。否則,使用包含的TextView創建自定義視圖,並像第一次那樣在自定義類中管理TextView。 – Rami