0% found this document useful (0 votes)
10 views44 pages

Lecture2-Activities Layouts Fragments Resources

The document provides an overview of Android development focusing on layouts, resources, and UI components. It covers essential topics such as XML layout definitions, handling user interactions, using ViewBinding, supporting different screen sizes, and implementing lists with ListView and RecyclerView. Additionally, it introduces Jetpack Compose for building adaptive and flexible layouts in modern Android applications.

Uploaded by

airmetrix
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views44 pages

Lecture2-Activities Layouts Fragments Resources

The document provides an overview of Android development focusing on layouts, resources, and UI components. It covers essential topics such as XML layout definitions, handling user interactions, using ViewBinding, supporting different screen sizes, and implementing lists with ListView and RecyclerView. Additionally, it introduces Jetpack Compose for building adaptive and flexible layouts in modern Android applications.

Uploaded by

airmetrix
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 44

Course 2 – layouts and resources

Lifecycle

https://developer.android.com/guide/components/activities/activity-lifecycle
Layouts
https://developer.android.com/guide/topics/ui/declaring-layout
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">
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView"/>
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"/>
</LinearLayout>

fun onCreate(savedInstanceState: Bundle) {


super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
}
Accessing Assets
<?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">
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a TextView"/>
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"/>
</LinearLayout>

fun onCreate(savedInstanceState: Bundle) {


super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
} val myButton: Button =
findViewById(R.id.button)
}
Add Event
...
Handler
<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"
/> android:onClick="sendMessage"
...

fun onCreate(savedInstanceState: Bundle) {


super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
val myButton: Button =
findViewById(R.id.button)
}
fun sendMessage(view: View) {
logd("Ready!")
}
Using Android
... KTX
import kotlinx.android.synthetic.main.activity_main.*

<Button android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, I am a Button"
android:onClick="sendMessage"
/>
...

fun onCreate(savedInstanceState: Bundle)


{ super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
val myButton : Button = findViewById(R.id.button)
myButton.setOnClickListener {
text.text = "From editText: {editText.text.toString()}"
myButton.text = “Update”
}
fun sendMessage(view: View) {
logd(“Ready!”);
}

https://developer.android.com/kotlin/ktx
Using ViewBinding
plugins
{ kotlin("android.extension
s")
}
android {
...
buildFeatures
{ viewBinding =
true
}
}

private lateinit var binding: MainActivityBinding


override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainActivityBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}
Using ViewBinding
private lateinit var binding: MainActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainActivityBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
}

binding.name.text = “Hello, I am a TextView”


binding.button.setOnClickListener { viewModel.userClicked() }

https://developer.android.com/topic/libraries/view-binding
Supporting different
screen sizes

• Flexible layouts

• Alternative layouts

• Stretchable images

• Alternative bitmaps

• Vector graphics

https://developer.android.com/guide/practices/screens_support
Flexible Layouts
ConstraintLayout
In module-level gradle.build:
repositories {
google()
}

dependencies {
implementation
‘com.android.su
pport.constrai
nt:constraint-
layout:2.1.4’
}

https://developer.android.com/training/constraint-layout/
Alternative layouts
res/layout/main_activity.xml # Default layout
res/layout-land/main_activity.xml # When in landscape mode
res/layout-sw600dp/main_activity.xml # For 7” tablets
res/layout-sw600dp-land/main_activity.xml # For 7” tablets in landscape

https://developer.android.com/training/multiscreen/screensizes#alternative-layouts
Building a Dynamic UI
with Fragments

https://developer.android.com/guide/components/fragments
Creating a Fragment
• New callbacks

• onAttach

• onCreateView

• onActivityCreated

• onDestroyView

• onDetach

https://developer.android.com/reference/android/support/v4/app/Fragment
Creating a Fragment
class ArticleListFragment : Fragment() {

override fun onCreateView(


inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.example_fragment,
} container, false)
}

<?xml version=“1.0” xmlns:android="http://schemas.android.com/apk


/res/android"
android:orientation=“horizontal”
android:layout_width="match_parent">
android:layout_height="match_parent">

