2012-04-16 4 views
1

私は単純な野球のスコアキーピングアプリを、主に学習の練習として作成しようとしています。Android:1つのオブジェクトのonClickに基づいて複数の(ボタン)オブジェクトを操作する

この時点で私は完全に機能するアプリを持っています。 1つのアクティビティと1つのレイアウトがあります。すべての数字(ボール、ストライク、アウト、イニング)がボタンとして表示されます。ボタンのテキストが整数であるようにandroid.widget.Buttonクラスを拡張し、ボタンをクリックしたときにonClickを使用して値を1ずつ増やしました。オブジェクトには最大値も格納されます。インクリメントがその値に達すると、カウンタは0にリセットされます。たとえば、 "ボール"ボタンは最大値4を持ち、0,1,2,3をカウントします。次回3

これまでのところ、これはすべて私の拡張ボタンクラスのソースコード(以下に示すソースコード)で動作します。さて、私はそれを変更しようとしているので、1つのカウンターが0に戻ると、他のカウンターも0になる。私はこれをどうやって行うかについて迷っています。 (ここで、「ストライキ」はアクティビティに定義されてScoreButtonオブジェクトです)

final ScoreButton strikes = (ScoreButton) findViewById(R.id.strikes); 
strikes.zero(); 

:私の最初の本能は、ちょうどそのように戻って0に値を反転させ、同じ「もし」ステートメントに追加することでした。これはヌルポインターエラーで戻ってきます。

2番目の考えは、インクリメントメソッドが0( "リセット")に戻るときに設定できるブール値属性を追加することでした。しかし、私はこの属性を読むべきところを理解していません。私は一度onResumeメソッドでチェックすることができますが、変数を繰り返し読み込むための "while"ループのようなことをしようとすると、メインレイアウトを表示しなくてもアプリケーションをロックするだけです。

これを行うためのより良い方法を研究しようとすると、AsyncTaskについての読み込みが難しくなってしまいました。これは、タスクが正常に機能しないことがわかりました(特定のボタンがリセットされたかどうかを確認する)は終了しません。

この時点で、これはとても簡単なことであり、私は明らかに何かを見逃しているに違いないようです。私はあなたの提案を感謝します。私のカスタムボタンクラスの

コード:

import android.widget.Button; 
import android.content.Context; 
import android.view.View; 
import android.util.AttributeSet; 

public class ScoreButton extends Button { 

protected int flipCount; 
protected int currCount; 
protected boolean reset; 

public ScoreButton(Context context) { 
     super(context); 
    } 

public ScoreButton(Context context, AttributeSet attr) { 
     super(context, attr); 
     setOnClickListener(incr); 
     setOnLongClickListener(dec); 
} 

public void init(int start, int max) { 
    flipCount = max; /** number at which the counter goes back to 0 **/ 
    currCount = start; /** number to start at **/ 
    reset = false; 
    setText(Integer.toString(currCount)); 
} 

/** reset the button value to 0 **/ 
public void zero() { 
    currCount = 0; 
    setText(Integer.toString(currCount)); 
} 


private OnClickListener incr = new OnClickListener() { 
    public void onClick(View v) { 
    currCount++; /** increment number on button **/ 
    if (currCount == flipCount) { /** if at the maximum value, go back to 0 **/ 
     currCount = 0; 
     reset = true; 
     final ScoreButton strikes = (ScoreButton) findViewById(R.id.strikes); 
     strikes.zero(); 
     } 
    setText(Integer.toString(currCount)); /** display the new button text **/ 

    } 
} ; 

/** this method decreases the value by 1 on a long click **/ 
private OnLongClickListener dec = new OnLongClickListener() { 
    public boolean onLongClick(View v) { 
    currCount--; 
    if (currCount == -1) { 
     currCount=0; 
    } 
    setText(Integer.toString(currCount)); 
    return true; 
} 
} ; 
} 

答えて

0

あなたが説明AsynkTask方法をしようとしないことが正しいです。それは正しくありません。

は、ここに私の提案です: あなたはすべてのScoreButton sのあなたは(ScoreButtonクラスのスコープではない、あなたの活動の範囲から)あなたのアクティビティに定義し、より複雑なonClickListenerを与えることができます。これは、メンバー変数としてすべてのButtonに関する情報を含む1つのリスナーになります。 1つのインスタンスを作成するだけですが、ScoreButton [ButtonsetOnClickListener()のすべてに渡します。 1つのスコアをラップする必要がある場合は、リスナー内の他のカウンタをすべて0に設定するだけです。[注:このアプローチでは、必要に応じてサブクラス化する必要はありません。Button]

しかし、学習していると言われているので、ビュー階層に配置できるScoreButtonGroupViewを作成することもできます。これは、ボタンの値を適切に設定するための内部ロジックを持っている素晴らしい自己完結型のソリューションです(サブクラス化すると思っていたように、Button)。

+0

ありがとう、私はすべてのボタンの共通のonClickハンドラを定義することはできませんでした。私はそれをします。グループビューは魅力的なアイデアですが、今後のバージョンでは残しておきたいと思います。 – grasshopper

関連する問題