React Native ile Mobil Uygulama Geliştirme – 4 – React Native UI Components

“React Native ile Mobil Uygulama Geliştirme” başlıklı makalelerimizden bir yenisini daha sizlerle paylaşmak istiyorum. Bu makale, bir dizi makaleden oluşacak olan serisinin 4. kısmıdır. Bir önceki makalede (Part 3), React Native’de Stillendirme ve Flex kullanımını örnekleyerek, elementleri boyutlandırma, renklendirme vb. değişiklikler yaparak nasıl özelleştireceğimizi anlattım.

Bu makalede, React Native ‘in en temel yapı taşı olan UI Components (Kullanıcı Arayüzü Bileşenleri) ‘ni anlatacağım. Component dediğimiz şey Türkçe’ye çevirdiğimizde bileşen anlamına geliyor. Sizin uygulamalarınızda işi yerine getiren, yapan her birime birer komponent denir aslında. Amaç bir kere yazalım o komponent’i her yerde kullanalım mantığı vardır. Bir React Native projesinde farklı tipteki UI öğelerini kullanabiliriz. Ancak bir android ve iPhone’da farklı görünebileceğini unutmayın. Text inputs, touchables ve picker’ların farklı örneklerle nasıl yapıldığını öğreneceğiz.

Daha önceki makaleleri okumadıysanız, lütfen buradan başlayın.

Text Inputs:

TextInput bileşeni, kullanıcı metin girişlerini almak için kullanılır. Metin girişleriyle kullanılabilecek aksesuarlar aşağıdadır:

placeholder : Bu placeholder metnidir, yani boş bir TextInput’ta gösterilecek metindir.

value: TextInput onChangeText içine yerleştirilecek değer: Bir işlev alır ve bu her metin değişikliğinde çağrılacaktır.

onSubmitEditing: Bir işlev alır ve metin gönderildikten sonra çağrılacaktır.

Aşağıdaki örneğe bakalım:

import React, { Component } from 'react';
import { Text, View, Button,TextInput } from 'react-native';
export default class MainComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {text: ''};
  }
  render() {
    return (
       <View style={{paddingTop: 100, paddingLeft : 100}}>
        <TextInput
          style={{height: 40}}
          placeholder="Enter a text"
          onChangeText={(text) => this.setState({text})}
          value={this.state.text}
        />
        <Text style={{padding: 10, fontSize: 42}}>
          {this.state.text}
        </Text>
      </View>
    );
  }
}

TextInput öğesine herhangi bir metin yazarsanız, metin içinde aynı metni gösterir. “placeholder” desteği yer tutucuyu koymak için kullanılır. Kullanıcı yazmaya başladığında bu kaldırılır. OnChangeText props bir işlevi alır ve geçerli ‘props‘ metin ’değerini değiştirir. “value” props, metni TextInput öğesine koymak için kullanılır. ‘TextInput’un‘ değerini ’doğrudan değiştirmiyoruz. “state” deki “metin” değerini değiştirir ve “metin” değer olarak atanır. Alttaki “Metin”, kullanıcının yazdığı metnin aynısını koymak için kullanılır.

TextInput’ta özelleştirme için başka birçok sahne var. Bu resmi kılavuzu kontrol ederek daha fazla bilgi edinebilirsiniz.

 

Touch Handling:

Tüm mobil uygulamalar esas olarak parmak dokunuşu kullanılarak işlenir. Bu dokunma hareketleri, dokunma, kaydırma, kıstırma vb. gibi farklı tiplerde olabilir. React Native, farklı hareketleri işlemek için bir hareket yanıtlama sistemi sağlar. Hemen hemen tüm React Native bileşeni kullanıcı parmak dokunuşunu algılayabilir, ancak yalnızca dokunma olayıyla ilgili olan bir bileşene “Touchables” adı verilir. Bu bileşeni kullanarak, farklı tasarıma sahip kendi özel düğmelerimizi oluşturabiliriz. Ayrıca, tek basış ve uzun basış olaylarını tespit etmek için iki farklı props sunar. Sağlayabileceği geri bildirim türleri şunlardır:

TouchableHighlight :

Bu, bir button veya web bağlantısı ile kullanılabilir. Kullanıcı öğeye bastığında görünüm kararır.