<fragment android:name="com.example.news.ArticleListFragment"
android:id="@+id/list"
android:layout_weight="1" android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment android:name="com.example.news.ArticleReaderFragment"
android:id="@+id/viewer"
android:layout_weight="2" android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>

https://developer.android.com/reference/android/support/v4/app/Fragment
Creating a Fragment
class ArticleListFragment : Fragment() {

override fun onCreateView(


inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this
fragment false)
return
} inflater.inflate(R.layout.examp
le_fragment, container,
}
Or, programmatically
val fragmentManager add the
= supportFragmentManager
fragment to an existing
val fragmentTransaction = fragmentManager.beginTransaction()
ViewGroup

val fragment = ArticleListFragment()


fragmentTransaction.add(R.id.fragment_container, fragment)
fragmentTransaction.commit()

https://developer.android.com/reference/android/support/v4/app/Fragment
Density-independent pixels
Density-independent pixels
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/clickme"
android:layout_marginTop="20dp" />

<TextView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp" />
dp units to pixel
units medium-density screen
"baseline" density

px = dp * (dpi / 160)

Actual device pixels


Progress Indicators
<ProgressBar
android:id="@+id/indicator"
android:layout_width="wrap_content“
android:layout_height="wrap_content“
android:visibility="gone"
/>
//before starting the action
indicator.visibility = = View.VISIBLE

indicator.visibility = = View.GONE

https://developer.android.com/reference/android/widget/ProgressBar
Lists

• ListView

• RecyclerView
ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>

<?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="wrap_content"
android:orientation="vertical">
<TextView android:id="@+id/text"
android:textSize="16sp"
android:textStyle="bold"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView android:id="@+id/subText"
...
</LinearLayout>
ListView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="..."
android:orientation="vertical"
android:layout_width="match_parent"

android:layout_height="match_parent
" android:paddingLeft="8dp"
android:paddingRight="8dp">
<ListView android:id="@android:id/myList"
android:layout_width="match_parent"
android:layout_height="match_parent"/
>
</LinearLayout>

val arrayAdapter = ArrayAdapter<String>(this,


android.R.layout.simple_list_item_1, arrayList)

myList.adapter = arrayAdapter

https://developer.android.com/guide/topics/ui/layout/listview
RecyclerView

• ListView

• RecyclerView
RecyclerView
<?xml version="1.0" encoding="utf-8"?>
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

class MyActivity : Activity() {


private lateinit var recyclerView: RecyclerView
var viewAdapter: RecyclerView.Adapter<*>
private lateinit var viewManager: RecyclerView.LayoutManager
override fun onCreate(savedInstanceState: Bundle?) {
private lateinit
super.onCreate(savedInstanceState)
setContentView(R.layout.my_activity)
viewManager = LinearLayoutManager(this)
viewAdapter = MyAdapter(myDataset)
recyclerView = findViewById<RecyclerView>(R.id.my_recycler_view).apply {
setHasFixedSize(true)
layoutManager = viewManager
adapter = viewAdapter
}
}
// ...
}

https://developer.android.com/guide/topics/ui/layout/recyclerview
RecyclerView.Adapter
class MyAdapter(private val myDataset: Array<String>) :
RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

class MyViewHolder(val textView: TextView) : RecyclerView.ViewHolder(textView)

override fun onCreateViewHolder(parent: ViewGroup,


viewType: Int): MyAdapter.MyViewHolder {
val textView = LayoutInflater.from(parent.context)
.inflate(R.layout.my_text_view,
parent, false) as TextView
...
return MyViewHolder(textView)
}

// ReplaceMyViewHolder,
override fun onBindViewHolder(holder: the contents position:
of a view Int)
(invoked
{
by the
// layout manager)from your dataset at this position
- get element
// - replace the contents of the view with that element
holder.textView.text = myDataset[position]
}

override fun getItemCount() = myDataset.size


}

https://developer.android.com/guide/topics/ui/layout/recyclerview
AsyncTask Deprecated

BackgroundThread

