web-dev-qa-db-ja.com

RelativeLayoutをマージおよびインクルードで動作させる方法は?

ネストされたLinearLayoutsのいくつかのレベルを1つのRelativeLayoutに変換することにより、レイアウトをより効率的にしようと数日試みましたが、見つけられなかったいくつかの問題に遭遇しましたの回避策...

Android初心者グループとこのサイトを検索しましたが、問題の解決に役立つものを見つけることができませんでした。

ブログの1つで、レイアウトをマージタグとインクルードタグに統合できることを読みました。私が持っているのは、RelativeLayoutルート要素を持つメインレイアウトファイルです。その中に、ルートのマージ要素を持つ5つの異なるxmlレイアウトファイルを参照する5つのタグが含まれています(マージファイルはすべて、それらのIDを除いて同じです)。

私は2つの問題に直面しています。レイアウトコードの簡易版を投稿した後で説明します。

メインレイアウトファイルのサンプル:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:background="@drawable/translucent_gray" >

    <include 
        Android:id="@+id/running_gallery_layout_id"
        layout="@layout/running_gallery_layout" />

    <include 
        Android:id="@+id/recent_gallery_layout_id" 
        layout="@layout/recent_gallery_layout"
        Android:layout_below="@id/running_gallery_layout_id" />

    <include
        Android:id="@+id/service_gallery_layout_id"
        layout="@layout/service_gallery_layout"
        Android:layout_below="@id/recent_gallery_layout_id" />

    <include
        Android:id="@+id/process_gallery_layout_id"
        layout="@layout/process_gallery_layout"
        Android:layout_below="@id/service_gallery_layout_id" />

</RelativeLayout>

サンプルに含まれるマージファイル:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <TextView 
        style="@style/TitleText"
        Android:id="@+id/service_gallery_title_text_id"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:gravity="left"
        Android:text="@string/service_title" />

    <Gallery
        Android:id="@+id/service_gallery_id"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:layout_weight="1"
        Android:layout_below="@id/service_gallery_title_text_id" />

    <TextView 
        style="@style/SubTitleText"
        Android:id="@+id/service_gallery_current_text_id"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_toRightOf="@id/service_gallery_title_text_id"
        Android:layout_above="@id/service_gallery_id" />
</merge>

私は2つの問題に直面しています:

1)includeタグで使用するとAndroid:layout_*属性は無視されるようで、マージされたすべてのレイアウトが互いの上に表示されます。この投稿によると( http://developer.Android.com/resources/articles/layout-tricks-reuse.html )「Android:layout_*属性は<include />タグ」

2)これが機能しないので、各マージレイアウトファイルの最初のTextViewアイテムにAndroid:layout_below属性を追加してみることにしました。つまり、各マージファイルは別のマージのIDを参照します。レイアウトファイル...ほとんどの場合、これは実際に機能し、レイアウトは正常に見えます。ただし、Android:layout_below属性の1つで、指定したIDが見つからないというエラーが表示されます。IDが正しいことを確認するために、IDを二重および三重にチェックしました。最も奇妙な部分は、最初にAutoFill機能を使用してIDを属性に入れたことです。

誰かが提案や回避策を持っている場合、私はそれらを試して喜んでいるでしょう。また、5の代わりに1つのマージxmlレイアウトファイルを作成する方法を誰かが考えていただければ幸いです。実行時にマージレイアウトファイル内の各アイテムにアクセスする必要があるため、その方法を見つけることができませんでした...

113
Justin

Includeタグに問題があります。チェック: https://issuetracker.google.com/issues/36908001

修正するには、必ず両方を上書きしてくださいlayout_widthおよびlayout_height含める場合、それ以外はすべて無視されます。

212
Macarse

以下のより高い投票の答えを参照してください。私のものはひどく時代遅れです


私は1つの問題に対処できますJustin raised:RelativeLayoutがインクルードの位置を管理できない(少なくともこの単純なケースでは、1.6エミュレータで)

CommonsWareは、インクルードを一意の親コンテナーにラッピングすることを提案しますが、同じ名前のビューをアドレス指定およびスコープするのを支援するためにJustin's include

それぞれに一意の親コンテナが必要であり、アクティビティではなくそのコンテナ(ViewGroup)でfindViewById()を呼び出します。

実際、RelativeLayoutが期待どおりに動作するようにするには、あなたもそれをしなければなりません

これは動作します(footerは適切に配置されています):

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent" Android:layout_height="fill_parent">
    <include Android:id="@+id/header" layout="@layout/header"
        Android:layout_alignParentTop="true" />
    <WebView Android:id="@+id/webView" Android:layout_below="@id/header"
        Android:background="#77CC0000" Android:layout_height="wrap_content"
        Android:layout_width="fill_parent" Android:focusable="false" />
    <LinearLayout Android:layout_alignParentBottom="true"
        Android:layout_height="wrap_content" Android:layout_width="fill_parent">
        <include Android:id="@+id/footer" layout="@layout/footer" />
    </LinearLayout>
</RelativeLayout>