TouchableNativeFeedback :

Bu Android’de dalgalanma etkisi gösterecektir. TouchableNativeFeedback, iOS’ta desteklenmez.

TouchableOpacity :

Bu, kullanıcı bastığında buttonun opaklığını azaltır.

TouchableWithoutFeedback :

Dokunulduğunda kullanıcıya herhangi bir geri bildirim göstermek istemiyorsanız kullanın.

Bu türler dışında, tek basış ve uzun basışları tespit etmek için ‘onPress’ ve ‘onLongPress’ aksesuarlarını kullanabiliriz. Bu iki sahne de bir ‘function’ gerektirir.

import React, { Component } from 'react';
import { Text, View, Button,TextInput,TouchableHighlight, StyleSheet } from 'react-native';
export default class MainComponent extends Component {
  onButtonPressed() {
    alert('Button pressed!')
  }
  onButtonLongPressed() {
    alert('Button Long pressed!')
  }
  render() {
    return (
       <View style={{paddingTop: 100, alignItems: 'center'}}>
        <TouchableHighlight onPress={this.onButtonPressed} onLongPress={this.onButtonLongPressed}>
          <View style={styles.button}>
            <Text style={styles.buttonText}>Touch it</Text>
          </View>
        </TouchableHighlight>
      </View>
    );
  }

}
const styles = StyleSheet.create({
  button: {
    width: 260,
    height: 50,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'blue',
    borderRadius: 5
  },
  buttonText: {
    color : "white"
  }
});

Burada da görebileceğiniz gibi, TouchableHighlight bileşenindeki tek basış ve uzun basışları tespit etmek için ‘onPress’ ve ‘onLongPress’ desteklerini kullanıyoruz.

Picker:

Picker, kullanıcıdan bir değer listesinden seçim yapmasını istemek için kullanılır. Picker bileşen hem Android hem de iOS’ta kullanılabilir. İşlevsellik hem Android hem de iOS’ta aynıdır, ancak görünüm farklıdır. Aslında yerel Android ve iOS seçicileri kullanıyor ve her ikisi de farklı görünüyor. Seçilen değeri gösterir ve üzerine tıkladığımızda, android’de bir açılır pencerede mevcut değerlerin bir listesini gösterir. İOS’ta, mevcut tüm seçeneklerle birlikte bir kaydırılabilir tekerlek gösterir. Seçici bileşenini, diğer bileşenler gibi ‘react-native’ öğesinden içe aktarabiliriz. Örneğin :

import React, { Component } from 'react';
import { View, Text, Picker, StyleSheet } from 'react-native'
class MainComponent extends Component {
   state = {day: ''}
   changePickerValue = (d) => {
      this.setState({ day: d })
      alert(`selected ${d}`)
   }
   render() {
      return (
         <View style={{paddingTop: 100}}>
            <Picker selectedValue = {this.state.day} onValueChange={(value, index) =>
    this.changePickerValue(value)
  }>
               <Picker.Item label = "Sun" value = "Sun" />
               <Picker.Item label = "Mon" value = "Mon" />
               <Picker.Item label = "Tues" value = "Tues" />
               <Picker.Item label = "Wed" value = "Wed" />
               <Picker.Item label = "Thurs" value = "Thurs" />
               <Picker.Item label = "Fri" value = "Fri" />
               <Picker.Item label = "Sat" value = "Sat" />
            </Picker>
         </View>
      )
   }
}
export default MainComponent

Bu kodu çalıştırırsanız, bir Android telefonda aşağıdaki gibi görünecektir:

Picker listesinde gösterilecek ‘Picker’ bileşeninin içine ‘Picker’ öğesi olarak bir öğe listesi eklememiz gerekir. Picker’da çok sayıda farklı props vardır. Bunlardan birkaçı aşağıdaki gibidir:

1. onValueChange :

Seçiciden bir öğe seçildiğinde bir geri arama verir. Seçilen öğenin değerini ve o öğenin dizinini verir. Dizin önemlidir, gerekirse dizini kullanarak farklı bir harita listesinden seçim yapabiliriz.

2. selectedValue :

Seçici öğe değerleri listelerinden biriyle eşleşmesi gereken seçilen değer.

