web-dev-qa-db-ja.com

RelativeLayoutのパーセント幅

私は自分のAndroidアプリでログインActivityのためのフォームレイアウトに取り組んでいます。以下の画像は、私がそれをどのように見せたいかということです:

enter image description here

私は以下の _ xml _ でこのレイアウトを達成することができました。問題は、それは少しハッキングです。 Host EditTextの幅をハードコードしなければなりませんでした。具体的には、

Android:layout_width="172dp" 

私は本当にHostにパーセンテージ幅を与え、EditTextを移植したいです。 (ホストが80%、ポートが20%など)。これは可能ですか?次のXMLは私のDroid上で動作しますが、すべての画面で動作するとは限りません。私はもっ​​と堅牢な解決策を望みます。

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/main"
    Android:layout_width="fill_parent"
    Android:layout_height="fill_parent" >

    <TextView
        Android:id="@+id/Host_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/home"
        Android:paddingLeft="15dp"
        Android:paddingTop="0dp"
        Android:text="Host"
        Android:textColor="#a5d4e2"
        Android:textSize="25sp"
        Android:textStyle="normal" />

    <TextView
        Android:id="@+id/port_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/home"
        Android:layout_toRightOf="@+id/Host_input"
        Android:paddingTop="0dp"
        Android:text="port"
        Android:textColor="#a5d4e2"
        Android:textSize="25sp"
        Android:textStyle="normal" />

    <EditText
        Android:id="@+id/Host_input"
        Android:layout_width="172dp"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/Host_label"
        Android:layout_marginLeft="15dp"
        Android:layout_marginRight="15dp"
        Android:layout_marginTop="4dp"
        Android:background="@Android:drawable/editbox_background"
        Android:inputType="textEmailAddress" />

    <EditText
        Android:id="@+id/port_input"
        Android:layout_width="100dp"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/Host_label"
        Android:layout_marginTop="4dp"
        Android:layout_toRightOf="@id/Host_input"
        Android:background="@Android:drawable/editbox_background"
        Android:inputType="number" />

    <TextView
        Android:id="@+id/username_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/Host_input"
        Android:paddingLeft="15dp"
        Android:paddingTop="15dp"
        Android:text="username"
        Android:textColor="#a5d4e2"
        Android:textSize="25sp"
        Android:textStyle="normal" />

    <EditText
        Android:id="@+id/username_input"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/username_label"
        Android:layout_marginLeft="15dp"
        Android:layout_marginRight="15dp"
        Android:layout_marginTop="4dp"
        Android:background="@Android:drawable/editbox_background"
        Android:inputType="textEmailAddress" />

    <TextView
        Android:id="@+id/password_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/username_input"
        Android:paddingLeft="15dp"
        Android:paddingTop="15dp"
        Android:text="password"
        Android:textColor="#a5d4e2"
        Android:textSize="25sp"
        Android:textStyle="normal" />

    <EditText
        Android:id="@+id/password_input"
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/password_label"
        Android:layout_marginLeft="15dp"
        Android:layout_marginRight="15dp"
        Android:layout_marginTop="4dp"
        Android:background="@Android:drawable/editbox_background"
        Android:inputType="textPassword" />

    <ImageView
        Android:id="@+id/home"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignParentTop="true"
        Android:layout_centerHorizontal="true"
        Android:layout_centerVertical="false"
        Android:paddingLeft="15dp"
        Android:paddingRight="15dp"
        Android:paddingTop="15dp"
        Android:scaleType="fitStart"
        Android:src="@drawable/home" />

    <Button
        Android:id="@+id/login_button"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_below="@+id/password_input"
        Android:layout_marginLeft="15dp"
        Android:layout_marginTop="15dp"
        Android:text="   login   "
        Android:textSize="18sp" >
    </Button>

</RelativeLayout>
425
Sarson

Android:layout_weight属性を探しています。それはあなたがあなたのレイアウトを定義するためにパーセンテージを使うことを可能にするでしょう。

次の例では、左ボタンはスペースの70%を使用し、右ボタンは30%を使用します。

<LinearLayout
    Android:layout_width="match_parent" 
    Android:layout_height="wrap_content"
    Android:orientation="horizontal">

    <Button
        Android:text="left" 
        Android:layout_width="0dp" 
        Android:layout_height="wrap_content" 
        Android:layout_weight=".70" /> 

    <Button
        Android:text="right" 
        Android:layout_width="0dp" 
        Android:layout_height="wrap_content" 
        Android:layout_weight=".30" />

</LinearLayout>

どの種類のViewでも同じように機能します。ニーズに合わせてボタンをEditTextに置き換えることができます。

必ずlayout_width0dpに設定してください。そうしないと、ビューが適切に拡大縮小されない可能性があります。