これはそうではありません(footerは画面上部に浮いています):

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="fill_parent" Android:layout_height="fill_parent">
    <include Android:id="@+id/header" layout="@layout/header"
        Android:layout_alignParentTop="true" />
    <WebView Android:id="@+id/webView" Android:layout_below="@id/header"
        Android:background="#77CC0000" Android:layout_height="wrap_content"
        Android:layout_width="fill_parent" Android:focusable="false" />
    <include Android:id="@+id/footer" layout="@layout/footer"
        Android:layout_alignParentBottom="true" />
</RelativeLayout>

裸のfooterインクルードは、周囲のLinearLayoutなしでは、親の下部に整列しません。この期待される動作を呼び出しません。

さらに、WebViewはIDによってheaderにうまくアタッチしているように見えますが、これは単にヘッダーの下に垂直に流れるため、これは錯覚だと思います。フッターインクルードのすぐ上にボタンを設定しようとしましたが、それもすべて浮いていて間違っていました

RelativeLayoutは1.5でより多くの問題を抱えていましたが、それでも気に入っています:)

33
alienjazzcat

男、これは古いですが、検索の上位に表示されるようですので、コメントします。

ここでの秘theは、<merge>タグと<include>タグを組み合わせることで、そのレベルの「親」ビューグループを本質的に削除することだと思います。では、他の誰かに「layout_below」を要求しているのは誰ですか?誰も。そのレベルにはビューがありません。

<merge>タグは、子ビューを取り、<include>タグの親に直接表示します。したがって、含めるレイアウトの子に、それに応じてアンカーを固定するように依頼する必要があります。

8
Plantage

RelativeLayoutで機能するように配置するには、メインレイアウトファイルではなく、インクルードファイルでlayout_ *パラメーターを設定する必要があります。そのように

main_layout.xml

<RelativeLayout
  Android:id="@+id/header"
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content">
   ....
</RelativeLayout>

<RelativeLayout 
  Android:id="@+id/footer"
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content"
  Android:layout_alignParentBottom="true">
    .....
</RelativeLayout>

<include layout="@layout/content_layout" />

content_layout.xml

<merge xmlns:Android="http://schemas.Android.com/apk/res/Android">
<RelativeLayout
    Android:id="@+id/content"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent"
    Android:layout_above="@id/footer"
    Android:layout_below="@id/header" >

    ....
</RelativeLayout>
</merge>

これは明らかに開発者が望むものではありませんが、xmlの重複を避けるために見つけた唯一の解決策です

4
Maragues

Android:layout_ *属性は、includeタグで使用すると無視されるようで、すべてのマージされたレイアウトが互いの上に表示されます。

私の推測では、レイアウトルールから_Android:id_要素で定義されている_<include>_属性を参照することはできず、「実際の」ウィジェットとコンテナーにあるもののみを参照できます。

また、5の代わりに1つのマージxmlレイアウトファイルを作成する方法を誰かが考えていただければ幸いです。

シンプル:すべてを1つのファイルに入れます。

実行時にマージレイアウトファイルの各アイテムにアクセスする必要があるため、それを行う方法を見つけることができませんでした

_<include>_要素が1つでも1,000でも、実行時にすべてのコンテンツにアクセスできる必要があります。例外は、_Android:id_属性を複製した場合です。ListView行からウィジェットを取得するときと同じように、findViewById()呼び出しを適切にスコープする必要があります。

内容が実行時にnotでアクセス可能であることを実証できる2+マージファイルを使用するサンプルプロジェクトを作成できる場合は、お知らせください。

1
CommonsWare

私は同じ問題を抱えていて、layout_widthおよびlayout_heightそれは機能しませんでした。問題は、私が含めていたレイアウトにタグがあり、それらを削除した後、すべてが魅力のように機能することでした。 mergeはレイアウトタグではなく、そのため、位置とサイズのパラメーターを受け取ることができないと思います。定義したものはすべて内部の親レイアウトに転送されるため、設定は破棄されました。

TL:DR:タグを削除し、xmlns定義を実際のレイアウトビューホルダーに移動するだけで十分です。

前:

<merge
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto">

    <...ui.component.BorderCardView
        Android:layout_width="112dp"
        Android:layout_height="32dp"
        app:cardCornerRadius="4dp"
        app:cardUseCompatPadding="true">

        <ImageView
            Android:layout_width="16dp"
            Android:layout_height="16dp"
            Android:src="@drawable/ic_logout"
            Android:tint="@color/divider" />

    </...ui.component.BorderCardView>
</merge>

ワーキング:

<...ui.component.BorderCardView
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="112dp"
    Android:layout_height="32dp"
    app:cardCornerRadius="4dp"
    app:cardUseCompatPadding="true">

    <ImageView
        Android:layout_width="16dp"
        Android:layout_height="16dp"
        Android:src="@drawable/ic_logout"
        Android:tint="@color/divider" />

</...ui.component.BorderCardView>
0
silvio.pereira

私の場合、インクルードしようとしたレイアウトは<mergeタグで始まります。レイアウトに変更したら、<RelativeLayoutと言いました。以下に図を示します。

ワーキング

<RelativeLayout xmlns:tools="http://schemas.Android.com/tools"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    tools:showIn="@layout/activity_home">

動作しない

<merge xmlns:tools="http://schemas.Android.com/tools"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    tools:showIn="@layout/activity_home">
0
Rohit Mandiwal