3. enabled :

Değeri ‘false’ olarak ayarlarsak seçiciyi devre dışı bırakır.

4. mode :

Bu seçenek yalnızca Android için kullanılabilir. “dialog” veya “dropdown” olabilir. “dialog” kalıcı bir iletişim kutusu gösterir, bu varsayılan seçenektir. “dropdown” bir açılır liste görüntüler.

5. style and itemstyle :

stil “pickerStyleType” türünde olmalıdır. “picker” ye bir “style” eklemek için kullanılır. “itemStyle”, öğe etiketlerinin her birine stil uygulamak için kullanılır.

Şimdiye kadar, çoğu uygulama için gereken en yaygın kullanılan React Native UI Bileşenlerini gördük. Lütfen görüşlerinizi ve bununla ilgili sorularınızı bize bildirin.

Kaynak: https://www.opencodez.com/

Android’de Directions API ile Rota Çizme

Günümüzde konum bilgisi kullanarak hayatımızı birçok alanda kolaylaştırması sağlayan yazılımlar bulunmaktadır. Mobil uygulamalarda GPS, araba kullanırken ya da yaya olarak yürürken, ulaşmak istediğimiz noktaya gidebilmek için yol tarifi yapması, bulunduğunuz konum çevresinde en yakın eczaneye ulaşmak gibi birçok konuda hayatımızı kolaylaştırmaktadır.

Bu makalemde, bir Android uygulamasında Google Directions API ‘yi kullanarak haritada belirlenen iki nokta arasında nasıl bir rota çizileceğini ve bu rotaya ne kadar sürede varılacağını göstereceğim.

Örnek projemizi kodlamaya başlamadan önce bazı işlemler yapmamız gerekmektedir.Bu işlemleri sırayla yapmaya başlayalım.

1- Google Play Services Yükleme

Google haritayla ilgili bir geliştirme yapacağımızdan dolayı, Google Play Services yüklememiz gerekmektedir. Bunun için Tools->Sdk manager’ı açıp Sdk Tools bölümünden Google Play Services işaretleyip, yükleme işlemini gerçekleştirin.

2- Google Maps API Key Oluşturma

3-Gerekli Kütüphanelerin Eklenmesi

Android Studio Ide ile oluşturduğum projemin app dizinin altındaki build.gradle dosyasını açıyoruz. Dependencies kod bloklarının arasına aşağıdaki kodları yerleştirerek Google Play services kütüphanesini yüklüyoruz.

implementation 'com.google.android.gms:play-services-maps:17.0.0'

4-AndroidManifest Dosyasına İlgili Ayarları Ekleme

Kullanıcının konumu belirlemek için izin tanımlamamız gerekir. Aşağıdaki izin kodunu da AndroidManifest.xml dosyasında application tag’nin üst kısmına yerleştirin.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

AndroidManifest dosyasına, daha önce üretmiş olduğumuz Google API Key’i ekleme işlemini yapacağız. Application tag arasına aşağıda görmüş olduğunuz meta-data tag kodunun içindeki value özelliğine Google API Key’i ekleyeniz.

<meta-data android:name="com.google.android.geo.API_KEY"
   android:value="AIzaSyBconZdqpSflHNcs6t-btfk0Rlo1Lex7wo" />

5-Xml Kodları

Haritayı gösterebilmek için SupportMapFragment sınıfını fragment ile kullanıyoruz.

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

4-Java Kodları

İlgili rotayı çizebilmek için ilk önce Google Map Directions web servisine API Key, başlangıç ve varış noktalarının konum bilgilerini bir url ile göndermeniz gerekir. İlgili url ile web servise bağlandığınızda, rotayı ne kadar sürede bitirebileceğiniz, rotanın kaç km olduğu, yol tarifleri hakkında detaylı bilgiler json verisi halinde gelecektir. Bu kısmı ve rotanın harita çizilmesi MainActivity sınıfında yapılmıştır. Detaylı anlatım kodlarda bulunmaktadır.

import androidx.fragment.app.FragmentActivity;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.*;
import android.preference.PreferenceManager;
import android.widget.Toast;
import com.google.android.gms.maps.*;
import com.google.android.gms.maps.model.*;
import org.json.JSONObject;
import java.io.*;
import java.net.*;
import java.util.*;

