質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

1447閲覧

内包されているクラスから、外側のクラスのある定数の値を使いたいです

ko20vonobird

総合スコア50

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2017/01/22 06:15

編集2017/01/22 12:57

###実現したいこと
タイトルの通りなのですが、アクティビティを継承しているクラスの中にビューを継承しているクラスがあり、そのクラスから外側のクラスで測った画面の幅の定数を取得したいのです。

###発生している問題
なぜか値が0になります。また、下記の試したことで書いたようにインスタンスを作成してインスタンス.定数;としてみたのですが、うまくいきませんでした。

###該当のソースコード
全文

java

1package com.gmail.archerygame; 2 3//import ゾーン 4 5public class Main extends Activity { 6 //コンストラクタ的ゾーン 7 private TextView title; 8 private int winWM, winHM; 9 private int winWMl, winHMl; 10 private int a, r, g, b, cnt; 11 private int sw = 0; 12 private double kaku; 13 private float titley; 14 private float titleh; 15 private int deltay; 16 private double rad; 17 private Handler mHandler; 18 private Runnable titleloop; 19 private Handler stHandler = new Handler(); 20 private Runnable st; 21 private Handler cbHandler; 22 private Runnable circlebreaking; 23 private Handler cbrunHandler = new Handler(); 24 private Runnable circlemake; 25 Ct cta; 26 float s = 37.0f; 27 public int getWinWM(){//########## 28 return winWM; 29 } 30 public int getWinHM(){//########## 31 return winHM; 32 } 33 @Override 34 protected void onCreate(Bundle savedInstanceState) { 35 super.onCreate(savedInstanceState); 36 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 37 //setContentView(R.layout.activity_main); 38 //ステータスバー非表示 39 getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); 40 //タイトルバー非表示 41 requestWindowFeature(Window.FEATURE_NO_TITLE); 42 } 43 public void onResume() { 44 super.onResume(); 45 if (mHandler != null){ 46 mHandler.postDelayed(titleloop, 1000); 47 } 48 if (stHandler != null){ 49 stHandler.postDelayed(st, 1000); 50 } 51 if (cbHandler != null){ 52 cbHandler.postDelayed(circlebreaking, 1000); 53 } 54 if (cbrunHandler != null){ 55 cbrunHandler.postDelayed(circlemake, 1000); 56 } 57 cta = new Ct(this); 58 parts(); 59 } 60 public void parts() { 61 WindowManager wmM = (WindowManager)getSystemService(WINDOW_SERVICE); 62 Display dpM = wmM.getDefaultDisplay(); 63 Point poM = new Point(); 64 dpM.getSize(poM); 65 winWM = poM.x; 66 winHM = poM.y; 67 FrameLayout fl = new FrameLayout(this); 68 this.setContentView(fl); 69 fl.addView(cta); 70 final LinearLayout ll = new LinearLayout(this); 71 ll.setOrientation(LinearLayout.VERTICAL); 72 fl.addView(ll); 73 title = new TextView(this); 74 title.setText("N!ce・Sl!ngshot"); 75 title.setTextSize(17.0f); 76 title.setTypeface(Typeface.SERIF); 77 float titlewidth = title.getCompoundPaddingLeft() + title.getCompoundPaddingRight() + Layout.getDesiredWidth(title.getText(),title.getPaint()); 78 float titlemiddle = titlewidth; 79 int titlewhere = (int)((winWM / 2) - (titlemiddle / 2)); 80 float titlewheref = (float)titlewhere; 81 title.setTranslationX(titlewheref); 82 ll.addView(title); 83 title.setVisibility(View.GONE); 84 st = new Runnable() { 85 @Override 86 public void run() { 87 stHandler.removeCallbacks(st); 88 looper(); 89 } 90 }; 91 stHandler.postDelayed(st, 3000); 92 } 93 public void looper() { 94 WindowManager wmMl = (WindowManager)getSystemService(WINDOW_SERVICE); 95 Display dpMl = wmMl.getDefaultDisplay(); 96 Point poMl = new Point(); 97 dpMl.getSize(poMl); 98 final int winWMl = poMl.x; 99 final int winHMl = poMl.y; 100 mHandler = new Handler(); 101 a = 35; 102 r = 0; 103 g = 0; 104 b = 0; 105 cnt = 0; 106 kaku = 0; 107 titley = winWMl - titleh; 108 titleloop = new Runnable() { 109 @Override 110 public void run() { 111 title.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 112 titleh = title.getCompoundPaddingTop() + title.getCompoundPaddingBottom() + title.getMeasuredHeight(); 113 float titlewidthcb = title.getCompoundPaddingLeft() + title.getCompoundPaddingRight() + Layout.getDesiredWidth(title.getText(),title.getPaint()); 114 float titlewherecb = (winWMl / 2) - (titlewidthcb / 2); 115 title.setTranslationX(titlewherecb); 116 title.setTranslationY(titley); 117 title.setTypeface(Typeface.SERIF); 118 switch(title.getVisibility()){ 119 case View.VISIBLE: 120 break; 121 case View.GONE: 122 title.setVisibility(View.VISIBLE); 123 break; 124 } 125 s = s + 0.4f; 126 kaku = -1 * cnt * 7.2; 127 rad = kaku * Math.PI / 180; 128 int deltay = (int)(winHMl * Math.sin(rad)); 129 titley = winHMl + deltay; 130 title.setTextSize(s); 131 title.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); 132 titleh = title.getCompoundPaddingTop() + title.getCompoundPaddingBottom() + title.getMeasuredHeight(); 133 float titlewidthc = title.getCompoundPaddingLeft() + title.getCompoundPaddingRight() + Layout.getDesiredWidth(title.getText(),title.getPaint()); 134 float titlewherec = (winWMl / 2) - (titlewidthc / 2); 135 title.setTranslationX(titlewherec); 136 title.setTranslationY(titley); 137 if (titley + titleh > winHMl) { 138 titley = winHMl - titleh; 139 title.setTranslationY(titley); 140 } 141 title.setTypeface(Typeface.SERIF); 142 title.setTextColor(Color.argb(a, r, g, b)); 143 a = a + 4; 144 mHandler.postDelayed(titleloop, 15); 145 if (s >= 59.0f) { 146 mHandler.removeCallbacks(titleloop); 147 //次のまで数秒のハンドラ作成 148 cbHandler = new Handler(); 149 circlebreaking = new Runnable() { 150 @Override 151 public void run() { 152 cb(); 153 } 154 }; 155 cbHandler.postDelayed(circlebreaking, 1500); 156 } 157 cnt = cnt + 1; 158 } 159 }; 160 mHandler.postDelayed(titleloop, 15); 161 } 162 public void cb() { 163 cbHandler.removeCallbacks(circlebreaking); 164 Paint cipa = new Paint(); 165 circlemake = new Runnable() { 166 @Override 167 public void run() { 168 //円のアニメーション描画 169 sw = 1; 170 cta.endraw(); 171 cbrunHandler.removeCallbacks(circlemake); 172 } 173 }; 174 cbrunHandler.postDelayed(circlemake, 15); 175 } 176 public class Ct extends View { 177 float gw = getWinWM();//########## 178 float gh = getWinHM();//########## 179 private float r1 = gw + 20; 180 private float cx = gw / 2; 181 private float cy = (gh / 2) - (gh / 6); 182 public Ct(Context context){ 183 super(context); 184 } 185 protected void onDraw(Canvas canvas){ 186 super.onDraw(canvas); 187 Paint pam = new Paint(); 188 if (sw == 1){ 189 //ここにすべての処理を書いていく↓ 190 pam.setColor(Color.argb(255, 0, 0, 0)); 191 pam.setStyle(Paint.Style.STROKE); 192 pam.setStrokeWidth(3); 193 canvas.drawCircle(cx, cy, r1, pam); 194 //ここにすべての処理を書いていく↑ 195 } 196 } 197 public void endraw(){ 198 invalidate(); 199 } 200 } 201 public void onPause() { 202 super.onPause(); 203 if (mHandler != null){ 204 mHandler.removeCallbacks(titleloop); 205 } 206 if (stHandler != null){ 207 stHandler.removeCallbacks(st); 208 } 209 if (cbHandler != null){ 210 cbHandler.removeCallbacks(circlebreaking); 211 } 212 if (cbrunHandler != null) { 213 cbrunHandler.removeCallbacks(circlemake); 214 } 215 } 216 public void onDestroy() { 217 super.onDestroy(); 218 if (mHandler != null){ 219 mHandler.removeCallbacks(titleloop); 220 } 221 if (stHandler != null){ 222 stHandler.removeCallbacks(st); 223 } 224 if (cbHandler != null){ 225 cbHandler.removeCallbacks(circlebreaking); 226 } 227 if (cbrunHandler != null){ 228 cbrunHandler.removeCallbacks(circlemake); 229 } 230 } 231} 232