重みの合計が1に等しい必要はないことに注意してください、私はそれがこのように読みやすいのを見つけるだけです。最初の重みを7に、2番目の重みを3に設定すると、同じ結果が得られます。

727
Dalmas

これは70/30分割のための最初の質問には全く答えませんが、コンポーネント間の50/50分割の特別な場合には方法があります。興味のある2つの要素。

<RelativeLayout 
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content">
    <View Android:id="@+id/strut"
        Android:layout_width="0dp"
        Android:layout_height="0dp" 
        Android:layout_centerHorizontal="true"/>
    <Button
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_alignRight="@id/strut"
        Android:layout_alignParentLeft="true"
        Android:text="Left"/> 
    <Button 
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_alignLeft="@id/strut"
        Android:layout_alignParentRight="true"
        Android:text="Right"/>
</RelativeLayout>

これはかなり一般的なケースですので、この解決策は単なる好奇心以上のものです。それは少しハックですが効率的なものです、なぜなら空の、ゼロサイズのストラットはほとんどコストがかからないはずだからです。

ただし、一般的には、Androidの標準的なレイアウトから期待しすぎないことが最善です。

282
olefevre

更新1

@EmJiHash PERCENTRELATIVELAYOUTで指摘されているように、APIレベル26.0.0では非推奨です。

以下のグーグルコメントを引用:

このクラスはAPIレベル26.0.0で非推奨となりました。代わりにConstraintLayoutとそれに関連するレイアウトの使用を検討してください。以下は、ConstraintLayoutを使用してパーセントレイアウトの機能を複製する方法を示しています。


GoogleはANDROID.SUPPORT.PERCENTという新しいAPIを導入しました

それからあなたはただビューによって取るためにパーセントを指定することができます

コンパイル依存関係を追加する

compile 'com.Android.support:percent:22.2.0

その中で、 PercentRelativeLayout はパーセンテージワイズレイアウトを実現できるものです。

 <Android.support.percent.PercentRelativeLayout
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
     xmlns:app="http://schemas.Android.com/apk/res-auto"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent">
     <ImageView
         app:layout_widthPercent="50%"
         app:layout_heightPercent="50%"
         app:layout_marginTopPercent="25%"
         app:layout_marginLeftPercent="25%"/>
 </Android.support.percent.PercentRelativeLayout>
129
N J

RelativeLayout内のビューの寸法を定義するためにパーセンテージを使用することはできません。そのための最善の方法は、LinearLayoutとウェイト、またはカスタムレイアウトを使用することです。

78
Romain Guy

新しいパーセントサポートライブラリを見てください。

compile 'com.Android.support:percent:22.2.0'

docs

サンプル

31
gbero

PercentRelativeLayout を使用することができます。これはデザインサポートライブラリへの最近の文書化されていない追加で、相対的な要素だけでなく合計パーセントも指定できるようにします。利用可能なスペース.

パーセンテージベースのディメンションとマージンをサポートするRelativeLayoutのサブクラス。 "Percent"サフィックスを持つ属性を使用して、ディメンションまたは子の余白を指定できます。

<Android.support.percent.PercentRelativeLayout
     xmlns:Android="http://schemas.Android.com/apk/res/Android"
     xmlns:app="http://schemas.Android.com/apk/res-auto"
     Android:layout_width="match_parent"
     Android:layout_height="match_parent">
  <ImageView
      Android:layout_width="match_parent"
      Android:layout_height="match_parent"
      app:layout_widthPercent="50%"
      app:layout_heightPercent="50%"
      app:layout_marginTopPercent="25%"
      app:layout_marginLeftPercent="25%"/>
</Android.support.percent.PercentFrameLayout>

Percentパッケージは、アプリ内で割合の追加と管理をサポートするためのAPIベースのディメンションを提供します。

使用するには、このGradle依存関係へのライブラリリストを追加する必要があります。

dependencies {
    compile 'com.Android.support:percent:22.2.0'//23.1.1
}
18
IntelliJ Amiya

これを解決してカスタムビューを作成しました。

public class FractionalSizeView extends View {
  public FractionalSizeView(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public FractionalSizeView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    setMeasuredDimension(width * 70 / 100, 0);
  }
}

これは、RelativeLayout内で他のビューを調整するために使用できる目に見えない支柱です。

11
Ivan Volosyuk

アップデート

@EmJiHashで示されているように、PercentRelativeLayoutとPercentFrameLayoutはAPIレベル26.0.0では推奨されていません。

ConstraintLayoutの使用を検討してください

Googleは と呼ばれる新しいAPIを導入しました - Android.support.percent

1)PercentRelativeLayout

2)PercentFrameLayout