public class MainActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private LatLng mOrigin;
    private LatLng mDestination;
    private Polyline mPolyline;
    ArrayList<LatLng> mMarkerPoints;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // SupportMapFragment ile haritayı yükleyeceğimiz arayüz elemanını tanımlıyoruz
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);

        mapFragment.getMapAsync(this);

        mMarkerPoints = new ArrayList<>();
    }
    //Harita üzerinde yolun başlangıç ve bitiş noktasını imleçler ile işaretleyerek seçme
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng point) {
                // Her lokasyon yolunu çizme işleminden sonra yeni yol çizimi için harita refresh yapılıyor
                if(mMarkerPoints.size()>1){
                    mMarkerPoints.clear();
                    mMap.clear();
                }
                mMarkerPoints.add(point);

                //İmleçleri oluşturan sınıfı tanımladık
                MarkerOptions options = new MarkerOptions();
                //İmleci, haritada belirtilen noktalara eklenmesi için ilgili yerin değerini atadık
                options.position(point);
                //DirectionsJSONParser sınıfında, yol süresi değerini SharedPreferences ile taşıyıp
                // imleçde gösterdik
                SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
                options.title("Duration: " +preferences.getString("duration", null));

                /**
                 * İmleçlerin görsellerini belirleme, Başlangıç imlecini yeşil
                 * lokasyonu bitişini belirten imleç ise kırmızı olarak belirledim
                 */
                if(mMarkerPoints.size()==1){
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                }else if(mMarkerPoints.size()==2){
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                }

                // Haritada marker(imleç) ekleniyor
                mMap.addMarker(options);

                // Google Directions web servis urlsini hazırlayan ve web servisi kullanan metodu çağırdık
                if(mMarkerPoints.size() >= 2){
                    mOrigin = mMarkerPoints.get(0);
                    mDestination = mMarkerPoints.get(1);
                    drawRoute();
                }

            }
        });
    }
    // Google Directions API den konum datalarını kullanabilmek için web servis ile
    //bağlantı kuracağımız url hazırlayan metodu çağırdık ve web servisi çalıştırdık
    private void drawRoute(){
        String url = getDirectionsUrl(mOrigin, mDestination);

        DownloadTask downloadTask = new DownloadTask();
        downloadTask.execute(url);
    }

    //Haritada belirttiğiniz başlangeç ve bitiş imleçlerinin koordinatlarını API Key ile kullanarak
    //çizilecek düzergah ile ilgili bilgileri elde etmek adına url olusturan metod
    private String getDirectionsUrl(LatLng origin,LatLng dest){

        String str_origin = "origin="+origin.latitude+","+origin.longitude;
        String str_dest = "destination="+dest.latitude+","+dest.longitude;

        // API Key parametre olarak hazırlama
        String key = "key=" +"AIzaSyBconZdqpSflHNcs6t-btfk0Rlo1Lex7wo";

        String parameters = str_origin+"&"+str_dest+"&"+key;
        String output = "json";

        // Oluşturduğumuz parametreleri kullanarak url yi oluşturuyoruz
        String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
        return url;
    }

    private String downloadUrl(String strUrl) throws IOException {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try{
            // Hazırladığımız url yi kullanarak web servise Http bağlantısı ile sağlıyoruz
            URL url = new URL(strUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();

            // webservisden gelen json datayı okuyup, data değişkenine atadık
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
            StringBuffer sb  = new StringBuffer();
            String line = "";
            while( ( line = br.readLine())  != null){
                sb.append(line);
            }
            //json veriyi data değişkenine atadıkve metodda return yaptık
            data = sb.toString();
            br.close();

        }catch(Exception e){
            //Log.d("Exception on download", e.toString());
        }finally{
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }

    /** Bu sınıf da, Google Directions URL kullanarak, rotanın kaç km. olduğu, ne kadar sürede gidilebildiği
     * gibi bilgileri barındıran json datayı çektik */
    private class DownloadTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... url) {
            String data = "";
            try{
                data = downloadUrl(url[0]);

            }catch(Exception e){
                //Log.d("Background Task",e.toString());
            }
            return data;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            //Google Directions bilgisini, JSON formatını parse ederek almayı sağlayan sınıf
            ParserTask parserTask = new ParserTask();
            parserTask.execute(result);
        }
    }

    /** Bu sınıf Google Directions bilgisini, JSON formatını parse ederek almayı sağlar  */
    private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
        @Override
        protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
            JSONObject jObject;
            List<List<HashMap<String, String>>> routes = null;

            try{
                jObject = new JSONObject(jsonData[0]);
                //DirectionsJSONParser sınıfında tüm json çözümlenir.
                DirectionsJSONParser parser = new DirectionsJSONParser();
                routes = parser.parse(jObject,MainActivity.this);
            }catch(Exception e){
                e.printStackTrace();
            }
            return routes;
        }

        // Json çözümlendikten sonra, harita üzerinde rotayı(path) çizmeyi sağlayan metod
        @Override
        protected void onPostExecute(List<List<HashMap<String, String>>> result) {
            ArrayList<LatLng> points = null;
            PolylineOptions lineOptions = null;

            for(int i=0;i<result.size();i++){
                points = new ArrayList<LatLng>();
                lineOptions = new PolylineOptions();

                List<HashMap<String, String>> path = result.get(i);

                for(int j=0;j<path.size();j++){
                    HashMap<String,String> point = path.get(j);

                    double lat = Double.parseDouble(point.get("lat"));
                    double lng = Double.parseDouble(point.get("lng"));
                    LatLng position = new LatLng(lat, lng);
                    points.add(position);
                }

                //PolylineOptions ile rota üzerinde noktalar ekleyerek, çizginin rengini ve genişliğini belirleme
                lineOptions.addAll(points);
                lineOptions.width(8);
                lineOptions.color(Color.RED);
            }

            if(lineOptions != null) {
                if(mPolyline != null){
                    mPolyline.remove();
                }
                mPolyline = mMap.addPolyline(lineOptions);

            }else
                Toast.makeText(getApplicationContext(),"Rota bulanamadı", Toast.LENGTH_LONG).show();
        }
    }

}

