我們繼續(xù)官方Jetchat這個(gè)項(xiàng)目講解
MainActivity 的入口最后一部分代碼
JetchatScaffold(
scaffoldState,
onChatClicked = {
findNavController(R.id.nav_host_fragment)
.popBackStack(R.id.nav_home, true)
scaffoldState.drawerState.close()
},
onProfileClicked = {
val bundle = bundleOf("userId" to it)
findNavController(R.id.nav_host_fragment).navigate(
R.id.nav_profile,
bundle
)
scaffoldState.drawerState.close()
}
) {
// Workaround for https://issuetracker.google.com/178174718
// and https://issuetracker.google.com/179181757
// Inflate the XML layout using View Binding:
val bindingRef = remember { Ref<ViewBinding>() }
val currentView = LocalView.current
AndroidViewBinding({ inflater, parent, attachToParent ->
if (bindingRef.value == null) {
val binding: ViewBinding =
ContentMainBinding.inflate(inflater, parent, attachToParent)
bindingRef.value = binding
binding.root.compositionContext =
currentView.findViewTreeCompositionContext()
}
bindingRef.value as ViewBinding
})
// End of workaround
// AndroidViewBinding(ContentMainBinding::inflate)
}
JetchatScaffold
封裝了自己的腳手架或者頁(yè)面主題和布局
@Composable
fun JetchatScaffold(
scaffoldState: ScaffoldState = rememberScaffoldState(),
onProfileClicked: (String) -> Unit,
onChatClicked: (String) -> Unit,
content: @Composable (PaddingValues) -> Unit
) {
JetchatTheme {
Scaffold(
scaffoldState = scaffoldState,
drawerContent = {
JetchatDrawer(
onProfileClicked = onProfileClicked,
onChatClicked = onChatClicked
)
},
bodyContent = content
)
}
}
利用組合思想內(nèi)部封裝了JetchatTheme 自定義主題
@Composable
fun JetchatTheme(
isDarkTheme: Boolean = isSystemInDarkTheme(),
colors: Colors? = null,
content: @Composable () -> Unit
) {
val myColors = colors ?: if (isDarkTheme) JetchatDarkPalette else JetchatLightPalette
MaterialTheme(
colors = myColors,
content = content,
typography = JetchatTypography,
shapes = JetchatShapes
)
}
我們看到這里就要回顧主題相關(guān)知識(shí)呐萌。isDarkTheme 判斷是否是深色主題篮迎,那么MaterialDesign方式封裝了兩套主題料滥。深色和淺色
JetchatDarkPalette 和 JetchatLightPalette
private val JetchatDarkPalette = darkColors(
primary = Blue200,
primaryVariant = Blue400,
onPrimary = Color.Black,
secondary = Yellow400,
onSecondary = Color.Black,
onSurface = Color.White,
onBackground = Color.White,
error = Red300,
onError = Color.Black
)
private val JetchatLightPalette = lightColors(
primary = Blue500,
primaryVariant = Blue800,
onPrimary = Color.White,
secondary = Yellow700,
secondaryVariant = Yellow800,
onSecondary = Color.Black,
onSurface = Color.Black,
onBackground = Color.Black,
error = Red800,
onError = Color.White
)
使用看來很簡(jiǎn)單瞭空,特別想C++里面的結(jié)構(gòu)提模软,其實(shí)就是兩個(gè)全局變量
封裝自己的字體等樣式排版躺涝,val JetchatTypography---Typography
特別接近CSS 有這個(gè)感覺沒厨钻,好像高級(jí)CSS也是面向?qū)ο螅救藢?duì)網(wǎng)頁(yè)不是很熟坚嗜。
學(xué)習(xí)到定義形狀夯膀,三個(gè)Shapes
val JetchatShapes = Shapes(
small = RoundedCornerShape(50),
medium = RoundedCornerShape(8.dp),
large = RoundedCornerShape(0.dp)
)
看似有電生疏,我們沒有做東西而已苍蔬。
系統(tǒng)MaterialTheme
定義好了參數(shù)诱建,我們自定義傳入就好
接下來,我們要到過來银室,向上層看涂佃。
JetchatTheme 組合傳入的就是JetchatDrawer
上篇文章提到過励翼。
封裝的就是這個(gè)布局和點(diǎn)擊事件 onProfileClicked,onChatClicked
粗略的看 Spacer 定義了layout布局傳入Modifier
類似Android傳統(tǒng)辜荠,定義Header DawerHeader()---組合Row兩個(gè)Image
運(yùn)行項(xiàng)目會(huì)看到一個(gè)分割線 Divider(),
DrawerItemHeader 定義標(biāo)題頭 Chats
接下來定義兩個(gè)ChatItem汽抚,包括點(diǎn)擊事件,就不看封裝源碼伯病。
DrawerItemHeader 標(biāo)題頭
接下來定義兩個(gè)ProfileItem 組合控件造烁。
繼續(xù)向上層回溯看。
JetchatScoffold里面 定義跳轉(zhuǎn)用的Navigation午笛,NavController
內(nèi)容惭蟋,用View Binding結(jié)合inflate出XML布局
// Inflate the XML layout using View Binding:
val bindingRef = remember { Ref<ViewBinding>() }
val currentView = LocalView.current
AndroidViewBinding({ inflater, parent, attachToParent ->
if (bindingRef.value == null) {
val binding: ViewBinding =
ContentMainBinding.inflate(inflater, parent, attachToParent)
bindingRef.value = binding
binding.root.compositionContext =
currentView.findViewTreeCompositionContext()
}
bindingRef.value as ViewBinding
})
我們注意到remember
記錄值用的,可以理解緩存药磺。
還有很多地方告组,看的不是很清晰,整體來看癌佩,大致整個(gè)小項(xiàng)目木缝,還是很簡(jiǎn)單。