class SomeTask():
AsyncTask<Void, Int, S tring>() {
override fun doInBackground(
vararg params: Void?):
String? {
// ...
}
override fun onPreExecute()
{ super.onPreExecute()
// ...
}
override fun
onPostExecute( result:
String?) {
super.onPostExecute(result)
// ...
}
override fun
onProgressUpdate( vararg
values: Int){ UiThread
super.onProgressUpdate(result)
}// ...
} https://developer.android.com/reference/android/os/AsyncTask
Anko AsyncTask Alternative
BackgroundThread

doAsync {
//Execute all the long running
// tasks here
val s: String = makeNetworkCall()
uiThread {
//Update the UI thread here
alert("Downloaded data is $s",
"Hi I'm an alert") { yesButton
{ toast("Yay !") } noButton
{ toast(":( !") }
}.show()
}
}

UiThread

https://github.com/Kotlin/anko/wiki/Anko-
Coroutines
Jetpack Compose

https://developer.android.com/jetpack/compose
Compose Layout Basics
Compose transforms state into UI elements, via:
•Composition of elements
•Layout of elements
•Drawing of elements
Goals

•High performance
•Ability to easily write custom layouts
Basics

@Composable
fun ArtistCard()
{
Text("Alfred Sisley")
Text("3 minutes ago")
}
Basics
@Composable
fun ArtistCard()
{
Column {
Text("Alfred Sisley")
Text("3 minutes ago")
}
}
Basics
@Composable
fun ArtistCard(artist: Artist) {
Row(verticalAlignment = Alignment.CenterVertically) {
Image(/*...*/)
Column {
Text(artist.name)
Text(artist.lastSeenOnline)
}
}
}
Basics
LazyLists
import androidx.compose.foundation.lazy.items

@Composable
fun MessageList(messages: List<Message>) {
LazyColumn {
items(messages) { message ->
MessageRow(message)
}
}
}

https://developer.android.com/jetpack/compose/
tutorial
Constraint Layout
@Composable
fun ConstraintLayoutContent() {
ConstraintLayout {
// Create references for the
composables to constrain
val (button, text) = createRefs()
Button(
onClick = { /* Do something */
},
// Assign reference "button" to
the Button composable
// and constrain it to the top of the ConstraintLayout
modifier = Modifier.constrainAs(button) {
top.linkTo(parent.top, margin = 16.dp)
}
){
Text("Button")
}
Adaptive Layouts
Adaptive Layouts
enum class WindowSizeClass { Compact, Medium, Expanded }

@Composable
fun MyApp(windowSizeClass: WindowSizeClass) {
// Perform logic on the size class to decide whether to show
// the top app bar.
val showTopAppBar = windowSizeClass != WindowSizeClass.Compact

// MyScreen knows nothing about window sizes, and performs logic


// based on a Boolean flag.
MyScreen(
showTopAppBar =
showTopAppBar,
/* ... */
)
}
Flexible Layouts
@Composable
fun
AdaptivePane(
showOnePane:
Boolean,
/* ... */
){
if (showOnePane) {
OnePane(/* ...
*/)
} else {
TwoPane(/* ... */)
}
}
Flexible Layouts
@Composable
fun
AdaptivePane(
showOnePane:
Boolean,
/* ... */
){
if (showOnePane) {
OnePane(/* ...
*/)
} else {
TwoPane(/* ... */)
}
}
Flexible Layouts
@Composable
fun Card(/* ... */)
{ BoxWithConstraint
s{
if (maxWidth <
400.dp) {
Column
{ Image(/* ...
*/)
Title(/* ... */)
}
} else {
Row {
Column
{ Title(/* ...
*/)
Description(/
* ... */)
}
Flexible Layouts
@Composable
fun Card(/* ... */)
{ BoxWithConstraint
s{
if (maxWidth <
400.dp) {
Column
{ Image(/* ...
*/)
Title(/* ... */)
}
} else {
Row {
Column
{ Title(/* ...
*/)
Description(/
* ... */)
} } https://developer.android.com/large-screens
Lecture outcomes

• Support different screen,


using layouts and fragments

• ListView, RecyclerView,
Progress Indicators

• Retrieve data on background


threads

You might also like