Code Examples
Supernova produces clean, valid code for Flutter, iOS, Android and React Native. However, we know just how bold this claim is! Since we are very proud of the quality the code Supernova produces, here are some examples of how the code actually looks like! If you are interested in a specific platform, select one of the following: Flutter, iOS, Android, React Native. If you want to see a full example of what Supernova is capable of, we've published some on our GitHub page.


This is the screen used in the following examples.
It contains navigation bar, map, some overlays and informational view at the bottom
Flutter Example
In the following example, you'll find a code required to build the screen in Flutter using Dart. The layout is calculated from Starlight rules to pure Flexbox definitions. You can use both Cupertino and material UI kits (material is exported by default).
Supernova currently doesn't support custom widgets, but as the code quality would benefit greatly from it, but we are working on the full support.
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class EventDetailWidget extends StatelessWidget {
void onGroupPressed(BuildContext context) => Navigator.pop(context);
void onLeftItemPressed(BuildContext context) {
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
"Guess who's back?",
style: TextStyle(
color: Color.fromARGB(255, 255, 255, 255),
fontSize: 17,
fontFamily: "Lato",
),
),
leading: IconButton(
onPressed: () => this.onGroupPressed(context),
icon: Image.asset("assets/images/group-2.png",),
),
actions: [
FlatButton(
onPressed: () => this.onLeftItemPressed(context),
textColor: Color.fromARGB(255, 255, 255, 255),
child: Text(
"Events",
style: TextStyle(
color: Color.fromARGB(255, 0, 0, 0),
fontSize: 12,
fontFamily: "",
),
textAlign: TextAlign.left,
),
),
],
flexibleSpace: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment(-0.014, 0.515),
end: Alignment(1.014, 0.485),
stops: [
0,
1,
],
colors: [
Color.fromARGB(255, 248, 132, 98),
Color.fromARGB(255, 140, 28, 140),
],
),
),
),
),
body: Container(
constraints: BoxConstraints.expand(),
decoration: BoxDecoration(
color: Color.fromARGB(255, 244, 242, 244),
),
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
left: 0,
top: 0,
right: 0,
bottom: 0,
child: Stack(
alignment: Alignment.center,
children: [
Positioned(
left: 0,
top: 0,
right: 0,
bottom: 0,
child: GoogleMap(
onMapCreated: (controller) {
},
),
),
Positioned(
left: 0,
right: 0,
bottom: 0,
child: Container(
height: 95,
child: Stack(
alignment: Alignment.topCenter,
children: [
Positioned(
left: 0,
top: 15,
right: 0,
child: Container(
height: 80,
decoration: BoxDecoration(
color: Color.fromARGB(255, 255, 255, 255),
),
child: Container(),
),
),
Positioned(
left: 9,
top: -1,
right: 20,
child: Container(
height: 82,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.topLeft,
child: Container(
width: 82,
height: 82,
child: Image.asset(
"assets/images/avatar-2.png",
fit: BoxFit.none,
),
),
),
Align(
alignment: Alignment.topLeft,
child: Container(
width: 122,
height: 51,
margin: EdgeInsets.only(left: 8, top: 25),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Align(
alignment: Alignment.topLeft,
child: Text(
"Guess who’s back?",
style: TextStyle(
color: Color.fromARGB(255, 15, 15, 15),
fontSize: 14,
fontFamily: "Lato",
fontWeight: FontWeight.w700,
),
textAlign: TextAlign.left,
),
),
Align(
alignment: Alignment.topLeft,
child: Container(
margin: EdgeInsets.only(top: 3),
child: Text(
"Happening in 20h, Bajkonur",
style: TextStyle(
color: Color.fromARGB(255, 0, 0, 0),
fontSize: 10,
fontFamily: "Lato",
),
textAlign: TextAlign.left,
),
),
),
Align(
alignment: Alignment.topLeft,
child: Container(
margin: EdgeInsets.only(top: 7),
child: Opacity(
opacity: 0.4,
child: Text(
"Event posted by Laika",
style: TextStyle(
color: Color.fromARGB(255, 0, 0, 0),
fontSize: 10,
fontFamily: "Lato",
),
textAlign: TextAlign.left,
),
),
),
),
],
),
),
),
Spacer(),
Align(
alignment: Alignment.topLeft,
child: Container(
width: 48,
height: 48,
margin: EdgeInsets.only(top: 28),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: 29,
margin: EdgeInsets.symmetric(horizontal: 10),
child: Image.asset(
"assets/images/group.png",
fit: BoxFit.none,
),
),
Spacer(),
Text(
"Coming",
style: TextStyle(
color: Color.fromARGB(255, 140, 28, 140),
fontSize: 14,
fontFamily: "Lato",
),
textAlign: TextAlign.left,
),
],
),
),
),
],
),
),
),
],
),
),
),
],
),
),
Positioned(
child: Container(
width: 185,
height: 185,
child: Image.asset(
"assets/images/icon-event-area.png",
fit: BoxFit.fill,
),
),
),
],
),
),
);
}
}
iOS Example
In the following example, you'll find a code required to build the screen in iOS using Swift 5. The layout is calculated from Starlight rules to pure Auto Layout definitions. This code is generated with UI type Code
. You can switch to Storyboards
and XIBs
where the code will look very different (most of the definitions will be moved to storyboards instead).
//
// EventDetailViewController.swift
// Spacebook
//
// Created by Supernova.
// Copyright © 2019 Supernova. All rights reserved.
//
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Import
import UIKit
import MapKit
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Implementation
class _EventDetailViewController: UIViewController {
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Properties
fileprivate var eventDetailView: UIView!
fileprivate var bgMapTempMapView: MKMapView!
fileprivate var iconEventAreaImageView: UIImageView!
fileprivate var footerView: UIView!
fileprivate var bgView: UIView!
fileprivate var avatarImageView: UIImageView!
fileprivate var guessWhoSBackLb: UILabel!
fileprivate var happeningIn20hBaLb: UILabel!
fileprivate var eventPostedByLaikLb: UILabel!
fileprivate var comingView: UIView!
fileprivate var groupImageView: UIImageView!
fileprivate var comingLb: UILabel!
fileprivate var groupBarButtonItem: UIBarButtonItem!
fileprivate var leftItemBarButtonItem: UIBarButtonItem!
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Lifecycle
override public func viewDidLoad() {
super.viewDidLoad()
self.setupComponents()
self.setupLayout()
self.setupUI()
self.setupGestureRecognizers()
self.setupLocalization()
// Do any additional setup after loading the view, typically from a nib.
}
override public func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Navigation bar, if any
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Setup
private func setupComponents() {
// Setup eventDetailView
self.view.backgroundColor = UIColor(red: 0.957, green: 0.949, blue: 0.957, alpha: 1) /* #F4F2F4 */
self.view.translatesAutoresizingMaskIntoConstraints = true
// Setup bgMapTempMapView
self.bgMapTempMapView = MKMapView()
self.bgMapTempMapView.isZoomEnabled = true
self.bgMapTempMapView.isScrollEnabled = true
self.bgMapTempMapView.isRotateEnabled = true
self.bgMapTempMapView.isPitchEnabled = true
self.bgMapTempMapView.showsBuildings = true
self.bgMapTempMapView.showsCompass = true
self.bgMapTempMapView.showsScale = false
self.bgMapTempMapView.showsTraffic = false
self.bgMapTempMapView.showsPointsOfInterest = true
self.bgMapTempMapView.showsUserLocation = false
self.bgMapTempMapView.backgroundColor = UIColor.clear
self.bgMapTempMapView.camera = MKMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.79, longitude: -122.41), fromDistance: 10000, pitch: 0, heading: 0)
self.view.addSubview(self.bgMapTempMapView)
self.bgMapTempMapView.translatesAutoresizingMaskIntoConstraints = false
// Setup iconEventAreaImageView
self.iconEventAreaImageView = UIImageView()
self.iconEventAreaImageView.backgroundColor = UIColor.clear
self.iconEventAreaImageView.image = UIImage(named: "icon-event-area")
self.iconEventAreaImageView.contentMode = .scaleToFill
self.view.addSubview(self.iconEventAreaImageView)
self.iconEventAreaImageView.translatesAutoresizingMaskIntoConstraints = false
// Setup footerView
self.footerView = UIView(frame: .zero)
self.footerView.backgroundColor = UIColor.clear
self.view.addSubview(self.footerView)
self.footerView.translatesAutoresizingMaskIntoConstraints = false
// Setup bgView
self.bgView = UIView(frame: .zero)
self.bgView.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1) /* #FFFFFF */
self.footerView.addSubview(self.bgView)
self.bgView.translatesAutoresizingMaskIntoConstraints = false
// Setup avatarImageView
self.avatarImageView = UIImageView()
self.avatarImageView.backgroundColor = UIColor.clear
self.avatarImageView.image = UIImage(named: "avatar-2")
self.avatarImageView.contentMode = .center
self.footerView.addSubview(self.avatarImageView)
self.avatarImageView.translatesAutoresizingMaskIntoConstraints = false
// Setup guessWhoSBackLb
self.guessWhoSBackLb = UILabel()
self.guessWhoSBackLb.numberOfLines = 0
self.guessWhoSBackLb.text = "Guess who’s back?"
self.guessWhoSBackLb.textColor = UIColor(red: 0.059, green: 0.059, blue: 0.059, alpha: 1) /* #0F0F0F */
self.guessWhoSBackLb.textAlignment = .left
self.guessWhoSBackLb.font = UIFont(name: "Lato-Bold", size: 14)
self.guessWhoSBackLb.backgroundColor = UIColor.clear
self.footerView.addSubview(self.guessWhoSBackLb)
self.guessWhoSBackLb.translatesAutoresizingMaskIntoConstraints = false
// Setup happeningIn20hBaLb
self.happeningIn20hBaLb = UILabel()
self.happeningIn20hBaLb.numberOfLines = 0
self.happeningIn20hBaLb.text = "Happening in 20h, Bajkonur"
self.happeningIn20hBaLb.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1) /* #000000 */
self.happeningIn20hBaLb.textAlignment = .left
self.happeningIn20hBaLb.font = UIFont(name: "Lato-Regular", size: 10)
self.happeningIn20hBaLb.backgroundColor = UIColor.clear
self.footerView.addSubview(self.happeningIn20hBaLb)
self.happeningIn20hBaLb.translatesAutoresizingMaskIntoConstraints = false
// Setup eventPostedByLaikLb
self.eventPostedByLaikLb = UILabel()
self.eventPostedByLaikLb.numberOfLines = 0
self.eventPostedByLaikLb.text = "Event posted by Laika"
self.eventPostedByLaikLb.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1) /* #000000 */
self.eventPostedByLaikLb.textAlignment = .left
self.eventPostedByLaikLb.font = UIFont(name: "Lato-Regular", size: 10)
self.eventPostedByLaikLb.backgroundColor = UIColor.clear
self.eventPostedByLaikLb.alpha = 0.4
self.footerView.addSubview(self.eventPostedByLaikLb)
self.eventPostedByLaikLb.translatesAutoresizingMaskIntoConstraints = false
// Setup comingView
self.comingView = UIView(frame: .zero)
self.comingView.backgroundColor = UIColor.clear
self.footerView.addSubview(self.comingView)
self.comingView.translatesAutoresizingMaskIntoConstraints = false
// Setup groupImageView
self.groupImageView = UIImageView()
self.groupImageView.backgroundColor = UIColor.clear
self.groupImageView.image = UIImage(named: "group")
self.groupImageView.contentMode = .center
self.comingView.addSubview(self.groupImageView)
self.groupImageView.translatesAutoresizingMaskIntoConstraints = false
// Setup comingLb
self.comingLb = UILabel()
self.comingLb.numberOfLines = 0
self.comingLb.text = "Coming"
self.comingLb.textColor = UIColor(red: 0.545, green: 0.106, blue: 0.549, alpha: 1) /* #8B1B8C */
self.comingLb.textAlignment = .left
self.comingLb.font = UIFont(name: "Lato-Regular", size: 14)
self.comingLb.backgroundColor = UIColor.clear
self.comingView.addSubview(self.comingLb)
self.comingLb.translatesAutoresizingMaskIntoConstraints = false
}
private func setupUI() {
self.extendedLayoutIncludesOpaqueBars = true
let navigationBar = self.navigationController!.navigationBar
let navigationGradient = CAGradientLayer()
navigationGradient.frame = navigationBar.bounds
navigationGradient.colors = [UIColor(red: 0.97, green: 0.52, blue: 0.38, alpha: 1).cgColor, UIColor(red: 0.55, green: 0.11, blue: 0.55, alpha: 1).cgColor]
navigationGradient.locations = [0.000, 1.000]
navigationGradient.startPoint = CGPoint(x: -0.014, y: 0.515)
navigationGradient.endPoint = CGPoint(x: 1.014, y: 0.485)
navigationBar.setBackgroundImage(UIImage.image(fromLayer: navigationGradient).resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch), for: .default)
navigationBar.tintColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
navigationBar.titleTextAttributes = [
NSFontAttributeName : UIFont(name: "Lato-Regular", size: 17)!,
NSForegroundColorAttributeName : UIColor(red: 1, green: 1, blue: 1, alpha: 1),
]
// Left navigation items
self.groupBarButtonItem = UIBarButtonItem(image: UIImage(named: "group-2"), style: .plain, target: self, action: #selector(self.onGroupPressed(_:)))
self.navigationItem.leftBarButtonItems = [ self.groupBarButtonItem ]
// Right navigation items
self.leftItemBarButtonItem = UIBarButtonItem(title: "Events", style: .plain, target: self, action: #selector(self.onLeftItemPressed(_:)))
self.navigationItem.rightBarButtonItems = [ self.leftItemBarButtonItem ]
self.navigationController?.setNavigationBarHidden(false, animated: true)
self.navigationItem.title = "Guess who's back?"
}
private func setupGestureRecognizers() {
}
private func setupLocalization() {
}
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Layout
private func setupLayout() {
// Setup layout for components
// Setup eventDetailView
// Setup bgMapTempMapView
self.bgMapTempMapView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
self.bgMapTempMapView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
self.bgMapTempMapView.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0).isActive = true
self.bgMapTempMapView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
// Setup iconEventAreaImageView
self.iconEventAreaImageView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: 0).isActive = true
self.iconEventAreaImageView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: 0).isActive = true
// Setup footerView
self.footerView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0).isActive = true
self.footerView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0).isActive = true
self.footerView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0).isActive = true
self.footerView.heightAnchor.constraint(equalToConstant: 95).isActive = true
// Setup bgView
self.bgView.leadingAnchor.constraint(equalTo: self.footerView.leadingAnchor, constant: 0).isActive = true
self.bgView.trailingAnchor.constraint(equalTo: self.footerView.trailingAnchor, constant: 0).isActive = true
self.bgView.topAnchor.constraint(equalTo: self.footerView.topAnchor, constant: 15).isActive = true
self.bgView.heightAnchor.constraint(equalToConstant: 80).isActive = true
// Setup avatarImageView
self.avatarImageView.leadingAnchor.constraint(equalTo: self.footerView.leadingAnchor, constant: 9).isActive = true
self.avatarImageView.topAnchor.constraint(equalTo: self.footerView.topAnchor, constant: -1).isActive = true
// Setup guessWhoSBackLb
self.guessWhoSBackLb.leadingAnchor.constraint(equalTo: self.avatarImageView.trailingAnchor, constant: 8).isActive = true
self.guessWhoSBackLb.topAnchor.constraint(equalTo: self.footerView.topAnchor, constant: 24).isActive = true
// Setup happeningIn20hBaLb
self.happeningIn20hBaLb.leadingAnchor.constraint(equalTo: self.avatarImageView.trailingAnchor, constant: 8).isActive = true
self.happeningIn20hBaLb.topAnchor.constraint(equalTo: self.guessWhoSBackLb.bottomAnchor, constant: 3).isActive = true
// Setup eventPostedByLaikLb
self.eventPostedByLaikLb.leadingAnchor.constraint(equalTo: self.avatarImageView.trailingAnchor, constant: 8).isActive = true
self.eventPostedByLaikLb.topAnchor.constraint(equalTo: self.happeningIn20hBaLb.bottomAnchor, constant: 7).isActive = true
// Setup comingView
self.comingView.trailingAnchor.constraint(equalTo: self.footerView.trailingAnchor, constant: -20).isActive = true
self.comingView.topAnchor.constraint(equalTo: self.footerView.topAnchor, constant: 27).isActive = true
self.comingView.widthAnchor.constraint(equalToConstant: 48).isActive = true
self.comingView.heightAnchor.constraint(equalToConstant: 48).isActive = true
// Setup groupImageView
self.groupImageView.leadingAnchor.constraint(equalTo: self.comingView.leadingAnchor, constant: 9).isActive = true
self.groupImageView.trailingAnchor.constraint(equalTo: self.comingView.trailingAnchor, constant: -9).isActive = true
self.groupImageView.topAnchor.constraint(equalTo: self.comingView.topAnchor, constant: 0).isActive = true
// Setup comingLb
self.comingLb.leadingAnchor.constraint(equalTo: self.comingView.leadingAnchor, constant: 0).isActive = true
self.comingLb.trailingAnchor.constraint(equalTo: self.comingView.trailingAnchor, constant: 0).isActive = true
self.comingLb.bottomAnchor.constraint(equalTo: self.comingView.bottomAnchor, constant: 0).isActive = true
}
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Status Bar
override public var prefersStatusBarHidden: Bool {
return false
}
override public var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Actions
@IBAction public func onGroupPressed(_ sender: UIView) {
// Pop the navigation stack or dismiss the modal presentation
if let navigationController = self.navigationController, navigationController.viewControllers.first != self {
navigationController.popViewController(animated: true)
} else if self.presentingViewController != nil {
self.dismiss(animated: true, completion: nil)
}
}
@IBAction public func onLeftItemPressed(_ sender: UIView) {
}
}
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Extension _EventDetailViewController
extension _EventDetailViewController: MKMapViewDelegate {
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
// MARK: - Methods
public func mapViewWillStartLoadingMap(_ mapView: MKMapView) {
}
public func mapViewDidFinishLoadingMap(_ mapView: MKMapView) {
}
public func mapViewDidFailLoadingMap(_ mapView: MKMapView, withError error: Error) {
}
public func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
}
}
Android Example
In the following example, you'll find a code required to build the screen in Android using Kotlin. The layout is calculated from Starlight rules to pure Constraint Layout definitions. This code is generated without data binding option, but you can optionally enable it to make work with the data easier. 2 files are required to build the screen - activity class and structure definition file.
/**
* Created by Supernova.
*/
package io.supernova.spacebook.activity
import android.content.Context
import android.view.View
import android.view.MenuItem
import android.support.v7.app.AppCompatActivity
import android.graphics.Color
import com.google.android.gms.maps.MapView
import android.widget.ImageView
import android.os.Bundle
import android.widget.TextView
import android.content.Intent
import android.support.v7.widget.Toolbar
import io.supernova.uitoolkit.drawable.LinearGradientDrawable
import android.view.Menu
import android.graphics.PointF
import io.supernova.spacebook.R
import android.support.constraint.ConstraintLayout
import android.view.MenuInflater
class EventDetailActivity: AppCompatActivity() {
companion object {
fun newIntent(context: Context): Intent {
// Fill the created intent with the data you want to be passed to this Activity when it's opened.
return Intent(context, EventDetailActivity::class.java)
}
}
private lateinit var toolbar: Toolbar
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
this.setContentView(R.layout.event_detail_activity)
this.init()
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.event_detail_activity_menu, menu)
return true
}
override fun onOptionsItemSelected(menuItem: MenuItem): Boolean {
when (menuItem.itemId) {
android.R.id.home -> {
this.onGroupPressed()
return true
}
R.id.left_item_menu_item -> {
this.onLeftItemPressed()
return true
}
else -> {
return super.onOptionsItemSelected(menuItem)
}
}
}
private fun init() {
// Configure Navigation Bar #2 component
toolbar = this.findViewById(R.id.toolbar)
toolbar.background = LinearGradientDrawable.Builder(this, PointF(-0.01f, 0.51f), PointF(1.01f, 0.49f)).addStop(0f, Color.argb(255, 247, 132, 97)).addStop(1f, Color.argb(255, 139, 27, 139)).build()
this.setupToolbar()
}
fun setupToolbar() {
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
// Additional Toolbar setup code can go here.
}
fun onGroupPressed() {
this.finish()
}
fun onLeftItemPressed() {
}
}
<android.support.constraint.ConstraintLayout
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/event_detail_constraint_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F4F2F4">
<com.google.android.gms.maps.MapView
android:id="@+id/bg_map_temp_map_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_weight="1"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp"/>
<ImageView
android:id="@+id/icon_event_area_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:src="@drawable/icon_event_area"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="95dp"
tools:layout_editor_absoluteY="241dp"/>
<android.support.constraint.ConstraintLayout
android:id="@+id/footer_constraint_layout"
android:layout_width="0dp"
android:layout_height="91dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="572dp">
<View
android:id="@+id/bg_constraint_layout"
android:layout_width="0dp"
android:layout_height="77dp"
android:layout_marginTop="14dp"
android:background="#FFFFFF"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="15dp"/>
<ImageView
android:id="@+id/avatar_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="9dp"
android:layout_marginTop="-1dp"
android:scaleType="center"
android:src="@drawable/avatar_2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="9dp"
tools:layout_editor_absoluteY="-1dp"/>
<TextView
android:id="@+id/guess_who_sback_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="23dp"
android:fontFamily="@font/font_lato_bold"
android:gravity="start"
android:text="Guess who’s back?"
android:textColor="#0F0F0F"
android:textSize="13sp"
app:layout_constraintLeft_toRightOf="@+id/avatar_image_view"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="99dp"
tools:layout_editor_absoluteY="24dp"/>
<TextView
android:id="@+id/happening_in20h_ba_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="3dp"
android:fontFamily="@font/font_lato_regular"
android:gravity="start"
android:text="Happening in 20h, Bajkonur"
android:textColor="#000000"
android:textSize="10sp"
app:layout_constraintLeft_toRightOf="@+id/avatar_image_view"
app:layout_constraintTop_toBottomOf="@+id/guess_who_sback_text_view"
tools:layout_editor_absoluteX="99dp"
tools:layout_editor_absoluteY="44dp"/>
<TextView
android:id="@+id/event_posted_by_laik_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="7dp"
android:alpha="0.4"
android:fontFamily="@font/font_lato_regular"
android:gravity="start"
android:text="Event posted by Laika"
android:textColor="#000000"
android:textSize="10sp"
app:layout_constraintLeft_toRightOf="@+id/avatar_image_view"
app:layout_constraintTop_toBottomOf="@+id/happening_in20h_ba_text_view"
tools:layout_editor_absoluteX="99dp"
tools:layout_editor_absoluteY="63dp"/>
<android.support.constraint.ConstraintLayout
android:id="@+id/coming_constraint_layout"
android:layout_width="46dp"
android:layout_height="46dp"
android:layout_marginEnd="19dp"
android:layout_marginTop="26dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="307dp"
tools:layout_editor_absoluteY="27dp">
<ImageView
android:id="@+id/group_image_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="9dp"
android:layout_marginStart="9dp"
android:scaleType="center"
android:src="@drawable/group"
app:layout_constraintHorizontal_weight="0.6"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="9dp"
tools:layout_editor_absoluteY="0dp"/>
<TextView
android:id="@+id/coming_text_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="@font/font_lato_regular"
android:gravity="start"
android:text="Coming"
android:textColor="#8B1B8C"
android:textSize="13sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="31dp"/>
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
React Native Example
In the following example, you'll find a code required to build the screen in React Native using JSX. The layout is calculated from Starlight rules to pure Flexbox definitions. Two files are required to implement the screen, the structural definition and styles.
//
// EventDetail
// Spacebook
//
// Created by Supernova.
// Copyright © 2018 Supernova. All rights reserved.
//
import { View, Image, Text, TouchableOpacity } from "react-native"
import React from "react"
import { LinearGradient } from "expo-linear-gradient"
import { MapView } from "expo"
import styles from "./EventDetailStyleSheet"
export default class EventDetail extends React.Component {
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state
return {
headerTransparent: true,
headerBackground: <LinearGradient
start={{
x: -0.01,
y: 0.51,
}}
end={{
x: 1.01,
y: 0.49,
}}
locations={[0, 1]}
colors={["rgb(247, 132, 98)", "rgb(139, 27, 140)"]}
style={styles.navigationBarGradient}/>,
title: "Guess who's back?",
headerTintColor: "white",
headerLeft: <View
style={styles.headerLeftContainer}>
<TouchableOpacity
onPress={params.onGroupPressed ? params.onGroupPressed : () => null}
style={styles.navigationBarItem}>
<Image
source={require("./../../assets/images/group-2.png")}
style={styles.navigationBarItemIcon}/>
</TouchableOpacity>
</View>,
headerRight: <View
style={styles.headerRightContainer}>
<TouchableOpacity
onPress={params.onLeftItemPressed ? params.onLeftItemPressed : () => null}
style={styles.navigationBarItem}>
<Text
style={styles.navigationBarItemTitle}>Events</Text>
</TouchableOpacity>
</View>,
headerStyle: {
},
}
}
constructor(props) {
super(props)
}
componentDidMount() {
this.props.navigation.setParams({
onGroupPressed: this.onGroupPressed,
onLeftItemPressed: this.onLeftItemPressed,
})
}
onGroupPressed = () => {
this.props.navigation.goBack()
}
onLeftItemPressed = () => {
}
render() {
return <View
style={styles.eventDetailView}>
<View
pointerEvents="box-none"
style={{
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
}}>
<MapView
showsScale={false}
showsTraffic={false}
style={styles.bgMapTempMapView}/>
<View
style={styles.footerView}>
<View
style={styles.bgView}/>
<View
pointerEvents="box-none"
style={{
position: "absolute",
left: 9,
right: 20,
top: -1,
height: 82,
flexDirection: "row",
alignItems: "flex-start",
}}>
<Image
source={require("./../../assets/images/avatar-2.png")}
style={styles.avatarImage}/>
<View
pointerEvents="box-none"
style={{
width: 122,
height: 51,
marginLeft: 8,
marginTop: 25,
alignItems: "flex-start",
}}>
<Text
style={styles.guessWhoSBackText}>Guess who’s back?</Text>
<Text
style={styles.happeningIn20hBaText}>Happening in 20h, Bajkonur</Text>
<Text
style={styles.eventPostedByLaikText}>Event posted by Laika</Text>
</View>
<View
style={{
flex: 1,
}}/>
<View
style={styles.comingView}>
<Image
source={require("./../../assets/images/group.png")}
style={styles.groupImage}/>
<View
style={{
flex: 1,
}}/>
<Text
style={styles.comingText}>Coming</Text>
</View>
</View>
</View>
</View>
<View
pointerEvents="box-none"
style={{
position: "absolute",
alignSelf: "center",
top: 0,
bottom: 0,
justifyContent: "center",
}}>
<Image
source={require("./../../assets/images/icon-event-area.png")}
style={styles.iconEventAreaImage}/>
</View>
</View>
}
}
//
// EventDetailStyleSheet.js
// Spacebook
//
// Created by Supernova.
// Copyright © 2018 Supernova. All rights reserved.
//
import { StyleSheet } from "react-native"
const styles = StyleSheet.create({
navigationBarItemTitle: {
color: "white",
},
navigationBarGradient: {
flex: 1,
},
headerLeftContainer: {
flexDirection: "row",
marginLeft: 8,
},
navigationBarItemIcon: {
tintColor: "white",
},
headerRightContainer: {
flexDirection: "row",
marginRight: 8,
},
navigationBarItem: {
},
eventDetailView: {
backgroundColor: "rgb(244, 242, 244)",
flex: 1,
},
bgMapTempMapView: {
backgroundColor: "transparent",
position: "absolute",
left: 0,
right: 0,
top: 0,
bottom: 0,
},
footerView: {
backgroundColor: "transparent",
position: "absolute",
left: 0,
right: 0,
bottom: 0,
height: 95,
},
bgView: {
backgroundColor: "white",
position: "absolute",
left: 0,
right: 0,
top: 15,
height: 80,
},
avatarImage: {
resizeMode: "center",
backgroundColor: "transparent",
width: 82,
height: 82,
},
guessWhoSBackText: {
backgroundColor: "transparent",
color: "rgb(15, 15, 15)",
fontFamily: "Lato-Bold",
fontSize: 14,
fontStyle: "normal",
fontWeight: "bold",
textAlign: "left",
},
happeningIn20hBaText: {
backgroundColor: "transparent",
color: "black",
fontFamily: "Lato-Regular",
fontSize: 10,
fontStyle: "normal",
fontWeight: "normal",
textAlign: "left",
marginTop: 3,
},
eventPostedByLaikText: {
backgroundColor: "transparent",
opacity: 0.4,
color: "black",
fontFamily: "Lato-Regular",
fontSize: 10,
fontStyle: "normal",
fontWeight: "normal",
textAlign: "left",
marginTop: 7,
},
comingView: {
backgroundColor: "transparent",
width: 48,
height: 48,
marginTop: 28,
},
groupImage: {
resizeMode: "center",
backgroundColor: "transparent",
width: null,
height: 29,
marginLeft: 10,
marginRight: 10,
},
comingText: {
color: "rgb(139, 27, 140)",
fontFamily: "Lato-Regular",
fontSize: 14,
fontStyle: "normal",
fontWeight: "normal",
textAlign: "left",
backgroundColor: "transparent",
},
iconEventAreaImage: {
backgroundColor: "transparent",
resizeMode: "stretch",
width: 185,
height: 185,
},
})
export default styles
Updated almost 3 years ago