DirectionsJSONParser sınıfında ise web servisden gelen Json veriyi çözümleyip, içindeki bilgileri ArrayList yapısına ekleyerek MainActivity sınıfında kullanılması sağlanmıştır. Ek olarak DirectionsJSONParser sınıfında Json veriden gelen polyline değerini (rota yolunun şifrelenmiş çizgileri) çözümleyen bir metod yazılmıştır. Bu metod sayesinde  rota yolunun çizilebilmesi için gerekli enlem, boylam değerleri elde edilir. Detaylı anlatım kodlarda bulunmaktadır.

import android.content.*;
import android.preference.PreferenceManager;
import com.google.android.gms.maps.model.LatLng;
import org.json.*;
import java.util.*;
public class DirectionsJSONParser {
    /** Google Directions URL kullanarak web servisden elde edilen JSONObject çözümlenerek,
     rotayı ne kadar sürede bitirebileceğiniz, rotanın kaç km olduğu, yol tarifleri hakkında detaylı bilgiler elde edilir   */
    public List<List<HashMap<String,String>>> parse(JSONObject jObject, Context context){

        List<List<HashMap<String, String>>> routes = new ArrayList<>() ;
        JSONArray jRoutes = null;
        JSONArray jLegs = null;
        JSONArray jSteps = null;

        try {
            jRoutes = jObject.getJSONArray("routes");

            for(int i=0;i<jRoutes.length();i++){
                jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");

                JSONObject c = jLegs.getJSONObject(i);
                JSONObject vo = c.getJSONObject("duration");
                //Rotaya varış süresini, SharedPreferences nesnesine atadım. Haritada gösterimi, MainActivity sınıfında.
                SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
                SharedPreferences.Editor editor = prefs.edit();
                editor.putString("duration", vo.getString("text"));
                editor.commit();

                List path = new ArrayList<HashMap<String, String>>();
                for(int j=0;j<jLegs.length();j++){
                    jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
                    for(int k=0;k<jSteps.length();k++){
                     //Polyline çözümleyerek, rota noktalarının enlem, boylam bilgisi alma
                        String polyline = "";
                        polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
                        List<LatLng> list = decodePoly(polyline);

                        for(int l=0;l<list.size();l++){
                            HashMap<String, String> hm = new HashMap<String, String>();
                            hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
                            hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
                            path.add(hm);
                        }
                    }
                    routes.add(path);
                }
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }catch (Exception e){
        }
        return routes;
    }

    /**
     * Polyline (rota yolunun şifrelenmiş çizgileri) çözümleyerek, rota noktalarının enlem, boylam bilgisini döner
     */
    private List<LatLng> decodePoly(String encoded) {

        List<LatLng> poly = new ArrayList<LatLng>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            LatLng p = new LatLng((((double) lat / 1E5)),
                    (((double) lng / 1E5)));
            poly.add(p);
        }
        return poly;
    }
}

