アクティビティに部品を追加
〜 Android Studio の使い方 9 〜
2023-05-20 作成 福島
TOP > androidstudio > inflatemain

使用ツール

    Android Studio Flamingo | 2022.2.1 Patch 2  


0. 概要

メインアクティビティにプログラムから部品を追加します。


1. 通常のプロジェクトを作成する。

ここでは ConstraintLayout と TextView を利用するので、画面の存在するプロジェクトを作成する。
「Empty Activity」「Empty Views Activity」等のプロジェクトが対象。


2. メインアクティビティに ID を定義する。

メインアクティビティを findViewById() で参照するために ID を付加する。

2-1. activity_main をデザインモードで開く。
要素名内容
アクティビティAndroid > app > res > layout > activity_main.xml
2-2. Component Tree に表示されている一番上の名前を選択する。
まだ名前を付けていないので表示が「ConstraintLayout」になっている。
2-3. Attributes の id に文字列を記入して Enter キーを押下する。
項目名内容備考
idmainLayoutプログラムから R.id.mainLayout として参照される。
他と重複しなければ名称は特にこだわらなくて良い。
2-4. 確認ダイアログボックスが表示されるので ボタンをクリックする。
リファクタリングにより、変更前の名称を参照していた箇所がすべて変更後の名称に変更される。
が、メインアクティビティのレイアウトには初期値が設定されていないので、今回は何も変更されない。
2-5. Component Tree に表示されている一番上の名前が変更されていることを確認する。
名前を変更したので表示が「mainLayout」になった。
2-6. activity_main をコードモードで開く。
「@+id/mainLayout」の行が追加されていることを確認する。
(それ以外はプロジェクト作成時に自動生成されたコード)
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <!-- ↑ android:id="@+id/mainLayout" が追加された -->

    <TextView
        android:id="@+id/textViewHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <!-- ↑ android:id="@+id/textViewHello" は後述*1 -->

</androidx.constraintlayout.widget.ConstraintLayout>


3. プログラムの実装

3-1. メインアクティビティに TextView を追加するプログラム。
クラス MainActivity の中に以下を記述する。
public class MainActivity extends AppCompatActivity {

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)  // generateViewId() は API17 が必要*2
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


ConstraintLayout constraintLayout = findViewById(R.id.mainLayout); // バージョンによっては警告が表示されるが動作する TextView textViewExtra = new TextView(this); constraintLayout.addView(textViewExtra); textViewExtra.setText("Extra message");

// ↓ 以下はお好みで実施 (textViewExtra の表示位置を調整) textViewExtra.setId(View.generateViewId()); // これをしないと getId() が -1 のままになる*2 int extraId = textViewExtra.getId(); ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(this, R.layout.activity_main); // id が未定義となっている部品が存在しないこと*1 // textViewExtra を画面の中心に配置 constraintSet.constrainWidth( extraId, ConstraintSet.WRAP_CONTENT); constraintSet.constrainHeight(extraId, ConstraintSet.WRAP_CONTENT); constraintSet.connect(extraId, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0); constraintSet.connect(extraId, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0); constraintSet.connect(extraId, ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0); constraintSet.connect(extraId, ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0); constraintSet.applyTo(constraintLayout); // 変更を反映させる
} }
*1 activity_main に id が未定義の部品がひとつでも存在すると ConstraintSet.clone() が実行時エラーとなる。
プロジェクト作成時に自動生成される部品 (Layout - activity_main / TextView - "Hello world!") は id が未定義なので、
上記 2 と同様にしてすべての部品の id を定義するか、id の無い部品を削除しておく必要がある。

あるいは、activity_main を include するアクティビティ (未定義 id が無いこと) を /app/res/layout/***.xml として作成して使用すればこの問題は発生しない。

*2プロジェクト作成時に Android 4.2 以上を指定すると API17 を含むことになるので、その場合は @RequiresApi(···) の記述が不要になる。