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

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

ただいまの
回答率

92.00%

  • Xamarin

    202questions

    Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

Xamarin.Androidコードによるコントロールの配置方法

解決済

回答 1

投稿 2017/03/16 11:20

  • 評価
  • クリップ 0
  • VIEW 201

M.inose

score 5

前提・実現したいこと

Xamarin.Androidコードによるコントロールの配置方法についてご教示ください。

Xamarin.Androidでアプリケーションを開発しております。
このアプリケーションは、上位からの指示で画面を構成します。

その為、レイアウト、ボタン等を動的に生成しなければなりません。

いろいろな情報を調べて、例えばレイアウトなら以下のコードで、実現できることが分かりました。

//リニアレイアウトを生成
var linearLayout = new LinearLayout(this) {
Orientation = Orientation.Vertical //子コントロールを縦方向に配置する
};

ところが、Orientation以外の情報を設定する方法が分かりません。

該当のソースコード

例えば

Main.axmlの
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />

の記述で動的にLinearLayoutを生成する場合は

var linearLayout = new LinearLayout(this) {
Orientation = Orientation.Vertical //子コントロールを縦方向に配置する
<-ここにandroid:layout_widthやandroid:layout_heightを記述したい
};

にどの様に記述すればよろしいのでしょうか?

また、他にレイアウト、ボタン等を動的に生成する方法があれば併せて
皆様にご教示いただきたく、お願い申し上げます。

補足情報(言語/FW/ツール等のバージョンなど)

開発環境 
Visual studio 2015 
Xamain 4.3.0.784 
Xamain.Android 7.1.0.41 
Android SDK Tools 25.2.5 
Android API 6.0

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

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

    クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

layout_widthやlayout_heightなどのlayout_から始まる属性は親Viewに対する設定値です。
ですので、親View配下のLayoutParamsクラスを生成し、生成したインスタンスに対して値を設定・子ViewのLayoutParametersプロパティに格納という形でlayout_widthなどは動的に設定できます。
(たとえば親がFrameLayoutの場合はFrameLayout.LayoutParamsクラス)
(axml(xml)から生成したレイアウトを動的に扱う場合はすでに格納されているのでキャストして利用)

textやgravity、paddingなどの属性は自身に対する設定値なのでOrientationのように設定することが可能です(この際、Java向けAPIからプロパティではなくメソッドに置き換えられている場合もあるのでオブジェクト初期化子内で記述できないこともあります)

以下のサンプルコードのようにレイアウトをコードから動的に生成するのは位置・サイズ調整など大変な要素が大きいのでLayoutInflaterなどを利用して極力axml(xml)からレイアウトを作成することをお勧めします。

また、Xamarin.AndroidにつきましてはAndroid(Java) APIをそのまま置き換えている面が大きいので、Android自体の開発に関する疑問は、Javaなどで記述されている記事などが検索で引っかかることが多いと思うのでそちらを参考にすればいいでしょう。(もちろんXamarin.Android固有の疑問点なども出ますので適宜調べ方の調整は必要です)

MainActivity.cs

using Android.App;
using Android.Content;
using Android.OS;
using Android.Views;
using Android.Widget;

namespace TeratailLayoutExample {

    [Activity(Label = "TeratailLayoutExample", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity {

        protected override void OnCreate(Bundle bundle) {
            base.OnCreate(bundle);

            //SetContentView(Resource.Layout.Main);
            SetContentView(makeViews());
        }

        private View makeViews() {
            var root = new LinearLayout(this) {
                Orientation = Orientation.Vertical,
                LayoutParameters = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent)
            };

            var title = new TextView(this) {
                Text = "Title",
                Gravity = GravityFlags.Center,
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent)
            };
            root.AddView(title);

            var horizontalLayout = new LinearLayout(this) {
                Orientation = Orientation.Horizontal,
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent) {
                    TopMargin = this.ConvertDensityIndependentPixelToPixel(16f)
                }
            };
            root.AddView(horizontalLayout);

            var leftText = new TextView(this) {
                Text = "LeftText",
                Gravity = GravityFlags.Center,
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) {
                    Weight = 1f
                }
            };
            horizontalLayout.AddView(leftText);

            var rightText = new TextView(this) {
                Text = "RightText",
                Gravity = GravityFlags.Center,
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WrapContent, ViewGroup.LayoutParams.WrapContent) {
                    Weight = 1f
                }
            };
            horizontalLayout.AddView(rightText);

            var content = new TextView(this) {
                Text = "Dynamic Layout",
                Gravity = GravityFlags.Center,
                LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.WrapContent)
            };
            content.SetPadding(0, this.ConvertDensityIndependentPixelToPixel(16f), 0, 0);
            root.AddView(content);

            return root;
        }
    }

    public static class ContextExtension {

        public static int ConvertDensityIndependentPixelToPixel(this Context context, float dp) {
            var metrics = context.Resources.DisplayMetrics;
            return (int)(dp * ((int)metrics.DensityDpi / 160f));
        }
    }
}

Main.axml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:text="Title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/Title"
        android:gravity="center" />
    <LinearLayout
        android:orientation="horizontal"
        android:layout_marginTop="16dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/HorizontalLayout">
        <TextView
            android:text="LeftText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:id="@+id/LeftText" />
        <TextView
            android:text="RightText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center"
            android:id="@+id/RightText" />
    </LinearLayout>
    <TextView
        android:text="Static Layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingTop="16dp"
        android:id="@+id/Content"
        android:gravity="center" />
</LinearLayout>


コードから生成:
コードから生成したレイアウト
axmlから生成:
axmlから生成したレイアウト

投稿 2017/03/17 02:08

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/03/17 11:38

    meilcli様
    早々に、ご回答いただき大変にありがとうございます。
    動作を確認致しました。
    具体的なサンプルソースコードを提示いただき大変にありがとうございます。

    感謝、感謝、感謝です。
    今回の開発は、レイアウト、ツール等全て動的に生成しなければならず、途方に暮れていました。

    LayoutInflaterの使用方法も調べてみます。
    (プロジェクトで新規作成したaxmlではなく、動的に作成したaxmlを読み込む方法があればいいのですが。)

    キャンセル

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

ただいまの回答率

92.00%

関連した質問

同じタグがついた質問を見る

  • Xamarin

    202questions

    Xamarin(ザマリン)は、iPhoneなどのiOSやAndroidで動作し、C# 言語を用いてアプリを開発できるクロスプラットフォーム開発環境です。Xamarin Studioと C# 言語を用いて、 iOS と Android の両方の開発を行うことができます。

閲覧数の多いXamarinの質問