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

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

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

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

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

1340閲覧

子ビューをfindViewByIdで取得したい

konpeit

総合スコア6

Java

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

Android

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

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2020/02/12 06:30

#子ビューをfindViewByIdで取得したい

実現したいこと

カレンダーを表示し、どこかの日付けをクリックするとその日付けの予定を参照できるアプリを作成しています。

##作成したファイル
MainActivity.java(主画面表示)
activity_main.xml (レイアウト)
CalendarView.java (カスタムviewクラス)
DayClickListner.java (カスタムview内のtextview用リスナークラス)
の4ファイルで構成しています。

カスタムviewクラス:CalendarViewを作成し、そのクラス内でtextviewを日付分作成しています。
activity_mainにCalendarViewを埋め込みカレンダーを表示させています。(ここまではOK)

この上で各textViewをclickbleに設定しDayClickListnerをsetOnclickListnerしています。
そして、クリックされたtextviewからDayClickListner内のonclickメソッドを呼び出し、findViewByIdで呼び出し元のtextviewを取り出そうとしているのですが、ここでNullPointerExceptionが発生してしまっているようです。

CalendarViewクラス内でfindViewById()は正常実行できるのですが、どうすればDayClickListner内でfindViewByIdできるようになるでしょうか。

Layoutinflatarが怪しいと思い試したもののエラー解消できませんでした。
おそらくviewに関する理解不足だと思うのですが、ご教示いただけると幸いです。

MainActivity.java

public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
}
}

###activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">
<com.example.xxx.CalendarView
android:id="@+id/Calendar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="49dp" >
</com.example.xxx.CalendarView>
</LinearLayout>

