茨城エンジニアのPython開発日記

茨城のITベンチャー企業ではたらく2年目エンジニア。Pythonで色々なものを作成中。

Androidアプリ作成時、フラグメントにビューをできるだけコード上から配置する方法


ブログから記事を見つけたい場合はこちら

ブログ地図 - 茨城エンジニアのPython開発日記

こんにちは。ファイアーエムブレム風花雪月やりました。
あんな地獄を見せるくらいなら学園ものにするな。


さて、タイトルのようにandroidアプリ作成時にできるだけコードからビューを配置します。

0. 前提

Android Studioアプリ開発するとき、アプリ画面はActivity⇒Fragment⇒Viewという順番に配置されます。
Activityが一番土台側で、Viewが実際に配置されるボタンとか写真とかそんなのですね。

Viewを宣言やら配置するのをxmlでやらずに、javaのコード上でしたいなと思ったんですが意外と手間取りました。
ActivityクラスにはViewを配置するメソッドがあるんですが、Fragmentにはそれらしいメソッドが見つからなかったんですね。

ちなみにBottom Navigation Activityというテンプレートを使っています。

0. 解決方法

上記の解決策が下記です。
①Fragmentのxmlに最低限のビューを配置(背景画像とスクロールビュー)
②FragmentのonCreatedメソッドでスクロールビュー上にボタンやらのViewを配置

どうということはなく、「スクロールビュー」という自分自身にViewを配置できるViewをxmlで置いといただけです。
以下コード。変数名が適当なのは許してください。

●Fragmentのxml

<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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.home.HomeFragment">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/bg"
        android:id="@+id/backGroundViewHome"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollViewHome">
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

●Fragmentのクラス

package com.makty.bingogosyuin.ui.home;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;

import com.makty.bingogosyuin.R;
import com.makty.bingogosyuin.databinding.FragmentHomeBinding;

public class HomeFragment extends Fragment {

    private FragmentHomeBinding binding;

    private Context m_context = null;       /*コンテキスト*/

    private @ColorInt
    int mBackgroundColor = Color.TRANSPARENT;

    /**画面上のビュー**/
    ScrollView m_scrollView = null;

    Button mButton0_0 = null;
    Button mButton0_1 = null;

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        HomeViewModel homeViewModel =
                new ViewModelProvider(this).get(HomeViewModel.class);

        binding = FragmentHomeBinding.inflate(inflater, container, false);
        View root = binding.getRoot();
        m_context = this.getContext();


        /*バックグラウンドのスクロールビュー取得*/
        m_scrollView = (ScrollView) root.findViewById(R.id.scrollViewHome);

        /*ボタン設置レイアウト作成*/
        LinearLayout layout = new LinearLayout(m_context);
        layout.setOrientation(LinearLayout.HORIZONTAL);

        layout.setLayoutParams(new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.MATCH_PARENT));
        layout.setGravity(Gravity.CENTER);

        /*ボタン作成*/
        mButton0_0 = new Button(m_context);
        mButton0_0.setBackgroundColor(0xFFee7800);
        mButton0_0.setText("鹿島神社\n(茨城県)");
        layout.addView(mButton0_0);

        mButton0_1 = new Button(m_context);
        mButton0_1.setBackgroundColor(0xFFee7800);
        mButton0_1.setGravity(Gravity.CENTER);
        mButton0_1.setText("鹿島神社\n(茨城県)");
        layout.addView(mButton0_1);

        /*スクロールビューにレイアウトを追加*/
        m_scrollView.addView(layout);

        return root;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}


今回できた画面はこんな感じ。


めでたい。
言語の仕様や使い方をゆっくり自分のものにしていくときが一番心が落ち着きますね。

よいお年を。