コンパイル依存関係を追加する

compile 'com.Android.support:percent:23.1.1'

ディメンションをパーセントで指定できるので、RelativeLayoutとpercentageの両方の利点が得られます。

 <Android.support.percent.PercentRelativeLayout
         xmlns:Android="http://schemas.Android.com/apk/res/Android"
         xmlns:app="http://schemas.Android.com/apk/res-auto"
         Android:layout_width="match_parent"
         Android:layout_height="match_parent"/>
     <TextView
         app:layout_widthPercent="40%"
         app:layout_heightPercent="40%"
         app:layout_marginTopPercent="15%"
         app:layout_marginLeftPercent="15%"/>
 </Android.support.percent.PercentRelativeLayout/>
11
Cold Fire

PercentRelativeLayoutは26.0.0で廃止され、RelativeLayout内のLinearLayoutのようなネストされたレイアウトはパフォーマンスに悪影響を及ぼします( ConstraintLayoutのパフォーマンス上の利点の理解 )パーセンテージ幅を達成するための最良の選択肢はConsttiveLayoutをConstraintLayoutに置き換えることです。

これは2つの方法で解決できます。

解決策#1パーセントオフセット付きのガイドラインを使用する

Layout Editor

<Android.support.constraint.ConstraintLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <TextView
        Android:id="@+id/Host_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Host"
        Android:layout_marginTop="16dp"
        Android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/Host_input" />

    <TextView
        Android:id="@+id/port_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Port"
        Android:layout_marginTop="16dp"
        Android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/port_input" />

    <EditText
        Android:id="@+id/Host_input"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="8dp"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:inputType="textEmailAddress"
        app:layout_constraintTop_toBottomOf="@+id/Host_label"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/guideline" />

    <EditText
        Android:id="@+id/port_input"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="8dp"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:inputType="number"
        app:layout_constraintTop_toBottomOf="@+id/port_label"
        app:layout_constraintLeft_toLeftOf="@+id/guideline"
        app:layout_constraintRight_toRightOf="parent" />

    <Android.support.constraint.Guideline
        Android:id="@+id/guideline"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:orientation="vertical"
        app:layout_constraintGuide_percent="0.8" />

</Android.support.constraint.ConstraintLayout>

解決策#2 EditTextに重み付き幅のチェーンを使用する

Layout Editor

<Android.support.constraint.ConstraintLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <TextView
        Android:id="@+id/Host_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Host"
        Android:layout_marginTop="16dp"
        Android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/Host_input" />

    <TextView
        Android:id="@+id/port_label"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:text="Port"
        Android:layout_marginTop="16dp"
        Android:layout_marginLeft="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintLeft_toLeftOf="@+id/port_input" />

    <EditText
        Android:id="@+id/Host_input"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="8dp"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:inputType="textEmailAddress"
        app:layout_constraintHorizontal_weight="0.8"
        app:layout_constraintTop_toBottomOf="@+id/Host_label"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@+id/port_input" />

    <EditText
        Android:id="@+id/port_input"
        Android:layout_width="0dp"
        Android:layout_height="wrap_content"
        Android:layout_marginTop="8dp"
        Android:layout_marginLeft="8dp"
        Android:layout_marginRight="8dp"
        Android:inputType="number"
        app:layout_constraintHorizontal_weight="0.2"
        app:layout_constraintTop_toBottomOf="@+id/port_label"
        app:layout_constraintLeft_toRightOf="@+id/Host_input"
        app:layout_constraintRight_toRightOf="parent" />

</Android.support.constraint.ConstraintLayout>

どちらの場合も、次のようになります。

Result View

6
Eugene Brusov

PercentRelativeLayout はサポートライブラリのリビジョン26.0.0から廃止予定です。

Googleは ConstraintLayout という新しいレイアウトを導入しました。

ライブラリをモジュールレベルのbuild.gradleファイルに依存関係として追加します。

     dependencies {
        compile 'com.Android.support.constraint:constraint-layout:1.0.1'
      }

レイアウトファイルを追加するだけです。

<?xml version="1.0" encoding="utf-8"?>
<Android.support.constraint.ConstraintLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">
</Android.support.constraint.ConstraintLayout>

制約