Örneklediğim projemin kodlarını indirmek isterseniz; yapmanız gereken tek şey aşağıya koyduğum KODLARI İNDİR resmine tıklamak.

React Native ile Mobil Uygulama Geliştirme – 3 – Stillendirme ve Flex Kullanımı

“React Native ile Mobil Uygulama Geliştirme” başlıklı makalelerimizden bir yenisini daha sizlerle paylaşmak istiyorum. Bu makale, bir dizi makaleden oluşacak olan serisinin 3. kısmıdır. Bir önceki makalede (Part 2), React Native ile cross-platform mobil uygulama geliştirmek için bilmeniz gereken State ve Props kavramlarından bahsettim.

Bu makalede, React Native’de Stillendirme ve Flex kullanımını örnekleyerek, elementleri boyutlandırma, renklendirme vb. değişiklikler yaparak nasıl özelleştireceğimizi anlatacağım.

Stil, uygulama geliştirmenin önemli parçalarından biridir. Native Android Uygulama geliştirme için XML, kullanıcı arayüzünü tasarlamak için kullanılır. Benzer şekilde, Native iOS Uygulama geliştirme için XCode gereklidir. Ancak React Native’de, hem Android hem de iOS’ta çalışan uygulamayı biçimlendirmek için yalnızca JavaScript kullanıyoruz. Reaksiyona özgü UI bileşenlerinin yerleşimini belirtmek için flexbox kullanılır. Bu makalede, React Native’de stil eklemeyi ve flexbox’ı nasıl kullanacağımızı öğreneceğiz.

Daha önceki makaleleri okumadıysanız, lütfen buradan başlayın

Biçimlendirme:

React Native’de stil için CSS’yi kullanamayız. Bunun yerine, stil öğeleri eklemek için JavaScript kullanılır. Her kullanıcı arabirimi öğesi, kendisine uygulanan bir stil ‘props’ alır. CSS’den farklı olarak, adlandırma kuralı camel case (büyük küçük harf) kullanır, örn. bir öğenin arka plan rengini eklemek için “arka plan rengi” yerine “backgroundColor” kullanacağız.

Örneğin, aşağıdaki gibi bir kalın metin oluşturabiliriz:

<Text style={{fontWeight: 'bold'}}>Hello</Text>

Her bileşen farklı türde stil props alır. Geçersiz bir stil’den geçersek yok sayılır.

Stylesheet Kullanma:

Her UI bileşeni için stil props’u eklenmesi, kodu düzenlenmemiş ve dağınık hale getirecektir. Ayrıca, bu şekilde, stili birden fazla kullanıcı arayüzü öğesiyle paylaşamayız. React-Native, farklı kullanıcı arayüzü öğeleri arasında paylaşılabilen bir ortak stil deseni oluşturmak için başka bir yol sağlar. Ortak bir stil sayfası oluşturmak için aşağıda gösterildiği gibi StyleSheet.create yöntemini kullanın:

import React, Component } from 'react';
import StyleSheet, Text, View, Button from react-native
const styles= StyleSheet.create({
title: {
color: blue'
fontWeight:
fontSize: 30,
},
description: {
color: "#841584"
},
});

export default class StyleClass extends Component
render()
return (
<V1ew>
<Text style={styles.title}>This is a heading</Text>
<Text style={styles.description}> This 1s a description with different style</Text>
</View>
);
}
}