問題個所に//##########を付けました。
###試したこと
デバッグして値を確かめたり、外側のクラスのインスタンスを作成してそれを用いて参照できないか試みました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

なぜかというと、onCreateが実行されたMainとあなたがnewしたMainは別のインスタンスだからです。
Activityを継承したクラスはOSがインスタンス化するもので、プログラマがインスタンス化するものではありません。

Mainクラスにプライベート変数へのアクセッサメソッドを定義しましょう。

投稿2017/01/22 09:35

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ko20vonobird

2017/01/22 10:00 編集

yonaさん、いつも回答ありがとうございます。大変助かります。 内包されているクラスから外側のクラスのプライベート変数を使うにはアクセッサメソッド、つまりゲッターとセッターを使わなければいけないということですね? public int getWinWM(){ return winWM; } を、コードに付け加えるということで合っていますか?
yona

2017/01/22 10:23

合っています。 できませんか?
ko20vonobird

2017/01/22 10:44

色々位置を模索していたのですが、位置が分からないです。
yona

2017/01/22 11:58

位置とはなんでしょう。 Mainクラスの変数へのアクセッサメソッドなのでMainに書くしかないですよね。
ko20vonobird

2017/01/22 12:23

onCreate()の中に書くのかその上に書くのかそれともその値を決定した後に書くのか迷っています。 今 public class Main extends Activity { public int getWinWM(){ return winWM; } public int getWinHM(){ return winHM; } //省略 public class Ct extends View { float gw = getWinWM(); float gh = getWinHM(); } } という風に書いているのですが、どこが間違っているのか分かりません。上の質問と併せて返信していただけるとありがたいです。
yona

2017/01/22 12:33

メソッドの中にメソッドは書けません。また、Javaではメンバの順番は関係ありません、ファイルの上から実行されると思っているんですか? また、コードだけ貼られてもなにができていないのかわかりません。エラーログやエラーメッセージを追記してください。
ko20vonobird

2017/01/22 12:41

ファイルの上から実行される、という意味が分かりません。 エラーなどはないのですが、上のようにしていても値が0で返ってきます。 デバッグでブレークポイントを置いて確かめました。実行もして確かめました。
yona

2017/01/22 12:48

フィールド変数の初期化処理はMain#onResumeよりも前に実行されるので0になります。 そのため、ブレークポイントの位置次第では0になります。
swordone

2017/01/22 12:59

ファイルの上から実行される=上に書いたコードから順番に実行される ということでは? yonaさんはそうではないと言っています。 メソッドの中ではメソッド内のコードが上から順番に実行されますが、独立したメソッドが勝手に上から順番に実行されるということはありません。
ko20vonobird

2017/01/22 13:01

なるほど、デバッグモードでは不確かな部分があるのですね。 しかし、実行モードで実行して確かめたのですが、円の座標が(0,0)で描画されていたので(左上に円が描画されている状態)うまく値を取得できてないです。 ほぼ全文(字数制限によりインポート文を削除)を載せましたので、併せてご覧ください。該当箇所に//##########を付けています。
ko20vonobird

2017/01/22 13:03 編集

swordoneさん、解説ありがとうございます。必ずしも絶対一方通行ではないことを言ってらっしゃったのですね。
yona

2017/01/22 13:12

説明が足りていませんでしたね。ごめんなさい。 Ct#onPause時に値を見てください。
ko20vonobird

2017/01/22 13:21

いえいえ、私も国語力がないので読み取れなかったです、ごめんなさい。 また、勉強不足で理解ができなく恐縮なのですが、Ct#onPauseとは、デバッグで値を確認するということですか??
ko20vonobird

2017/01/22 13:31

一応デバッグモードでpublic Ct(Context context){にブレークポイントを設定した時の各値を書いておきます。 gw: 0.0 gh: 0.0 r1: 0.0 cx: 0.0 cy: 0.0
yona

2017/01/22 13:45

onPause時にコンソール出力してください。
ko20vonobird

2017/01/22 14:07

ログでコンソール出力をして確認しました。以下にその時得られた値を書きます。 gw: 0.0 gh: 0.0 r1: 20.0 cx: 0.0 cy: 0.0 です。
yona

2017/01/22 14:11

フィールド変数を直接出力していませんか?アクセッサメソッド経由で出力してください。
ko20vonobird

2017/01/22 14:22 編集

直接測ってみた結果 wm: 800 hm: 480 と、ちゃんと値が出ました。 追記、直接、というよりアクセッサメソッド経由のことです。すいません。
yona

2017/01/22 14:22

前のコメントの通り初期化のタイミングが悪いです。 フィールド変数を直接初期化するのはやめましょう。
ko20vonobird

2017/01/22 14:46 編集

毎度恐縮なのですが、それは即ちどうすれば良いのでしょうか? といいますのも、基本は調べた通りに組み立てていっていますので、、、
yona

2017/01/22 14:46

毎回アクセッサメソッドでアクセスしに行ったり、コンストラクタで渡したり、処理の順番を変えたりいろいろな方法があります、ただどれがベストかは私には判断がつきません。あなたが作りたいものに沿って実装するべきです。 あと、教えて貰ったら少しは自分で考えましょうね。
ko20vonobird

2017/01/22 15:07

直接初期化するなどの意味がよくイメージできなかったので上の形でいつものように聞かせていただきました。無論、検索エンジンで用語などを調べたりしていますが、それで出てこないものもあります。私はあなたより経験値がとてもとても低いのでどうしても具体性がない言い方だとさっぱり理解できません。しかし、その一方で一方的になげやりになっている部分もこれまでのyonaさんへの質問でも多々ありました。自分の欠点であり、反省しなければならないと思っています。 なので、知恵ならば考えるべきなのですが、その前提となる知識に関しては教えてください、例えば、直接初期化するというのはどういう用語なのか、などです。 長くなりましたが、アクセッサメソッドでアクセスしに行くということについてなのですが、今書いているのは Mainクラス{ public int getWinWM(){ return winWM; } public int getWinHM(){ return winHM; } Ctクラス{ int gw = getWinWM(); int gh = getWinHM(); } } という風になっています。私は、Ctクラスの部分の記述でgw,ghがアクセッサメソッドにアクセスしていると思っているのですが、この解釈は間違いなのでしょうか?
yona

2017/01/22 15:30

1-現状はgwに0が入っている。 2-getWinWMが0を返却している。 3-なぜgetWinWMが0を返すのか? 4-初期化のタイミングが悪いって言われている。 5-フィールド変数の初期化のタイミングはいつだろう? 6-フィールド変数はクラスがインスタンス化された時に初期化される。 7-そういえばpartsメソッドが実行された後じゃないとgetWinWMは正しい値を返さない。 8-試しにインスタンス化とpartsメソッドの順番を変えてみよう、アクセッサメソッドが悪いなら直接コンストラクタに渡すのもいいな、タイミングが悪いなら毎回アクセッサメソッドでアクセスするのもいいな これが「自分で考える」です、ウェブで検索する行為は「自分の問題と同じ人を見つけてその解決方法を借りる」です。もちろん経験も必要ですが、ウェブや人から答えを教えてもらう事は何の経験にもなりません。 あと、フィールド変数にint gw = getWinWM()と書いておけば値が変わっても最新の値が取得できると考えているなら誤りです。
ko20vonobird

2017/01/22 15:59

甘かったです、自分は3ぐらいでいつも諦めがちでした。これからはもっと徐々にではありますが時間をかけて問題に取り組もうと思います。大切なことを教えていただきありがとうございます。 まだちょっと混乱しているのですが、確認した上で確認しますと、7は先ほどのonpauseの確認作業のことで合っていますか?8について、順番を変えるのはコード内で書く位置を変えることで合っていますよね? 試してみたのですが、コンソール出力及び実行画面に変化はありませんでした。もしかしたら私の解釈が、考えた結論が間違っているかもしれないのですが、どうなのでしょうか? 値が変わった場合、もしかして、その都度値を代入する?必要があるということでしょうか?
yona

2017/01/22 16:18

私はteratailをその辺の力を鍛えるために利用しています。 onPauseで行った確認は4の証明です。ここで正しい値が取得できないならそもそもの取得方法が間違っている、または取得したがその後0に再設定されているという事になります。しかし正しい値が取得できたので、ある程度推測が正しいと考えられます。 7についてはpartsメソッドの中でwinWMが初期化されているのでこのメソッド以降は正しい値が設定されますが、それ以前は0です。 8についてはとりあえずCtのインスタンス化とpartメソッドの処理順を入れ替えて見てください。 フィールド変数の初期化は一度のみです、変更されたらその都度更新する必要があります。
ko20vonobird

2017/01/22 16:59

私も思考力?を鍛えられるように努力していこうと思います。ただ、一つ不安でもあるのが、自分の思考が遅いがために相手の時間まで割いてしまっていいのかというものです。 4については0に再設定されているわけでもないですよね?アクセッサメソッドを使って得た値は0ではなかったので。 7について、初期化されることで正しい値が取得できるようになるのですよね? なるほど、てっきり他の言語と混同していました。
ko20vonobird

2017/01/22 17:03

ようやく解決しました。どう変えたかというと、Ctクラスにて初期化する際に数値などまで設定していましたが、どう考えたのかまでは忘れましたがそれをやめて、宣言だけにして、ゲッターと共に初期化部分?をonDrawの中に入れたところちゃんと作動するようになりました。 これでひとまずといったところなのですが、onDrawは頻繁に呼び出されると教えてもらったことがあり、ここに初期化?の部分を置いて良いのかが未だ疑問です。もし、こうした方がいいというのがあれば教えていただけると幸いです。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問