Aan de slag met natuurlijke indelingen van React

In deze tutorial leer je hoe je React Native-apps kunt indelen en hoe je lay-outs kunt implementeren die vaak in apps worden gebruikt. Dit omvat de stapellay-out, rasterlay-out en absolute lay-out. Ik ga ervan uit dat je de basiskennis van het ontwerpen van een React Native app al kent en hoe je CSS in het algemeen kunt gebruiken, dus ik zal niet te veel opletten StyleSheet.create en hoe je styling toevoegt aan verschillende elementen.

Je vindt de volledige broncode voor deze tutorial op GitHub.

Project Setup

Om het u gemakkelijk te maken, gebruiken we React Native voor web. Met de React Native voor Web Starter kunnen we eenvoudig een nieuw React Native-project opstarten dat in de browser kan worden uitgevoerd. Deze code is 100% compatibel met het React Native-project. We zullen een afzonderlijke component maken voor elke lay-out die we zullen implementeren, zodat u ze gemakkelijk kunt importeren in een normaal React Native-project als u dat wilt. We gebruiken React Native voor web alleen omdat het gemakkelijker is om het in gebruik te nemen. 

U kunt de volgende opdrachten uitvoeren om het project in te stellen:

git clone https://github.com/grabcode/react-native-web-starter.git RNLayouts cd RNLayouts rm -rf .git npm install

Zodra het klaar is met installeren, navigeer je binnen de app / components directory. Dit is waar de bestanden zijn waar we voornamelijk aan zullen werken. 

Open de App.js bestand en vervang de standaardcode door het volgende:

import Reageren, Component uit 'reageren'; // importeer de componenten die we hier gaan maken exportklasse App-uitbreidingen Component render () return (// gebruik de componenten hier); 

Later kunt u de componenten die we gaan maken importeren en ze vervolgens vanuit dit bestand teruggeven. Onthoud gewoon dat elk onderdeel dat we opslaan in de lay-outs map mag niet worden weergegeven met iets anders. Bijvoorbeeld, als we dat hebben lay-outs / StackLayout.js, doe het volgende in App.js:

import Reageren, Component uit 'reageren'; // importeer de componenten die we hier zullen maken importeer StackLayout van './layouts/StackLayout'; exportklasse-app breidt component render () terug (  ); 

U kunt het project bedienen door het volgende commando uit te voeren:

npm run dev

Dit geeft u toegang tot het in de browser door het te bezoeken http: // localhost: 3000. Een herladen van de volledige pagina wordt geactiveerd als u een wijziging aanbrengt in een van de bestanden die momenteel zijn geïmporteerd uit de App.js het dossier.

Hoe verschillende lay-outs te maken

Layouts in React Native gebruiken een subset van Flexbox. (Ik zeg "subset" omdat niet alle functies die in de Flexbox-specificatie zijn opgenomen.) Dus als u Flexbox al kent, kunt u die vaardigheden gemakkelijk toepassen in React Native. Het is ook vermeldenswaard dat er geen drijvers of op percentage gebaseerde eenheden in React Native zijn. Dit betekent dat we alleen lay-outs kunnen doen met behulp van Flexbox en CSS-positionering.

Stapel lay-out

Het eerste type lay-out dat we zullen implementeren, is de stapellay-out. Voor verticale oriëntatie stapelt het elementen op elkaar, terwijl voor horizontale oriëntatie de elementen naast elkaar worden geplaatst. Laten we eerst de verticale richting bekijken:

Dit is de code om de bovenstaande lay-out te voltooien:

import Reageren, Component uit 'reageren'; import StyleSheet, View, Dimensions van 'react native'; var height = Dimensions.get ('venster'); var box_count = 3; var box_height = height / box_count; export standaardklasse VerticalStackLayout breidt component render () return (uit (      );  const styles = StyleSheet.create (container: flex: 1, flexDirection: 'column', box: height: box_height, box1: backgroundColor: '# 2196F3', box2: backgroundColor: '# 8BC34A ', box3: backgroundColor:' # e3aa1a '); 

Als we de bovenstaande code doorbreken, krijgen we eerst de hoogte van de beschikbare ruimte voor de app om te consumeren. Vervolgens berekenen we wat de hoogte van elke doos zal zijn. Omdat we drie vakken hebben, verdelen we deze door drie.

var height = Dimensions.get ('venster'); var box_count = 3; var box_height = height / box_count;

Voor de markup moeten de dozen in een container worden gewikkeld. Gemeenschappelijke stijlen worden gedeclareerd in de doos object en unieke achtergrondkleuren worden toegepast op objecten met een unieke naam (box1, box2, box3):

    

Om Flexbox te gebruiken, moet u de buigen eigendom op de container. De waarde is de hoeveelheid ruimte die het zal verbruiken. Als het is 1, het betekent dat het alle beschikbare ruimte verbruikt, op voorwaarde dat het element geen broers of zussen heeft. We zullen een voorbeeld van gebruik bekijken buigen met broers en zussen later. 

flexDirection kunt u de primaire as van de lay-out opgeven. Standaard is dit ingesteld op kolom. omgeving flexDirection naar kolom betekent dat de kinderen van de container verticaal worden opgesteld (op elkaar gestapeld) terwijl ze worden geplaatst rij betekent dat de kinderen horizontaal (naast elkaar) worden neergelegd. Om dezelfde hoogte te bereiken, stelt u de hoogte in van de doos tot die van de waarde die we eerder hebben berekend.

const styles = StyleSheet.create (container: flex: 1, flexDirection: 'column', box: height: box_height // plaats deze, box1: backgroundColor: '# 2196F3', box2: backgroundColor : '# 8BC34A', box3: backgroundColor: '# e3aa1a'); 

Hier is een afbeelding om u te helpen visualiseren hoe de inhoud zal stromen op basis van de flexDirection die u hebt opgegeven.

De methode die ik zojuist heb laten zien, is de handmatige manier om dingen te doen. De ... gebruiken Dimensies het berekenen van de breedte of hoogte van de elementen mislukt als uw app zowel de staande als liggende apparaatoriëntatie ondersteunt. Dat komt omdat zodra de gebruiker zijn apparaat omdraait, de breedte of hoogte die u eerder hebt berekend verkeerd is. React Native zal het niet automatisch opnieuw voor u berekenen, dus de app ziet er raar uit.

Flexbox kan de berekening eigenlijk voor u uitvoeren als u alleen de juiste waarden opgeeft. Om dezelfde lay-out als hierboven te bereiken zonder de Dimensies, het enige wat je hoeft te doen is specificeren flex: 1 voor alle vakken in plaats van de hoogte:

vak: flex: 1,

Dit is nu een voorbeeld van gebruik buigen met broers en zussen. Nu hebben we drie broers en zussen met hetzelfde buigen waarde. Dit betekent dat ze alle drie dezelfde beschikbare ruimte zullen delen sinds de buigen waarde is hetzelfde. (Je kunt elk willekeurig gebruiken buigen waarde zolang de onderliggende elementen allemaal dezelfde waarde hebben.)

Met behulp van deze kennis kunt u nu lay-outs bereiken met een koptekst, inhoud en een voettekst:

// header box1: flex: 1, backgroundColor: '# 2196F3', // content box2: flex: 10, backgroundColor: '# 8BC34A', // footer box3: flex: .5, backgroundColor: ' # e3aa1a '

Hier is hoe het eruit zal zien:

Merk op dat dit statisch is. Dus als je hoofdinhoud hoger wordt dan de maximaal beschikbare hoogte, dan wordt de rest van je inhoud verborgen. Als u verwacht dat uw inhoud die limiet overschrijdt, kunt u de ingebouwde functie gebruiken ScrollView component om automatisch een verticale schuifbalk te genereren, net als in webpagina's. 

Horizontale stapellay-outs

Om horizontale stapellay-outs te implementeren, hoeft u alleen het flexDirection naar rij.

 container: flex: 1, flexDirection: 'rij',

Als we de doos veranderen buigen waarde terug naar 1, dit resulteert in de volgende uitvoer:

Het enige dat we hebben veranderd is het flexDirection, die nu is ingesteld op rij. Omdat de vakken allemaal zijn ingesteld op flex: 1, ze hebben dezelfde breedte en hoogte. Alle ideeën uit de verticale stapellay-out zijn op dezelfde manier van toepassing.

Inhoud rechtvaardigen 

Als u de verdeling van kinderen binnen een container wilt regelen, gebruikt u de justifyContent eigendom op de container. 

Hieronder staan ​​de vijf mogelijke waarden die kunnen worden gebruikt met deze eigenschap. In de volgende voorbeelden is de hoogte van elk van de kinderen verminderd om aan te tonen hoe ze er uit zouden zien. U zou geen enkel verschil kunnen zien als het buigen waarde was 1 voor elk van de kinderen, omdat ze uiteindelijk alle beschikbare ruimte zouden opslokken.

  • flex-start: onderliggende elementen worden op het startpunt afgestemd. Let op de witte achtergrond direct onder het laatste kind. Dat is hoe je weet dat dit gebruikt flex-start omdat alle kinderen op het beginpunt zijn afgestemd. Dit laat een lege ruimte tegen het einde.
  • flex-end: onderliggende elementen worden uitgelijnd op de eindlijn. Merk op dat deze keer de lege ruimte bij het beginpunt is.
  • centrum: onderliggende elementen worden naar het midden geplaatst. Deze keer is de lege ruimte gelijk verdeeld tussen het begin- en eindpunt.
  • ruimte-around: onderliggende elementen worden zodanig verdeeld dat er rondom elk kind dezelfde ruimte is. Dit betekent dat de elementen aan de buitenkant minder ruimte hebben aan de buitenkant en dat de ruimte tussen de twee kinderen wordt verdubbeld.
  • ruimte tussen: onderliggende elementen worden zodanig verdeeld dat er een gelijke hoeveelheid ruimte tussen elk element is. 

Zoals je misschien hebt gemerkt, is elk van deze stijleigenschappen afhankelijk van de hoogte of breedte van de onderliggende elementen. Het is afhankelijk van de breedte als het flexDirection is rij, en op de hoogte als het flexDirection is kolom

Bijvoorbeeld, ruimte tussen heeft geen echt effect op een verticale stapelindeling als elk van de onderliggende elementen gebruikt buigen om de hoogte te regelen. Dit komt omdat er geen ruimte meer overblijft voor de kloof tussen elk kind-element om te consumeren. 

Items uitlijnen

Op het eerste gezicht, justifyContent en alignItems zou eruit kunnen zien alsof ze hetzelfde doen. Ze delen ook drie mogelijke waarden: flex-start, flex-end, en centrum, met de toevoeging van een uitrekken waarde. 

Het belangrijkste verschil tussen justifyContent en alignItems is de as waarop de kinderen worden verdeeld. Zoals je eerder hebt gezien, justifyContent gebruikt altijd de primaire as bij het distribueren van onderliggende elementen. Maar alignItems gebruikt de as tegenover de primaire as. 

We weten al dat de as wordt bepaald door de flexDirection dat is ingesteld. Dus als het flexDirection is rij, de primaire as stroomt van links naar rechts. Dit betekent dat de dwarsas van boven naar beneden zal vloeien. Aan de andere kant, als flexDirection is kolom dan zal de dwarsas van links naar rechts stromen.

Hieronder zijn enkele voorbeelden van justifyContent en alignItems naast elkaar geïmplementeerd flexDirection van rij. De eerste gebruikt justifyContent terwijl de tweede gebruikt alignItems.

  • flex-start: de positionering van de elementen is hetzelfde, vandaar de alignItems implementatie lijkt precies op justifyContent.
  • flex-end: nu beginnen we een verschil te zien. In eerste instantie is het aan het einde van de regel van de eerste rij, terwijl het tweede exemplaar zich aan de startlijn van de laatste rij bevindt. 
  • centrumcentrum heeft hetzelfde idee als de rest van de waarden die we tot nu toe hebben gebruikt. In eerste instantie zijn de items gecentreerd op de x-as terwijl in de tweede de items gecentreerd zijn op de y-as.


  • uitrekken: gebruik dit om de onderliggende elementen uit te rekken om de container te vullen. Dit is de standaardwaarde voor alignItems, dus het opgeven van deze waarde is optioneel. U hebt al gezien hoe dit werkt wanneer we verticale en horizontale stapellay-outs implementeerden.

Hier is de code die in bovenstaande voorbeelden wordt gebruikt. Speel gewoon met de waarden voor de flexDirection, justifyContent en alignItems als je wilt zien hoe ze eruitzien:

import Reageren, Component uit 'reageren'; importeer StyleSheet, View uit 'react-native'; standaardklasse exporteren AlignItems breidt component render () return (uit (             );  const styles = StyleSheet.create (wrapper: flex: 1, container: flex: .5, flexDirection: 'row', justifyContent: 'flex-start', // vervangen met flex-end of center borderBottomWidth : 1, borderBottomColor: '# 000', container2: flex: .5, flexDirection: 'row', alignItems: 'flex-start' // vervangen met flex-end of center, doos: width: 100, hoogte: 100, vak1: backgroundColor: '# 2196F3', box2: backgroundColor: '# 8BC34A', box3: backgroundColor: '# e3aa1a'); 

Als u de uitlijning van afzonderlijke elementen in een container wilt opgeven, kunt u de alignSelf eigendom. Alle mogelijke waarden voor uitlijnen-items zijn ook van toepassing op deze eigenschap. U kunt bijvoorbeeld een enkel element rechts van de container uitlijnen, terwijl de rest links uitgelijnd is.

Rasterlay-out

React Native komt niet echt met een grid lay-out systeem, maar Flexbox is flexibel genoeg om er een te maken. Door de dingen te gebruiken die we tot nu toe hebben geleerd, kunnen we gridlay-outs opnieuw maken met Flexbox. Hier is een voorbeeld:

En hier is de code die die lay-out maakt:

import Reageren, Component uit 'reageren'; importeer StyleSheet, View uit 'react-native'; Standaardklasse exporteren GridLayout verlengt component render () return (                              );  const styles = StyleSheet.create (row: flex: 1, flexDirection: 'row', justifyContent: 'space-between', marginBottom: 10, box: flex: 1, height: 100, backgroundColor: ' # 333 ',, box2: backgroundColor:' green ', box3: backgroundColor:' orange ', two: flex: 2);

Uit de bovenstaande code kunt u zien dat we emuleren wat ze gewoonlijk doen in CSS-rasterframeworks. Elke rij is verpakt in een aparte weergave en de rasteritems zitten erin. Een standaard buigen waarde van 1 wordt toegepast op elk item, zodat ze de beschikbare ruimte op elke rij gelijkelijk delen. Maar voor items die meer ruimte nodig hebben, een hogere buigen waarde wordt toegepast. Hiermee wordt de breedte van de andere items automatisch aangepast, zodat alle items kunnen worden geplaatst.

Als u spaties wilt toevoegen tussen elk item in een rij, kunt u een opvulling aan elk item toevoegen en vervolgens een vak in elke rij maken.

Dit resulteert in de volgende uitvoer:

Absolute lay-out

React Native ondersteunt alleen absoluut en familielid positionering. Dit zou u echter niet moeten beperken, omdat u deze altijd kunt combineren met Flexbox om de verschillende elementen overal te plaatsen waar u maar wilt.

Laten we kijken naar hoe we het volgende zouden bereiken:


We kunnen dit gemakkelijk bereiken als we de volledige controle hebben over de positioneringswaarden die beschikbaar zijn in de browser. Maar omdat we in React Native zijn, moeten we eerst de Flexbox-weg bedenken en vervolgens CSS-positionering gebruiken voor de kleine vakken.. 

Met Flexbox kan dit op twee manieren worden bereikt. Je kunt het gebruiken rij of kolom voor de flexDirection voor de hoofdcontainer. Hoe u de verschillende elementen rangschikt, hangt af van de methode die u kiest. Hier gaan we gebruiken rij voor de flexDirection dus het scherm zal in drie kolommen worden verdeeld. De eerste kolom bevat het oranje vak, de tweede kolom bevat de vakken zwart, grijs en groen en de derde kolom bevat de blauwe en kleine paarse vakken..

import Reageren, Component uit 'reageren'; importeer StyleSheet, View uit 'react-native'; export standaardklasse Positionering breidt component render () return (uit (                      ); 

Als je al weet hoe elk van de elementen zal worden uitgelegd, is het slechts een kwestie van toepassen van de dingen die we tot nu toe hebben geleerd. Het is immers niet nodig om CSS-positionering toe te passen op de grote dozen, alleen de kleine. 

De eerste kolom heeft alleen het oranje vak, dus van toepassing justifyContent: 'centrum' naar de container zou het lukken. Voor het geval je het al bent vergeten, flexDirection standaard ingesteld op kolom. Dit betekent dat als u instelt justifyContent naar centrum, de kinderen worden uitgelijnd op het midden van de Y-as. 

De tweede kolom heeft in principe hetzelfde idee als de eerste, maar we willen deze keer niet alle vakken op het midden uitlijnen. Wat we willen is dat ze gelijke ruimtes tussen elkaar hebben, en justifyContent: 'ruimte-tussen' maakt die klus gedaan. Maar tegelijkertijd willen we ook alle kinderen centreren op de X-as zodat we ze gebruiken alignItems: 'center'

Het enige lastige hier is dat je geen enkele moet toepassen breedte eigendom van de grijze doos, omdat we willen dat deze helemaal uitrekt om de volledige breedte van de bovenliggende lijn te consumeren. Omdat we geen toepassen breedte, we zouden moeten toepassen alignSelf: 'stretch' naar het grijze vak zodat het de volledige breedte van het bovenliggende element zal verbruiken. 

Vervolgens gebruiken we het kleine rode vak iets weg van zijn relatieve positie positie: relatief en pas dan toe top en links waarden omdat de relatieve positie zich in de linkerbovenhoek van het bovenliggende niveau bevindt. 

Wat betreft de kleine oranje doos die we gebruiken positie: 'absoluut' omdat we het moeten uitlijnen met de rechterbovenhoek van het bovenliggende element. Dit werkt omdat absoluut gepositioneerde elementen in React Native aan hun bovenliggend element zijn gebonden.

De derde kolom past in principe hetzelfde idee toe, dus ik ga het niet langer uitleggen.

const styles = StyleSheet.create (container: flex: 1, flexDirection: 'row', left: flex: 1, justifyContent: 'center', middle: flex: 5, justifyContent: 'space-between' , alignItems: 'center', rechts: flex: 1, justifyContent: 'center', alignItems: 'flex-end', vak: width: 100, height: 100, backgroundColor: '# 333', big_green_box : backgroundColor: 'green', big_orange_box: backgroundColor: 'orange', big_lightblue_box: backgroundColor: '# 03A9F4', big_gray_box: height: 100, alignSelf: 'stretch', backgroundColor: '#ccc' , inner_box: width: 20, height: 20,, red_box: position: 'relative', backgroundColor: 'red', top: 10, left: 10, orange_box: position: 'absolute', backgroundColor: ' orange ', top: 10, right: 10, purple_box: position:' absolute ', backgroundColor:' purple ', bottom: 10, right: 10, black_box: position:' relative ', backgroundColor:' black ' ); 

Laten we vervolgens proberen een vaste header- en voettekstlay-out te implementeren. Dit wordt vaak aangetroffen in apps met een tabbladnavigatie; de tabbladen zijn aan de onderkant van het scherm bevestigd, terwijl de hoofdinhoud kan worden gescrold. 

Om dit te bereiken, moeten we de ScrollView component zodat, als de hoofdinhoud de hoogte van de container overschrijdt, React Native automatisch een verticale schuifbalk genereert. Dit laat ons toe om toe te voegen marginTop en marginBottom naar de container met de hoofdinhoud, zodat de vaste kop- en voettekst de hoofdinhoud niet blokkeren. Merk ook op dat de links en rechts waarden van de koptekst en voettekst zijn ingesteld op 0 zodat ze de volledige apparaatbreedte consumeren. 

import Reageren, Component uit 'reageren'; importeer StyleSheet, View, ScrollView uit 'react native'; export standaardklasse FixedHeaderFooter breidt Component render () return uit (                );  const styles = StyleSheet.create (container: flex: 1, flexDirection: 'column', justifyContent: 'center', header: height: 40, position: 'absolute', left: 0, right: 0 , top: 0, backgroundColor: '# 03A9F4', zIndex: 10, content: alignItems: 'center', marginTop: 50, marginBottom: 40, footer: height: 40, position: 'absolute', left: 0, rechts: 0, onder: 0, backgroundColor: '# 8BC34A', vak: width: 100, height: 100, backgroundColor: '# 333', marginBottom: 10); 

Zo ziet het eruit:

Bibliotheken van derden

React Native heeft een grote gemeenschap achter de rug, dus het is niet verwonderlijk dat er al een paar bibliotheken zijn gemaakt om de implementatie van lay-outs te vergemakkelijken. In deze sectie zal ik je voorstellen aan een bibliotheek genaamd React Native Easy Grid. U kunt het gebruiken om te beschrijven hoe u uw app wilt indelen door gebruik te maken van de rooster, Rij, en Col componenten.

U kunt het met de volgende opdracht installeren: 

npm install react-native-easy-grid - opslaan

Importeer de bibliotheek en extraheer de verschillende componenten in uw bestand.

import Reageren, Component uit 'reageren'; importeer StyleSheet, View uit 'react-native'; importeer Col, Row, Grid uit "react-native-easy-grid";

De rooster component wordt gebruikt voor het inpakken van alles. Col wordt gebruikt om een ​​kolom te maken, en Rij wordt gebruikt om rijen te maken. U kunt een grootte eigendom voor beide Rij en Col, hoewel we het alleen op de Rij hieronder. Als de grootte niet is opgegeven, wordt de beschikbare ruimte gelijk verdeeld tussen de Col instanties. 

In dit geval zijn er slechts twee, dus het hele scherm is verdeeld in twee kolommen. De eerste kolom wordt dan verdeeld in twee rijen. Hier hebben we een opgegeven grootte, maar je kunt het eigenlijk overslaan als je alleen even grote rijen nodig hebt, zoals we hieronder deden.

export standaardklasse FlexboxGridLibrary verlengt Component render () return (        ); 

Zodra dat is gebeurd, hoeft u alleen de stijl voor de rijen en kolommen toe te voegen:

const styles = StyleSheet.create (orange_box: backgroundColor: 'orange', green_box: backgroundColor: 'green', gray_box: backgroundColor: 'gray');

Zoals je gemerkt hebt, heeft React Native Easy Grid een zeer intuïtieve API. 

Conclusie

In deze zelfstudie leer je hoe je React Native-apps kunt indelen. Concreet heb je geleerd hoe je React Native's Flexbox kunt gebruiken om dingen rond te positioneren. Je hebt ook geleerd hoe je React Native Easy Grid kunt gebruiken, waardoor de implementatie van Flexbox eenvoudiger wordt. 

.