Bu örnekte, ‘Metin’ öğeleri içeren ‘StyleClass’ adlı bir bileşenimiz var. Her iki “Text” öğesi iki farklı stil kullanıyor. ‘StyleSheet.create’ öğesini kullanarak bileşeni dışa aktarmadan önce stili tanımlıyoruz. İki farklı stilin oluşturulduğunu görebilirsiniz: “title” ve “description” ve bu stilleri eklemek için “{styles.stylename}” kullanıyoruz. Bu yaklaşımın ana avantajı, kodun daha temiz hale gelmesi ve birden fazla UI bileşeninde bir stil kullanabilmemizdir.

Sabit boyut için yükseklik ve genişlik ekleme:

React-native’de, bir UI öğesi için sabit genişlik ve yükseklik ekleyebiliriz. Sabit yükseklik / genişlik ayarlarsak, tüm boyutlu cihazlar için aynı boyutta oluşturulurlar. ‘Stil’ bölümünde ‘genişlik’ ve yüksekliği aşağıdaki gibi kullanabilirsiniz:

<View style={{width: 150, height: 150, backgroundColor: 'powderblue'}} />

Bu boyutlar birimsizdir ve yoğunluktan bağımsız pikselleri temsil eder.

Ancak bu iyi bir uygulama değildir, çünkü bir görünümün veya başka bir UI öğesinin ekranın yarısını doldurmasını istiyorsak ve sabit boyut kullanırsak, telefonlar ve tabletler gibi farklı cihazlarda farklı olacaktır. Bunun için “flexbox” adı verilen başka bir mekanizma kullanılır. Nasıl çalıştığını kontrol edelim:

Flexbox :

Flex, bir görünüme dinamik boyut vermek için kullanılır. Flex değerine 1 verirseniz, tam ekran alanı kaplar. Ebeveyn görüşüne ‘flex = 1’ verebilir ve alt görüşlerine farklı esnek değerler verebiliriz. Örnek,

<View style={{flex: 1}}>
<View style={{flex: 0.2, backgroundColor: 'red'}} />
<View style={{flex: 0.2, backgroundColor: 'blue'}} />
<View style={{flex: 0.2, backgroundColor: 'black'}} />
<View style={{flex: 0.2, backgroundColor: 'orange'}} />
<View style={{flex: 0.2, backgroundColor: 'green'}} />
</View>

Burada, çıktı aşağıdaki gibi görünecektir:

Gördüğünüz gibi iç görünümler eşit olarak bölünmüş durumda. İç görünümlere aynı değerde farklı bir değer verirsek, aynı çıktıyı üretecektir. Daha büyük bükülme değeri kardeşlerine göre daha yüksek boşluk oranı sağlayacaktır. Bir görünümün 0’dan büyük bir değere sahip esnekliğe sahip olması veya sabit bir yükseklik / genişliğe sahip olması gerektiğini, aksi takdirde alt görünümlerin görünmeyeceğini unutmayın. Flexbox, farklı ekranlarda tutarlı düzen boyutu sağlamak için kullanılır.

Flexbox’ın ana kavramları şunlardır:

  1. flexDirection
  2. alignItems
  3. justifyContent

flexDirection:

flexDirection, child görünümlerinin hangi yönde yerleştirileceğini tanımlamak için kullanılır. Ana flexDirection türleri şunlardır:

row: Tüm öğeleri soldan sağa hizalayın.
column: Tüm öğeleri yukarıdan aşağıya hizalayın. Bu varsayılan değerdir.
row-reverse : Satırın tersi. Tüm öğeleri sağdan sola hizala
column-reverse i: Sütunun tersi. Tüm öğeleri aşağıdan yukarıya hizalayın.

Örnek :

import React, Component} from 'react";
import Text, View, Button } from 'react-native'
export default class MainComponent extends Component{
render(){
return(
<View style={{flexDirection: "row",flex : 1}}>
 <View style-{{flex: 2, backgroundColor: 'red'}} />
 <View style-{{flex: 2, backgroundColor: 'blue'}} />
 <View style-{{flex: 2, backgroundColor: 'black'}} />
 <View style-{{flex: 2, backgroundColor: 'orange'}} />
 <View style-{{flex: 2, backgroundColor: 'green'}} />
</View>
);
 }
}

