# Table of contents # Create Views Activity - Sometimes things that were available in XML are not available in Compose - Interop # How to write UI - XML - Manual # Building blocks - View - ViewGroup - Describe and show difference with Compose # Dimensions - Density-independent pixels (dp) - Scalable pixels (sp) - WrapContent - MatchParent - Raw pixels :warning: # Introduce editor # Views ## FrameLayout basics (for overlapping views) ## View - Fixed `width`, `height`, `matchParent` - `background`, `visibility` - `layout_gravity`, `margin` - Typical usage: divider ```xml= <View android:layout_width="200dp" android:layout_height="200dp" android:background="#ff0000" /> <View android:layout_width="match_parent" android:layout_height="2dp" android:layout_marginTop="200dp" android:background="#000" /> ``` ## TextView - `wrapContent`, `text` - `fontFamily` (add font), `textSize` - `gravity` vs `layout_gravity` - `padding` vs `margin` - `ellipsize` ```xml= <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#FFC7C7" android:ellipsize="end" android:fontFamily="@font/roboto_serif" android:gravity="center" android:maxLines="2" android:padding="20dp" android:text="How are you?" android:textSize="24sp" /> ``` ## Button - `findViewById`, `viewBinding` (`viewBinding true`), data binding exists - ID also used for state restoration - `setOnClickListener` - https://stackoverflow.com/questions/3572463/what-is-context-on-android - `enabled`, `disabled` ```xml= <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click me" /> ``` ```kotlin= val button = findViewById<Button>(R.id.button) button.setOnClickListener { Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show() } val binding = ViewButtonBinding.inflate(layoutInflater) binding.button.text = "Yooo, click pls" binding.button.setOnClickListener { Snackbar.make(binding.root, "Hello", Snackbar.LENGTH_SHORT).show() } setContentView(binding.root) ``` ## ImageView - `srcCompat` (import vector drawable, png) - `scaleType`, `contentDescription` - https://medium.com/mobile-app-development-publication/android-imageview-scaletype-fully-illustrated-with-adjustviewbound-1ce094dee777 - SelectableBackground - Mention `Coil` ```xml= <ImageView android:layout_width="200dp" android:layout_height="200dp" android:contentDescription="@null" android:scaleType="centerCrop" app:srcCompat="@drawable/kitten" /> ``` # ViewGroups ## FrameLayout - Typical usage: image with something, gradients etc. ```xml= <?xml version="1.0" encoding="utf-8"?> <FrameLayout 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"> <FrameLayout android:id="@+id/img_container" android:layout_width="250dp" android:layout_height="wrap_content" android:layout_gravity="center" tools:ignore="UselessParent"> <ImageView android:layout_width="250dp" android:layout_height="250dp" android:contentDescription="@null" android:scaleType="centerCrop" app:srcCompat="@drawable/kitten" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_marginVertical="8dp" android:layout_marginStart="48dp" android:layout_marginEnd="8dp" android:background="#59000000" android:padding="4dp" android:text="Some description of the img" android:textColor="#FFF" android:textSize="20sp" /> </FrameLayout> </FrameLayout> ``` ## LinearLayout - `vertical`, `horizontal` - `weight` ```xml= <?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:orientation="vertical" android:weightSum="4"> <TextView android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="2" android:text="Hello" /> <TextView android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" android:text="Hello" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="How are you?" /> </LinearLayout> ``` ## ScrollView & HorizontalScrollView - NOT USED FOR INFINITE LISTS (ListView haha, RecyclerView) ```xml= <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> ... ... </ScrollView> ``` # Resources ## Types - `layout` (reference with `R.layout` or `@layout`) - it's just IDs, not the real thing - `drawable` (`.png`, `.jpg`, vectors, `shapes`, state drawables, vector image asset, image asset) ```xml= <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <solid android:color="#ff0000" /> <corners android:radius="24dp" /> <stroke android:width="12dp" android:color="#000" /> </shape> <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <item android:drawable="@color/teal_200" android:state_enabled="true" /> <item android:drawable="@color/purple_200" /> </selector> ``` - `values` - colors - dimens - strings - styles ```xml= Colors <resources> <color name="purple_200">#FFBB86FC</color> <color name="purple_500">#FF6200EE</color></resources> Strings <resources> <string name="app_name">cv2</string> <string name="greeting">Hello %s, how are you?</string> </resources> Styles <item name="colorPrimary">@color/my_red</item> <item name="android:textSize">22sp</item> <style name="MyTextViewStyle" parent="TextAppearance.MaterialComponents.Headline1"> <item name="android:textSize">48sp</item> <item name="android:textColor">#008832</item> <item name="android:background">@color/purple_200</item> </style> <item name="textAppearanceHeadline1">@style/MyTextViewStyle</item> Dimens <resources> <dimen name="some_space">58dp</dimen> </resources> ``` - `colors` ```xml= <selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <item android:color="@color/purple_200" android:state_enabled="true" /> <item android:color="@color/my_red" /> </selector> ``` - `fonts` (use resource manager, download online) - `menu` ```xml= <item android:icon="@drawable/ic_timer" android:title="Search" app:showAsAction="always" /> <item android:icon="@drawable/ic_caution" android:title="Add" app:showAsAction="always" /> ``` - `mipmap` (launcher icons) - `raw` (for example videos) ## Qualifiers - locale - night mode - size - version - density - :warning: precedence - They must be defined in the correct order - Google Play can strip unused resources ### Implement - Dark mode - Translations (preferred languages) # Break # Constraint Layout - `match_constraint`, `constrainedWidth` - `bias`, `chains` - `barrier`, `guideline`, `group`, `ratio` - Why is it better? - Why even use other ViewGroups? - Mentioned MotionLayout, RelativeLayout, ... - Compose vs ConstraintLayout # More views - Toolbar, BottomNavigation, Card, CheckBox, RadioButton/Group, Switch, ProgressBar, Swipe2Refresh, TabLayout # UI implementation # Mention custom view # Final notes - Debugging with layout inspector