Android
layouter
Sök…
Introduktion
En layout definierar den visuella strukturen för ett användargränssnitt, till exempel en aktivitet eller widget.
En layout deklareras i XML, inklusive skärmelement som kommer att visas i den. Koden kan läggas till i applikationen för att ändra tillståndet för skärmobjekt vid körning, inklusive de som deklareras i XML.
Syntax
- android: gravitation = "top | botten | vänster | höger | center_vertical | fill_vertical | center_horizontal | fill_horizontal | center | fyllning | clip_vertical | clip_horizontal | start | end"
- android: layout_gravity = "top | botten | vänster | höger | center_vertical | fill_vertical | center_horizontal | fill_horizontal | center | fyllning | clip_vertical | clip_horizontal | start | end"
Anmärkningar
LayoutParams och Layout_ Attribut
Effektpåverkan från att använda RelativeLayouts nära toppen av din visningshierarki
Som förklarats i denna artikel om prestanda i Android kräver en RelativeLayout två layoutpass för att kunna visas korrekt. För komplexa visningshierarkier kan detta ha en betydande inverkan på prestandan. Nesting RelativeLayouts gör detta problem ännu värre, eftersom varje RelativeLayout får antalet layoutpasseringar att öka.
Linear
LinearLayout är en ViewGroup som ordnar sina barn i en enda kolumn eller en enda rad. Orienteringen kan ställas in genom att anropa metoden setOrientation() eller använda xml-attributet android:orientation .
- Vertikal orientering :
android:orientation="vertical"
<?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:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@android:string/cancel" />
</LinearLayout>
Här är en skärmdump hur detta kommer att se ut:
Horisontell orientering :
android:orientation="horizontal"<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/app_name" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@android:string/cancel" />
LinearLayout stöder också att tilldela en vikt till enskilda barn med attributet android:layout_weight .
RelativeLayout
RelativeLayout är en ViewGroup som visar ViewGroup i relativa positioner. Som standard ritas alla barnvyer uppe till vänster i layouten, så du måste definiera positionen för varje vy med hjälp av de olika layoutegenskaper som finns tillgängliga från RelativeLayout.LayoutParams . Värdet för varje layoutegenskap är antingen en boolesisk för att möjliggöra en layoutposition i förhållande till överordnade RelativeLayout eller ett ID som refererar till en annan vy i den layout som vyn ska placeras mot.
Exempel:
<?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="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:src="@mipmap/ic_launcher" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_toRightOf="@+id/imageView"
android:layout_toEndOf="@+id/imageView"
android:hint="@string/hint" />
</RelativeLayout>
Här är en skärmdump hur detta kommer att se ut:
Gravitet och layout tyngdkraft
android: layout_gravity
-
android:layout_gravityanvänds för att ställa in positionen för ett element i dess överordnade (t.ex. ett barnViewinuti enLayout). - Stöds av LinearLayout och FrameLayout
android: gravitation
-
android:gravityanvänds för att ställa in innehållets placering i ett element (t.ex. en text i enTextView).
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:layout_gravity="left"
android:gravity="center_vertical">
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/first"
android:background="@color/colorPrimary"
android:gravity="left"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/second"
android:background="@color/colorPrimary"
android:gravity="center"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/third"
android:background="@color/colorPrimary"
android:gravity="right"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center_vertical">
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/first"
android:background="@color/colorAccent"
android:gravity="left"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/second"
android:background="@color/colorAccent"
android:gravity="center"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/third"
android:background="@color/colorAccent"
android:gravity="right"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical"
android:layout_gravity="right"
android:gravity="center_vertical">
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/first"
android:background="@color/colorPrimaryDark"
android:gravity="left"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/second"
android:background="@color/colorPrimaryDark"
android:gravity="center"/>
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/third"
android:background="@color/colorPrimaryDark"
android:gravity="right"/>
</LinearLayout>
</LinearLayout>
Vilket görs enligt följande:
Rutnätslayout
GridLayout, som namnet antyder är en layout som används för att ordna Visningar i ett rutnät. En GridLayout delar upp sig i kolumner och rader. Som du kan se i exemplet nedan anges mängden kolumner och / eller rader av egenskaperna columnCount och rowCount . Om du lägger till vyer i denna layout läggs den första vyn till den första kolumnen, den andra vyn i den andra kolumnen och den tredje vyn i den första kolumnen i den andra raden.
<?xml version="1.0" encoding="utf-8"?>
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:columnCount="2"
android:rowCount="2">
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/first"
android:background="@color/colorPrimary"
android:layout_margin="@dimen/default_margin" />
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/second"
android:background="@color/colorPrimary"
android:layout_margin="@dimen/default_margin" />
<TextView
android:layout_width="@dimen/fixed"
android:layout_height="wrap_content"
android:text="@string/third"
android:background="@color/colorPrimary"
android:layout_margin="@dimen/default_margin" />
</GridLayout>
Procentlayouter
Procent Support Library ger PercentFrameLayout och PercentRelativeLayout , två ViewGroups som ger ett enkelt sätt att ange Visa dimensioner och marginaler i termer av en procentandel av den totala storleken.
Du kan använda Procent Support Library genom att lägga till följande i dina beroenden.
compile 'com.android.support:percent:25.3.1'
Om du ville visa en vy som fyller skärmen horisontellt men bara halva skärmen vertikalt skulle du göra följande.
<android.support.percent.PercentFrameLayout
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">
<FrameLayout
app:layout_widthPercent="100%"
app:layout_heightPercent="50%"
android:background="@android:color/black" />
<android.support.percent.PercentFrameLayout>
Du kan också definiera procentsatserna i en separat XML-fil med kod som:
<fraction name="margin_start_percent">25%</fraction>
Och hänvisa till dem i dina layouter med @fraction/margin_start_percent .
De innehåller också möjligheten att ställa in ett anpassat bildförhållande via app:layout_aspectRatio .
Detta gör att du bara kan ställa in en enda dimension, till exempel bara bredden, och höjden bestäms automatiskt baserat på det bildförhållande du har definierat, oavsett om det är 4: 3 eller 16: 9 eller till och med en kvadrat 1: 1 sidförhållande.
Till exempel:
<ImageView
app:layout_widthPercent="100%"
app:layout_aspectRatio="178%"
android:scaleType="centerCrop"
android:src="@drawable/header_background"/>
FrameLayout
FrameLayout är utformad för att blockera ett område på skärmen för att visa ett enda objekt. Du kan dock lägga till flera barn till en FrameLayout och kontrollera deras position inom FrameLayout genom att tilldela allvar till varje barn med attributet Android: layout_gravity .
Vanligtvis används FrameLayout för att hålla en enskild barnvy. Vanliga fall skapar platshållare för att blåsa upp Fragments i Activity , överlappa vyer eller tillämpa förgrunden till vyerna.
Exempel:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/nougat"
android:scaleType="fitCenter"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<TextView
android:text="FrameLayout Example"
android:textSize="30sp"
android:textStyle="bold"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"/>
</FrameLayout>
Det kommer att se ut så här:
CoordinatorLayout
CoordinatorLayout är en behållare som liknar FrameLayout men med extra kapacitet kallas den superdrivna FrameLayout i den officiella dokumentationen.
Genom att ansluta en CoordinatorLayout.Behavior till ett direkt barn av CoordinatorLayout kan du fånga beröringshändelser, fönsterinsatser, mätning, layout och kapslad rullning.
För att kunna använda den måste du först lägga till ett beroende för supportbiblioteket i din gradle-fil:
compile 'com.android.support:design:25.3.1'
Numret på den senaste versionen av biblioteket kan hittas här
Ett praktiskt fall med CoordinatorLayout är att skapa en vy med en FloatingActionButton . I detta specifika fall kommer vi att skapa en RecyclerView med en SwipeRefreshLayout och en FloatingActionButton ovanpå. Så här kan du göra det:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coord_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/recycler_view"/>
</android.support.v4.widget.SwipeRefreshLayout>
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:color="@color/colorAccent"
android:src="@mipmap/ic_add_white"
android:layout_gravity="end|bottom"
app:layout_anchorGravity="bottom|right|end"/>
</android.support.design.widget.CoordinatorLayout>
Lägg märke till hur FloatingActionButton är förankrat i CoordinatorLayout med app:layout_anchor="@id/coord_layout"
KoordinatorLayout Rullningsbeteende
En bifogad CoordinatorLayout kan användas för att uppnå rullningseffekter för materialdesign när du använder inre layouter som stöder kapslad rullning, till exempel NestedScrollView eller RecyclerView .
För detta exempel:
-
app:layout_scrollFlags="scroll|enterAlways"används i verktygsfältets egenskaper -
app:layout_behavior="@string/appbar_scrolling_view_behavior"används i ViewPager-egenskaperna - En RecyclerView används i ViewPager-fragmenten
Här är layout-xml-filen som används i en aktivitet:
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_layout"
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=".MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="6dp">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:elevation="0dp"
app:layout_scrollFlags="scroll|enterAlways"
/>
<android.support.design.widget.TabLayout
android:id="@+id/tab_layout"
app:tabMode="fixed"
android:layout_below="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:elevation="0dp"
app:tabTextColor="#d3d3d3"
android:minHeight="?attr/actionBarSize"
/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_below="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
Resultat:
Visa vikt
Ett av de mest använda attributen för LinearLayout är vikten av sina barnvyer. Vikt definierar hur mycket utrymme en vy kommer att förbrukas jämfört med andra vyer inom en LinearLayout.
Vikt används när du vill ge specifikt skärmutrymme till en komponent jämfört med en annan.
Viktiga egenskaper :
weightSumär den totala summan av vikterna för alla barnvyer. Om du inte angerweightSumkommer systemet att beräkna summan av alla vikterna på egen hand.layout_weightanger mängden utrymme ur den totala viktsumman som widgeten kommer att uppta.
Koda:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="4">
<EditText
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Type Your Text Here" />
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Text1" />
<Button
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="Text1" />
</LinearLayout>
Utgången är:
Även om enhetens storlek är större tar EditText 2/4 av skärmens utrymme. Därför ses appens utseende konsekvent på alla skärmar.
Obs: Här layout_width hålls 0dp som widgeten utrymmet delas horisontellt. Om widgets ska justeras vertikalt kommer layout_height att ställas in på 0dp . Detta görs för att öka effektiviteten för koden eftersom systemet under körning inte kommer att försöka beräkna bredden respektive höjden eftersom det hanteras av vikten. Om du istället använde wrap_content skulle systemet försöka beräkna bredden / höjden först innan du använder wrap_content som orsakar en annan beräkningscykel.
Skapa LinearLayout programmatiskt
Hierarki
- LinearLayout(horizontal)
- ImageView
- LinearLayout(vertical)
- TextView
- TextView
Koda
LinearLayout rootView = new LinearLayout(context);
rootView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
rootView.setOrientation(LinearLayout.HORIZONTAL);
// for imageview
ImageView imageView = new ImageView(context);
// for horizontal linearlayout
LinearLayout linearLayout2 = new LinearLayout(context);
linearLayout2.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
linearLayout2.setOrientation(LinearLayout.VERTICAL);
TextView tv1 = new TextView(context);
TextView tv2 = new TextView(context);
// add 2 textview to horizontal linearlayout
linearLayout2.addView(tv1);
linearLayout2.addView(tv2);
// finally, add imageview and horizontal linearlayout to vertical linearlayout (rootView)
rootView.addView(imageView);
rootView.addView(linearLayout2);
LayoutParams
Varje enskild ViewGroup (t.ex. LinearLayout , RelativeLayout , CoordinatorLayout , etc.) måste lagra information om sina barns egenskaper. Om hur barnen läggs ut i ViewGroup . Denna information lagras i objekt i en omslagsklass ViewGroup.LayoutParams .
För att inkludera parametrar som är specifika för en viss ViewGroups använder ViewGroups underklasser i klassen ViewGroup.LayoutParams .
T.ex.
-
LinearLayoutdet ärLinearLayout.LayoutParams -
RelativeLayoutdet ärRelativeLayout.LayoutParams -
CoordinatorLayoutdet ärCoordinatorLayout.LayoutParams - ...
De flesta av ViewGroups återanvänder förmågan att sätta margins för sina barn, så att de inte underklasserar ViewGroup.LayoutParams direkt, men de underklasserar ViewGroup.MarginLayoutParams istället (som i sig är en underklass för ViewGroup.LayoutParams ).
LayoutParams i xml
LayoutParams objekt skapas baserat på den uppblåsta layout- xml filen.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="50dp"
android:layout_gravity="right"
android:gravity="bottom"
android:text="Example text"
android:textColor="@android:color/holo_green_dark"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/holo_green_dark"
android:scaleType="centerInside"
android:src="@drawable/example"/>
</LinearLayout>
Alla parametrar som börjar med layout_ anger hur den bifogade layouten ska fungera. När layouten blåses upp lindas dessa parametrar i ett korrekt LayoutParams objekt, som senare kommer att användas av Layout att korrekt placera en viss View i ViewGroup . Andra egenskaper hos en View är direkt View relaterade och bearbetas av View själv.
För TextView :
-
layout_width,layout_heightochlayout_gravitylagras i ettLinearLayout.LayoutParamsobjekt och används avLinearLayout -
gravity,textochtextColorkommer att användas avTextViewsjälv
För ImageView :
-
layout_width,layout_heightochlayout_weightlagras i ettLinearLayout.LayoutParamsobjekt och används avLinearLayout -
background,scaleTypeochsrckommer att användas avImageViewsjälv
LayoutParams objekt
getLayoutParams är en View's metod som gör det möjligt att hämta ett aktuellt LayoutParams objekt.
Eftersom LayoutParams objektet är direkt relaterad till den omslutande ViewGroup kommer denna metod returnerar en icke-noll-värde endast när View är ansluten till ViewGroup . Du måste tänka på att detta objekt kanske inte är närvarande hela tiden. Särskilt bör du inte vara beroende av att ha den i View's konstruktör.
public class ExampleView extends View {
public ExampleView(Context context) {
super(context);
setupView(context);
}
public ExampleView(Context context, AttributeSet attrs) {
super(context, attrs);
setupView(context);
}
public ExampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupView(context);
}
private void setupView(Context context) {
if (getLayoutParams().height == 50){ // DO NOT DO THIS!
// This might produce NullPointerException
doSomething();
}
}
//...
}
Om du vill vara beroende av att ha LayoutParams objekt, bör du använda onAttachedToWindow metoden istället.
public class ExampleView extends View {
public ExampleView(Context context) {
super(context);
}
public ExampleView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ExampleView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (getLayoutParams().height == 50) { // getLayoutParams() will NOT return null here
doSomething();
}
}
//...
}
Casting LayoutParams objekt
Du kanske behöver använda funktioner som är specifika för en viss ViewGroup (t.ex. kan du programmatiskt ändra regler för en RelativeLayout ). För detta ändamål måste du veta hur du kastar ViewGroup.LayoutParams objektet ViewGroup.LayoutParams .
Det här kan vara lite förvirrande när du får ett LayoutParams objekt för en View som faktiskt är en annan ViewGroup .
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/outer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/inner_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="right"/>
</LinearLayout>
VIKTIGT: Typen av LayoutParams objekt är direkt relaterad till typen av ENCLOSING ViewGroup .
Felaktig gjutning :
FrameLayout innerLayout = (FrameLayout)findViewById(R.id.inner_layout);
FrameLayout.LayoutParams par = (FrameLayout.LayoutParams) innerLayout.getLayoutParams();
// INCORRECT! This will produce ClassCastException
Rätt gjutning :
FrameLayout innerLayout = (FrameLayout)findViewById(R.id.inner_layout);
LinearLayout.LayoutParams par = (LinearLayout.LayoutParams) innerLayout.getLayoutParams();
// CORRECT! the enclosing layout is a LinearLayout