制約を使用すると、ウィジェットを整列させることができます。以下に示す制約ハンドルなどのアンカーを使用して、さまざまなウィジェット間の配置規則を決定できます。

  1. Wrap Content:ビューはその内容に合わせて必要に応じて拡張されます。
  2. Match Constraints:マージンを考慮した後、必要に応じてビューが拡大され、制約の定義を満たすようになります。ただし、指定されたディメンションに制約が1つしかない場合、ビューはその内容に合わせて拡大されます。このモードを高さまたは幅のいずれかで使用すると、サイズ比を設定することもできます。
  3. Fixed:下のテキストボックスで特定の寸法を指定するか、エディタでビューのサイズを変更してください。
  4. Spread:ビューは均等に分配されます(マージンが考慮された後)。これがデフォルトです。
  5. Spread inside:最初と最後のビューはチェーンの両端の制約に固定され、残りは均等に分散されています。
  6. Weighted:チェーンがスプレッドまたは内側に広がるように設定されている場合、1つ以上のビューを "制約に一致"(0dp)に設定することで残りのスペースを埋めることができます。デフォルトでは、スペースは「制約の一致」に設定されている各ビュー間で均等に分散されますが、layout_constraintHorizo​​ntal_weight属性とlayout_constraintVertical_weight属性を使用して、各ビューに重要度の重みを割り当てることができます。線形レイアウトでlayout_weightを使い慣れている場合でも、これは同じように機能します。そのため、最も高い重み値を持つビューが最も多くのスペースを使用します。同じ重みを持つビューは、同じ量のスペースを取得します。
  7. Packed:ビューはマージンが考慮された後にまとめられます。チェーンのヘッドビューバイアスを変更することで、チェーン全体のバイアス(左/右または上/下)を調整できます。
  8. Center Horizontally or Center Vertically:ビューのチェーンをすばやく作成するには、それらをすべて選択し、ビューの1つを右クリックしてから、水平方向または垂直方向の中央を選択して、水平または垂直方向のチェーンを作成します。
  9. Baseline alignment:ビューのテキストベースラインを別のビューのテキストベースラインに揃えます。
  10. Constrain to a guideline:ビューを制限できる垂直または水平のガイドラインを追加できます。ガイドラインはアプリユーザーには見えません。レイアウトのエッジに対する相対的なdp単位またはパーセントに基づいて、レイアウト内にガイドラインを配置できます。
  11. Adjust the constraint bias:ビューの両側に制約を追加すると(そして同じ寸法のビューサイズが "fixed"か "wrap content"のどちらか)、デフォルトでは50%の偏りでビューは2つの制約の間の中心になります。プロパティウィンドウのバイアススライダをドラッグしてバイアスを調整できます。
  12. Set size as a ratio:ビューのサイズの少なくとも1つが "制約の一致"(0dp)に設定されている場合は、ビューのサイズを16:9などの比率に設定できます。

あなたは公式の doc からもっと学ぶことができます。

6
Darish

興味深いことに、@olefevreからの答えを基にして、「見えないストラット」で50/50のレイアウトを行うことができるだけでなく、2のべき乗を含むあらゆる種類のレイアウトを行うことができます。

たとえば、幅を4つの等しい部分(実際には3、1、1、2の重みを持つ)にカットするレイアウトは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content" >

    <View
        Android:id="@+id/strut"
        Android:layout_width="1dp"
        Android:layout_height="match_parent"
        Android:layout_centerHorizontal="true"
        Android:background="#000000" />

    <RelativeLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_toLeftOf="@+id/strut" >

        <View
            Android:id="@+id/left_strut"
            Android:layout_width="1dp"
            Android:layout_height="match_parent"
            Android:layout_toLeftOf="@+id/strut"
            Android:layout_centerHorizontal="true"
            Android:background="#000000" />

        <Button
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_alignParentLeft="true"
            Android:layout_alignRight="@+id/left_strut"
            Android:text="Far Left" />

        <Button
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_alignParentRight="true"
            Android:layout_toRightOf="@+id/left_strut"
            Android:text="Near Left" />
    </RelativeLayout>

        <Button
            Android:layout_width="0dp"
            Android:layout_height="wrap_content"
            Android:layout_alignLeft="@id/strut"
            Android:layout_alignParentRight="true"
            Android:text="Right" />

</RelativeLayout>
3
coco

あなたはレイアウトの重みによってこれを達成することができます。重みによって、画面の要求されていない部分がどのように分割されるかが決まります。各EditTextにlayout_widthを0にし、それに比例した重みを付けます。つまり、最初に2倍のスペースを取りたい場合は、一方に2の重みを付け、もう一方に1の重みを付けます。

3
Cheryl Simon

2つのテキストビューのホストとポートを独立した直線レイアウトの水平に配置し、Android:layout_weightを使用してパーセンテージを設定します。

3
Cyatophilum

https://github.com/mmin18/FlexLayout を確認してください。レイアウトxmlにパーセントまたはJava式を直接使用できます。

<EditText
    app:layout_left="0%"
    app:layout_right="60%"
    app:layout_height="wrap_content"/>
<EditText
    app:layout_left="prev.right+10dp"
    app:layout_right="100%"
    app:layout_height="wrap_content"/>
1
mmin