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

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

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

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

Android

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

Q&A

2回答

1583閲覧

特定条件でのリソース選択の最適解

tetsukay

総合スコア232

Java

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

Android

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

0グッド

0クリップ

投稿2017/06/15 02:12

編集2017/06/15 04:38

※ こので挙げる例は性差別の議論を呼ぶかもしれませんが,あくまで説明のための例であることをご理解いただければと思います.

やりたいこと

ユーザの属性によって,リソースを切り分けたい

ユーザが男性なら R.drawable.man_button 女性なら R.drawable.woman_button を選択したいとき,愚直に書けば

java

1imageView.setImageResource(user.gender == Gender.MAN ? 2 R.drawable.man_button : R.drawable.woman_button);

となりますが,この指定の箇所もリソースも多くなってくるとコードの可動性が悪くなってしまいます.

試したアプローチ

三項演算子による分岐だけをユーティリティメソッドとして共通化

java

1static class Util { 2 public static int getRes(User user, int manRes, int womanRes) { 3 return user.gender == Gender.MAN ? manRes : wimanRes; 4 } 5} 6 7imageView.setImageResource(Util.getRes(user, R.drawable.man_button, R.drawable.woman_button));
  • あんまり見通しよくはなってない

Resource.getIdentifier() を使う

java

1imageView.setImageResource(context.getResources().getIdentifier( 2 user.gender.name + "_button", "drawable", context.getPackageName()));
  • 参照するリソースが無い場合に,コンパイルエラーで検知できない
  • 参照するリソースが unused でlintに引っかかる

・リソースを整理したい時に,消していいリソースか判断に迷う

管理用クラスを作る

java

1public class UserResources { 2 public final User user; 3 4 public UserResources(User user) { 5 this.user = user; 6 } 7 8 public int getRes(Res res) { 9 return user.gender == Gender.MAN ? res.man : res.woman; 10 } 11 12 private enum Res { 13 BUTTON(R.drawable.man_button, R.drawable.woman_button), 14 LAYOUT(R.layout.man_layout, R.layout.woman_layout), 15 STRING(R.string.man_string, R.string.woman_string); 16 17 public final int man; 18 public final int woman; 19 20 Res(int man, int woman) { 21 this.man = man; 22 this.woman = woman; 23 } 24 } 25} 26UserResources res = new UserResource(user); 27imageView.setImageResource(res.getRes(Res.BUTTON));
  • リソースを追加したら管理クラスに追加しないといけないのが面倒
  • リソースがライブラリ下に入っていると,ライブラリの UserResource と アプリの UserResource ができて,中々にカオス

所感

  • 管理用クラスを作る

が一番現実的なんですかねぇ…?
他に何かいい方法(やライブラリ)があれば教えてください.

ちょっと考えたけどフワッとしてること

アノテーションプロセッシングで何かできないか

  • Resource.getIdentifier() を使う

の弱点改良版.
man_ woman_ のprefixを外したコアテキスト( button )と種類( drawable ) を渡すと,よしなに R.drawable.man_button をコード生成してくれるとか.
コード生成されればリフレクションと違って直接参照されるので,unused警告やリソースがない場合にコンパイルエラー検出可能なはず…?
(これが実現可能&有用そう&既存の回避策がないならライブラリ作ってみようかしら)

Kotlinの拡張関数つかうと行ける?

判断基準

  • リソースを使用する箇所はできるだけシンプルに記述できること

・使う箇所で条件分岐はしたくない
・使う箇所のステップ数を少なく

  • リソースを選択する側の仕組みも極力シンプルになるように

・リソースを追加するたびに管理クラスに手を入れずに済む方法があればベスト

これでもまだふわっとしてるのは重々承知ですが,

  1. リソースを使う箇所はシンプルに書きたい
  2. リソースが無いことをコンパイルエラーで検知したい
  3. unused resources なlintは出されたくない
  4. リソースを追加しても管理クラスに手を入れたくない

というのが要件でしょうか.
1, 2, 3はMUST,4はSHULDですが,4もMUSTにできるならその方法が知りたい次第です.

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

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

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

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

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

coco_bauer

2017/06/15 02:22

最適を判断する事項・項目と、その評価基準を示して下さい。
tetsukay

2017/06/15 02:39

判断基準を追記しました
guest

回答2

0

Genderの中に入れてしまうか、Genderから管理用クラスを取得するのはどうでしょうか。

(文法無視して書きます)

interface Gender { final MAN = new Man(); final WOMEN = new Woman(); abstract button(); abstract string(); } class Man implements Gender { button() { return R.drawable.man_button; } string() { return R.string.man_string; } } // 利用側 imageView.setImageResource(user.gender.button()); // Genderから管理用クラスを取得する imageView.setImageResource(user.gender.getRes().button());

投稿2017/06/26 03:07

kodai

総合スコア759

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

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

tetsukay

2017/06/26 04:20

回答有り難うございます.頂いた方法も, 1件目の回答のsylteリソースの定義と同様の問題が生じると思われます.
guest

0

男性styleリソースと女性styleリソースを定義したらいいと思いますよ。

投稿2017/06/15 16:17

yona

総合スコア18155

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

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

tetsukay

2017/06/16 02:14

回答ありがとうございます.例ではdrawableをリソース分けしていますが,実際の利用シーンでは表示テキストなども切り替える必要があるのです.styleではこれらに対応できないという認識です.
yona

2017/06/16 02:20

android:textで指定したらできますよね?
tetsukay

2017/06/19 03:22

いえ,textで全パターン指定すると大変なので,コードで動的に作りたいという意図です. 動的に作りたいという前提の上, getIdentifierではlintやリソース選択のミスをコンパイルエラーで検知できないという弱点があるので,これを解決できる方法を探っています.
yona

2017/06/19 06:06

なるほど、かなりの属性があるんですね。そうするとstyleでは厳しいですね。 これは管理クラスを作り、徹底的に単体テストを行うべきだと思いますよ。
tetsukay

2017/06/22 12:10

ありがとうございます.fmm...やはりそうなりますよね….検討の方向性が定まりました.管理クラス設計してみようと思います.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問