Building a Twitter Profile Clone Using Jetpack Compose
Starting With Jetpack Compose
I started learning Jetpack Compose recently. Building android UI now feels programmatic. I managed to build the profile page although it's not a near perfect match clone, I learnt some basic skills working with Jetpack Compose
This were some of the takeaways:
- Using Rows
- Using Columns
- Loading Images from drawable resource directory
- Defining theme Colors
- Overriding theme color
- Using Box component to stack components
- Material theme
- Defining a composable
- Previewing a composable
Below is a code snippet that entails usage of above mentioned items.
View Composable
@Composable
fun profile(){
Column(modifier = Modifier
.fillMaxSize()
.background(color = MaterialTheme.colors.background)){
Row(
modifier = Modifier
.padding(
start = 15.dp,
top = 15.dp, end = 15.dp, bottom = 8.dp
)
.fillMaxWidth()
) {
Image(
painter = painterResource(id = R.drawable.ic_baseline_arrow_back_24),
contentDescription = "Back Arrow",
modifier = Modifier.align(Alignment.CenterVertically)
)
Spacer(modifier = Modifier.width(20.dp))
Column() {
Text(text = "John Mwai",
color = Color.White,
fontSize= 20.sp,
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.body1
)
Spacer(modifier = Modifier.height(1.dp))
Text(text = "814 tweets",
style = MaterialTheme.typography.caption,
color = Color.Gray,
fontSize = 13.sp)
}
}
Box(
modifier = Modifier
.height(220.dp)
.fillMaxSize()
){
Box(modifier = Modifier
.fillMaxWidth()) {
Image(
painter = painterResource(id = R.drawable.header_image),
contentDescription = "Header Image")
}
Box( modifier = Modifier
.fillMaxSize()
.padding(start = 15.dp, bottom = 15.dp),
contentAlignment = Alignment.BottomStart
){
Image(painter = painterResource(
id = R.drawable.photo),
contentDescription = "Profile Picture",
modifier = Modifier
.clip(CircleShape)
.size(120.dp)
.border(
2.dp, MaterialTheme.colors.background,
CircleShape
))
}
Box( modifier = Modifier
.fillMaxSize()
.padding(
start = 1.dp,
top = 15.dp, end = 15.dp, bottom = 40.dp
),
contentAlignment = Alignment.BottomEnd
){
OutlinedButton(onClick = { /*TODO*/ },
shape = CircleShape,
border= BorderStroke(1.dp, Color.Gray,),
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.background,
contentColor = Color.White)
) {
Text(text = "Edit profile",
style = MaterialTheme.typography.body1,
fontWeight = FontWeight.Bold)
}
}
}
Column(
modifier = Modifier.padding(15.dp)
) {
Column {
Text(text = "John Mwai",
color = Color.White,
fontSize= 20.sp,
fontWeight = FontWeight.Bold,
style = MaterialTheme.typography.body1
)
Spacer(modifier = Modifier.height(1.dp))
Text(text = "@HelloMwai",
style = MaterialTheme.typography.caption,
color = Color.Gray,
fontSize = 13.sp)
Spacer(modifier = Modifier.height(15.dp))
Text(text = "#android #backend #kotlin",
style = MaterialTheme.typography.caption,
color = Color(0xFF1D98F0),
fontSize = 13.sp)
Spacer(modifier = Modifier.height(1.dp))
Text(text = "Eternal student, Software developer,Programmer",
style = MaterialTheme.typography.caption,
color = Color.White,
fontSize = 13.sp)
Spacer(modifier = Modifier.height(15.dp))
Text(text = "watch me build, \nwatch me write, \nwatch me fail, \nwatch me succeed",
style = MaterialTheme.typography.caption,
color = Color.White,
fontSize = 13.sp)
Spacer(modifier = Modifier.height(5.dp))
Row(horizontalArrangement = Arrangement.SpaceBetween) {
Icon(painter = painterResource(R.drawable.location), tint = Color.Gray , contentDescription = "DOB")
Spacer(modifier = Modifier.width(2.dp))
Text("World",
color = Color.Gray,)
Spacer(modifier = Modifier.width(15.dp))
Icon(painter = painterResource(R.drawable.ic_baseline_link), tint = Color.Gray , contentDescription = "DOB")
Spacer(modifier = Modifier.width(2.dp))
Text("github.com/mwaijohn",
color = Color(0xFF1D98F0),)
}
Spacer(modifier = Modifier.height(0.5.dp))
Row(horizontalArrangement = Arrangement.SpaceAround) {
Icon(painter = painterResource(R.drawable.balloon), tint = Color.Gray , contentDescription = "DOB")
Spacer(modifier = Modifier.width(2.dp))
Text("Born September 10, 1996",
color = Color.Gray,)
Spacer(modifier = Modifier.width(15.dp))
Icon(painter = painterResource(R.drawable.date), tint = Color.Gray , contentDescription = "DOB")
Spacer(modifier = Modifier.width(2.dp))
Text("Joined March 2017",
color = Color.Gray)
}
Spacer(modifier = Modifier.height(4.dp))
Row(horizontalArrangement = Arrangement.SpaceAround) {
Row(){
Text("706",
color = Color.White,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.width(7.dp))
Text("Following",
color = Color.Gray)
}
Spacer(modifier = Modifier.width(5.dp))
Row(){
Text("298",
color = Color.White,
fontWeight = FontWeight.Bold)
Spacer(modifier = Modifier.width(7.dp))
Text("Followers",
color = Color.Gray)
}
}
}
}
}
Preview Composable
@Preview(showBackground = true, showSystemUi = true)
@Composable
fun ProfilePreview() {
ComposeTwitterProfileTheme {
profile()
}
}
Showing composable content in MainActivity
ComposeTwitterProfileTheme {
profile()
}