###CalendarView.java
public class CalendarView extends LinearLayout{
/** 週の始まりの曜日を保持する /
public int beginningWeek = Calendar.SUNDAY;
/
* 今日のフォント色 /
public int todayColor = Color.RED;
/
* 今週の背景色 /
public int todayBackgroundColor = Color.LTGRAY;
/
* 通常の背景色 /
public int defaultBackgroundColor = Color.TRANSPARENT;
/
* 通常のフォント色 /
public int defaultColor;
/
* 年月のフォントサイズ /
public float titleFontPx;
/
* 日付のフォントサイズ */
public float dayFontPx;
private LinearLayout mWeekLayout;
private ArrayList<LinearLayout> mWeeks = new ArrayList<LinearLayout>();
private Calendar mToday;
private TextView mTitle;
private static final int WEEK_7 = 7;
private static final int MAX_WEEK = 6;

@SuppressLint("ResourceType") public CalendarView(Context context, AttributeSet attrs) { super(context, attrs); this.setOrientation(VERTICAL); // dp-->px 変換用の値 final float scale = context.getResources().getDisplayMetrics().density; // パディング final int padding = (int) (scale * 5); // 右パディング final int paddingR = (int) (scale * 15); // タイトルとのパディング final int paddintT = (int) (scale * 20); titleFontPx = scale * 20; // 本日の日付を保持 mToday = Calendar.getInstance(); // タイトル部 年月表示 Log.v("CalendarView", "タイトル部 年月表示"); mTitle = new TextView(context); mTitle.setGravity(Gravity.CENTER_HORIZONTAL); // 中央に表示 mTitle.setTypeface(null, Typeface.BOLD); // 太字 mTitle.setText("DEBUG"); mTitle.setPadding(0, 0, 0, paddintT); addView(mTitle, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); dayFontPx = mTitle.getTextSize(); // 現在のフォントサイズを保持 defaultColor = mTitle.getTextColors().getDefaultColor(); // 週表示部 日月火水木金土 Log.v("CalendarView", "週表示部 日月火水木金土"); mWeekLayout = new LinearLayout(context); // 週表示レイアウト Calendar cal = Calendar.getInstance(); cal.set(Calendar.DAY_OF_WEEK, beginningWeek); // 週の頭をセット SimpleDateFormat formatter = new SimpleDateFormat("E"); // 曜日を取得するフォーマッタ for (int i = 0; i < WEEK_7; i++) { TextView textView = new TextView(context); textView.setGravity(Gravity.CENTER_HORIZONTAL); // 中央に表示 LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT); llp.weight = 1; mWeekLayout.addView(textView, llp); cal.add(Calendar.DAY_OF_MONTH, 1); } addView(mWeekLayout, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); //クリックリスナーインスタンスを作成 DayClickListener dayClickListener = new DayClickListener(); // カレンダー部 最大6行必要 Log.v("CalendarView", "カレンダー部 最大6行必要"); for (int i = 0; i < MAX_WEEK; i++) { LinearLayout weekLine = new LinearLayout(context); mWeeks.add(weekLine); // 1週間分の日付ビュー作成 for (int j = 0; j < WEEK_7; j++) { TextView dayView = new TextView(context); //dayView.setText(String.valueOf((i * WEEK_7) + (j + 1))); // TODO:DEBUG dayView.setGravity(Gravity.RIGHT); // 右寄せで表示 dayView.setClickable(true);//Textviewをクリック可能にする dayView.setId(View.generateViewId()); //個々の日付の余白設定、左、右、トップ、ボトムの順 dayView.setPadding(0, padding, paddingR, padding*10); LinearLayout.LayoutParams llp = new LinearLayout.LayoutParams(0, LayoutParams.WRAP_CONTENT); llp.weight = 1; weekLine.addView(dayView, llp); //リスナーをセット dayView.setOnClickListener(dayClickListener); } this.addView(weekLine, new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); } init(mToday.get(Calendar.YEAR), mToday.get(Calendar.MONTH)); } // 表示設定 public void init(int year, int month) { Calendar cal = Calendar.getInstance(); cal.clear(); // まずクリアしてからセットしないといけない cal.set(Calendar.YEAR, year); cal.set(Calendar.MONTH, month); cal.set(Calendar.DAY_OF_MONTH, 1); int todayYear = mToday.get(Calendar.YEAR); int todayMonth = mToday.get(Calendar.MONTH); int todayDay = mToday.get(Calendar.DAY_OF_MONTH); // タイトル 年月 設定 String formatString = mTitle.getContext().getString(R.string.format_month_year); // 年月フォーマット文字列 mTitle.setTextSize(titleFontPx); // 年月を取得するフォーマッタ SimpleDateFormat formatter = new SimpleDateFormat(formatString); mTitle.setText(formatter.format(cal.getTime())); // 週表示部 日月火水木金土 Log.v("CalendarView", "週表示部 日月火水木金土"); Calendar week = Calendar.getInstance(); week.set(Calendar.DAY_OF_WEEK, beginningWeek); // 週の頭をセット SimpleDateFormat weekFormatter = new SimpleDateFormat("E"); // 曜日を取得するフォーマッタ for (int i = 0; i < WEEK_7; i++) { TextView textView = (TextView) mWeekLayout.getChildAt(i); textView.setText(weekFormatter.format(week.getTime())); // テキストに曜日を表示 week.add(Calendar.DAY_OF_MONTH, 1); } // カレンダーの最初の空白の個数を求める。 int skipCount; // 空白の個数 int firstDayMonthWeek = cal.get(Calendar.DAY_OF_WEEK); // 1日の曜日 if (beginningWeek > firstDayMonthWeek) { skipCount = firstDayMonthWeek - beginningWeek + WEEK_7; } else { skipCount = firstDayMonthWeek - beginningWeek; } int lastDay = cal.getActualMaximum(Calendar.DATE); // 月の最終日 // 日付を生成する。 int dayCounter = 1; for (int i = 0; i < MAX_WEEK; i++) { LinearLayout weekLayout = mWeeks.get(i); weekLayout.setBackgroundColor(defaultBackgroundColor); for (int j = 0; j < WEEK_7; j++) { TextView dayView = (TextView) weekLayout.getChildAt(j); if (i == 0 && skipCount > 0) { dayView.setText(" "); skipCount--; } else if (dayCounter <= lastDay) { dayView.setText(String.valueOf(dayCounter)); // 今日の日付を赤文字にする if (todayYear == year && todayMonth == month && todayDay == dayCounter) { dayView.setTextColor(todayColor); // 赤文字 dayView.setTypeface(null, Typeface.BOLD); // 太字 weekLayout.setBackgroundColor(todayBackgroundColor); // 週の背景グレー } else { dayView.setTextColor(defaultColor); dayView.setTypeface(null, Typeface.NORMAL); } dayCounter++; } else { dayView.setText(" "); } } } }

}

###DayClickListner.java
public class DayClickListener extends AppCompatActivity implements View.OnClickListener {
@Override
public void onClick(View v){
TextView schedule = (TextView) this.findViewById(v.getId());
String day = schedule.getText().toString();
//Intent intent = new Intent(this, ScheduleDetail.class);
//startActivity(intent);
}
}

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

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

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

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

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

guest

回答1

0

ベストアンサー

どうすればDayClickListner内でfindViewByIdできるようになるでしょうか。

する必要はありません.
引数の View v が呼び出し元の TextView です.

また,

public class DayClickListener extends AppCompatActivity implements View.OnClickListener {

となっていますが, OnClickListener に必要なのは implements View.OnClickListener だけで extends AppCompatActivity は不要です. 余計な(巨大な)データが付いてしまいますので, 削除されたほうが良いように思います.

投稿2020/02/12 07:54

jimbe

総合スコア13209

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

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

konpeit

2020/02/12 11:31

想定としては、textviewから日付を取得し、これをintentにputExtraしたのち、startActivity(intent)で次画面に遷移させようと考えています。そのため、Intentを使うにあたりAppCompatActivityを継承する必要があるという認識ですが誤っていますか? また別件にはなりますが、実際にstartActivity(intent)で画面遷移させようとしたところ、遷移せずアプリが落ちてしまいます。 intentのコンストラクタには、mainActivityクラスにgetApplicationContextを返すgetterメソッドを用意しその戻り値と次画面.classを渡しています。 listenerクラスを外部に立てた場合intentで画面遷移は行えないのでしょうか?
jimbe

2020/02/12 17:14

> Intentを使うにあたりAppCompatActivityを継承する必要があるという認識です なんでもかんでも使えるわけではありません. Intent を使える Activity は, テキトウに (new で) 作ったものでは無く, システムが生成したもので無ければなりません. つまり件の場合は MainActivity を使う必要があります. 別件のほうは「落ちてしまいます」だけでは何が起きているのか分かりません. ですが, 確か Android の version によっては ApplicationContext を使うとエラーになる場合があったように思います. 落ちた時のログを確認する等で何が起きているのかをお調べください.
konpeit

2020/02/13 13:46

ご回答ありがとうございます。 なんとか正常動作を得ることができました。。
jimbe

2020/02/13 16:04

同じ内容の別質問を作成されたようですね... 解決されましたら, 解決済みとされますようお願いします.
konpeit

2020/02/14 15:37

質問がわかりにくかったので再投稿しました。 ご回答ありがとうございます。 まだ慣れておらずすいません、、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問