Aşağıdaki çıktıyı üretecektir:

 

justifyContent:

Geliştirme sırasında bunu, eksenindeki alt görünümlerin nasıl hizalandığını tanımlamak için kullanabilirsiniz. Ana türleri şunlardır:

flex-start: Bu varsayılan değerdir. Tüm içeriği ana eksenin başlangıcına hizalar.

flex-end: İçeriği eksenin sonuna hizalayın.

center: İçeriği eksenin merkezine hizalayın.

space-between : childlar arasındaki kalan alanı dağıtarak tüm childları eksen boyunca eşit aralıklarla yerleştirin.

space-around: childlara eşit boşluk bırakarak eşit boşluk alan childlar.

Örnek :

import React, { Component } from 'react';
import { Text, View, Button } from 'react-native';
export default class MainComponent extends Component {
  render() {
    return (
      <View style={{flexDirection: "column",flex : 1,justifyContent: 'space-between'}}>
        <View style={{flex: .2, backgroundColor: 'red'}} />
        <View style={{flex: .2, backgroundColor: 'blue'}} />
        <View style={{flex: .2, backgroundColor: 'green'}} />
      </View>
    );
  }
}

Aşağıdaki çıktıyı üretecektir:

alignItems:

Bu, öğeleri çapraz eksen boyunca hizalamak için kullanılır. Ana ekseni hizalamak için justifyContent kullanılabilir. Öğeleri çapraz eksen boyunca hizalar. Türleri şunlardır:

stretch: childi çapraz eksenin yüksekliğine uyacak şekilde uzatın.

flex-start: chidları çapraz eksenin başlangıcına hizalayın.

flex-end: Yukarıdaki ile aynıdır, ancak uçlara hizalanır.

center: Merkeze hizalayın.

baseline : Ortak bir taban çizgisi boyunca hizalayın.

Örnek :

import React, { Component } from 'react';
import { Text, View, Button } from 'react-native';
export default class MainComponent extends Component {
  render() {
    return (
      <View style={{flexDirection: "column",flex : 1,justifyContent: 'center', alignItems: 'center'}}>
        <View style={{width: 50, height: 50, backgroundColor: 'red'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'blue'}} />
        <View style={{width: 50, height: 50, backgroundColor: 'green'}} />
      </View>
    );
  }
}

Tek bir öğenin alignItems öğelerini geçersiz kılmak için ‘alignSelf’ özelliğini de kullanabilirsiniz.

flexWrap alignContent :

Ekranın boyutu taşarsa, öğeleri kontrol etmek için flexWrap kullanabilirsiniz. ‘nowrap’ ve ‘wrap’ olmak üzere iki değeri vardır. Örnek :

import React, { Component } from 'react';
import { Text, View, Button } from 'react-native';
export default class MainComponent extends Component {
  render() {
    return (
      <View style={{flexDirection: "column",flexWrap: "wrap",flex : 1}}>
        <View style={{width: 50, height: 250, backgroundColor: 'red'}} />
        <View style={{width: 50, height: 250, backgroundColor: 'blue'}} />
        <View style={{width: 50, height: 350, backgroundColor: 'green'}} />
      </View>
    );
  }
}

Burada görebileceğiniz gibi, son görünüm sağa yerleştirilir, çünkü ikinci görünümün altına yerleştirirsek ekranı geçecektir.

‘FlexWrap’i kullanarak sarmaladıysanız, öğeleri hizalamak için alignContent kullanabilirsiniz. 6 değeri vardır: ‘flex-start’, ‘flex-end’, ‘stretch’, ‘center’, ‘space-between’, ‘space-around’.

Flexbox kavramı CSS’deki ile aynıdır. Tek fark, flexDirection’ın varsayılan olarak “column” olmasıdır ve flex parametreleri yalnızca tek bir sayıyı destekler.

Sonuç:
Makale, React Native App’te Styling’i nasıl gerçekleştirebileceğiniz konusunda kısa bir giriş yapmıştır. Makaleyi herhangi bir noktayı içerecek şekilde güncellememiz gerekiyorsa lütfen okuyun ve bize bildirin.

Kaynak: https://www.opencodez.com/