parent
3bcab0cb2e
commit
014d4ae16c
@ -0,0 +1,192 @@ |
||||
package com.gyf.csams |
||||
|
||||
import androidx.compose.foundation.Canvas |
||||
import androidx.compose.foundation.background |
||||
import androidx.compose.foundation.layout.* |
||||
import androidx.compose.material.Text |
||||
import androidx.compose.runtime.Composable |
||||
import androidx.compose.ui.Alignment |
||||
import androidx.compose.ui.Modifier |
||||
import androidx.compose.ui.draw.rotate |
||||
import androidx.compose.ui.graphics.Color |
||||
import androidx.compose.ui.graphics.drawscope.rotate |
||||
import androidx.compose.ui.text.SpanStyle |
||||
import androidx.compose.ui.text.buildAnnotatedString |
||||
import androidx.compose.ui.text.withStyle |
||||
import androidx.compose.ui.tooling.preview.Preview |
||||
import androidx.compose.ui.unit.Dp |
||||
import androidx.compose.ui.unit.dp |
||||
import androidx.compose.ui.unit.sp |
||||
|
||||
@Composable |
||||
fun MyBox(modifier: Modifier, canvasSize:Dp, canvasD:Float, content: @Composable BoxScope.() -> Unit){ |
||||
Box(modifier = modifier,contentAlignment = Alignment.Center){ |
||||
Canvas(modifier = Modifier.size(canvasSize)) { |
||||
rotate(canvasD){ |
||||
drawRect(color = Color.Cyan) |
||||
} |
||||
} |
||||
content() |
||||
} |
||||
} |
||||
|
||||
@Composable |
||||
fun BoxSetSize(degrees:Float=0F, content: @Composable BoxScope.() -> Unit){ |
||||
MyBox(modifier = Modifier |
||||
.height(300.dp) |
||||
.fillMaxWidth() |
||||
.background(Color.Gray) |
||||
.rotate(degrees = degrees), canvasSize = 200.dp, canvasD = 45F,content = content |
||||
) |
||||
} |
||||
|
||||
@Composable |
||||
fun BoxFillSize(degrees:Float=0F, content: @Composable BoxScope.() -> Unit){ |
||||
MyBox( |
||||
modifier = Modifier |
||||
.fillMaxSize() |
||||
.background(Color.LightGray), canvasSize = 100.dp, canvasD = 80F,content = content |
||||
) |
||||
} |
||||
|
||||
//@Preview |
||||
@Composable |
||||
fun TestPreview(){ |
||||
Column(modifier = Modifier.fillMaxSize()){ |
||||
BoxSetSize { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("前置子布局固定尺寸") |
||||
} |
||||
}) |
||||
} |
||||
|
||||
BoxFillSize { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("后置子布局使用") |
||||
} |
||||
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){ |
||||
append("fillMaxSize修饰符") |
||||
} |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("填充父项允许的所有可用空间") |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
//@Preview |
||||
@Composable |
||||
fun TestPreview2(){ |
||||
Column(modifier = Modifier.fillMaxSize()){ |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("如果使用示例1方法是") |
||||
} |
||||
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){ |
||||
append("无法实现前置子布局填充父项所有可用空间,后置子布局固定尺寸") |
||||
} |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("因为前置布局已经填充父项允许的所有可用空间,后置子布局没有剩余空间可用") |
||||
} |
||||
|
||||
}) |
||||
|
||||
BoxFillSize { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("前置子布局填充父项允许的所有可用空间") |
||||
} |
||||
}) |
||||
} |
||||
|
||||
BoxSetSize { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("后置子布局固定尺寸") |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
//@Preview |
||||
@Composable |
||||
fun TestPreview3(){ |
||||
Column(modifier = Modifier |
||||
.fillMaxSize()) { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("折衷方案是通过父项旋转180°实现,子项分别旋转180°复位可") |
||||
} |
||||
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){ |
||||
append("实现前置子布局填充父项所有可用空间,后置子布局固定尺寸") |
||||
} |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append(",除了旋转,应该有更好的实现方式?") |
||||
} |
||||
}) |
||||
Column(modifier = Modifier.rotate(180F)){ |
||||
BoxSetSize(degrees = 180F) { |
||||
Text(buildAnnotatedString { |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("前置子布局固定尺寸,通过旋转和后置子布局对调位置") |
||||
} |
||||
}) |
||||
} |
||||
BoxFillSize(degrees = 180F) { |
||||
Text(buildAnnotatedString { |
||||
|
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("后置子布局使用") |
||||
} |
||||
withStyle(style = SpanStyle(color= Color.Red,fontSize = 30.sp)){ |
||||
append("fillMaxSize修饰符") |
||||
} |
||||
withStyle(style = SpanStyle(fontSize = 30.sp)){ |
||||
append("填充父项允许的所有可用空间,通过旋转和前置子布局对调位置") |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
//@Preview |
||||
@Composable |
||||
fun TestPreview4(){ |
||||
Column(modifier = Modifier |
||||
.fillMaxSize()) { |
||||
|
||||
|
||||
MyBox(modifier = Modifier |
||||
.fillMaxWidth() |
||||
.fillMaxHeight() |
||||
.background(Color.Gray), canvasSize = 100.dp, canvasD = 80F){ |
||||
Text(text = "Box1") |
||||
} |
||||
|
||||
MyBox(modifier = Modifier |
||||
.height(300.dp) |
||||
.fillMaxWidth() |
||||
.background(Color.Gray), canvasSize = 200.dp, canvasD = 45F){ |
||||
Text(text = "Box2") |
||||
} |
||||
} |
||||
} |
||||
|
||||
@Preview |
||||
@Composable |
||||
fun TestPreview5(){ |
||||
|
||||
Column { |
||||
Row { |
||||
|
||||
} |
||||
|
||||
} |
||||
} |
||||
|
@ -1,19 +1,100 @@ |
||||
package com.gyf.csams |
||||
|
||||
import android.app.Application |
||||
import android.content.res.Resources |
||||
import android.graphics.Bitmap |
||||
import android.graphics.BitmapFactory |
||||
import android.util.LruCache |
||||
import androidx.compose.ui.graphics.ImageBitmap |
||||
import androidx.compose.ui.graphics.asImageBitmap |
||||
import com.gyf.csams.uikit.BackgroundImage |
||||
import com.orhanobut.logger.AndroidLogAdapter |
||||
import com.orhanobut.logger.DiskLogAdapter |
||||
import com.orhanobut.logger.Logger |
||||
|
||||
class APP : Application() { |
||||
|
||||
private lateinit var memoryCache: LruCache<BackgroundImage, Bitmap> |
||||
// Get max available VM memory, exceeding this amount will throw an |
||||
// OutOfMemory exception. Stored in kilobytes as LruCache takes an |
||||
// int in its constructor. |
||||
private val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt() |
||||
// Use 1/8th of the available memory for this memory cache. |
||||
val cacheSize = maxMemory / 8 |
||||
|
||||
fun getImage(image: BackgroundImage, reqWidth: Int, reqHeight: Int): ImageBitmap { |
||||
val bitmap=memoryCache.get(image) |
||||
return if(bitmap==null){ |
||||
Logger.i("reqWidth=$reqWidth,reqHeight=$reqHeight") |
||||
val cacheValue= decodeSampledBitmapFromResource(res = resources,image.id,reqWidth=reqWidth,reqHeight=reqHeight) |
||||
memoryCache.put(image, cacheValue) |
||||
Logger.i("添加缓存:${image}") |
||||
cacheValue.asImageBitmap() |
||||
}else{ |
||||
Logger.i("从缓存读取:${image}") |
||||
bitmap.asImageBitmap() |
||||
} |
||||
} |
||||
|
||||
private fun decodeSampledBitmapFromResource( |
||||
res: Resources, |
||||
resId: Int, |
||||
reqWidth: Int, |
||||
reqHeight: Int |
||||
): Bitmap { |
||||
// First decode with inJustDecodeBounds=true to check dimensions |
||||
return BitmapFactory.Options().run { |
||||
inJustDecodeBounds = true |
||||
BitmapFactory.decodeResource(res, resId, this) |
||||
|
||||
// Calculate inSampleSize |
||||
inSampleSize = calculateInSampleSize(this, reqWidth, reqHeight) |
||||
|
||||
// Decode bitmap with inSampleSize set |
||||
inJustDecodeBounds = false |
||||
|
||||
BitmapFactory.decodeResource(res, resId, this) |
||||
} |
||||
} |
||||
|
||||
private fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int { |
||||
// Raw height and width of image |
||||
val (height: Int, width: Int) = options.run { outHeight to outWidth } |
||||
var inSampleSize = 1 |
||||
|
||||
if (height > reqHeight || width > reqWidth) { |
||||
|
||||
val halfHeight: Int = height / 2 |
||||
val halfWidth: Int = width / 2 |
||||
|
||||
// Calculate the largest inSampleSize value that is a power of 2 and keeps both |
||||
// height and width larger than the requested height and width. |
||||
while (halfHeight / inSampleSize >= reqHeight && halfWidth / inSampleSize >= reqWidth) { |
||||
inSampleSize *= 2 |
||||
} |
||||
} |
||||
|
||||
return inSampleSize |
||||
} |
||||
|
||||
override fun onCreate() { |
||||
super.onCreate() |
||||
|
||||
memoryCache = object : LruCache<BackgroundImage, Bitmap>(cacheSize) { |
||||
|
||||
override fun sizeOf(key: BackgroundImage, bitmap: Bitmap): Int { |
||||
// The cache size will be measured in kilobytes rather than |
||||
// number of items. |
||||
return bitmap.byteCount / 1024 |
||||
} |
||||
} |
||||
|
||||
//初始化日志 |
||||
Logger.addLogAdapter(AndroidLogAdapter()) |
||||
Logger.addLogAdapter(DiskLogAdapter()) |
||||
|
||||
Logger.i("${BuildConfig.APP_NAME}启动") |
||||
|
||||
|
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
package com.gyf.csams.association.model |
||||
|
||||
import android.net.Uri |
||||
import androidx.lifecycle.LiveData |
||||
import androidx.lifecycle.MutableLiveData |
||||
import androidx.lifecycle.ViewModel |
||||
import com.gyf.csams.uikit.StringForm |
||||
|
||||
|
||||
data class Image(val uri:Uri,val createTime:Long,val size:Long) |
||||
|
||||
class RegAssociationViewModel : ViewModel() { |
||||
|
||||
val frameDesc="社团注册资料" |
||||
|
||||
val name= StringForm(formDesc = "社团名称",textLength = 5) |
||||
val desc = StringForm(formDesc = "社团简介",textLength = 30) |
||||
|
||||
|
||||
val _picture=MutableLiveData<Uri>() |
||||
val picture:LiveData<Uri> =_picture |
||||
|
||||
val piciurePlaceHolder="请上传图片" |
||||
|
||||
val errorPicture="图片加载失败,请联系管理员" |
||||
|
||||
val deninedPermission="拒绝授权" |
||||
|
||||
val register="注册" |
||||
val back="返回" |
||||
|
||||
fun setPicture(uri: Uri){ |
||||
_picture.value=uri |
||||
} |
||||
|
||||
/** |
||||
* TODO 注册社团 |
||||
* |
||||
* @param callback |
||||
*/ |
||||
fun register(callback: (value: String) -> Unit){ |
||||
callback("功能尚未实现,敬请期待") |
||||
} |
||||
|
||||
} |
@ -0,0 +1,258 @@ |
||||
package com.gyf.csams.association.ui |
||||
|
||||
import android.Manifest |
||||
import android.app.Activity |
||||
import android.content.Context |
||||
import android.content.Intent |
||||
import android.content.pm.PackageManager |
||||
import android.graphics.BitmapFactory |
||||
import android.net.Uri |
||||
import android.os.Bundle |
||||
import android.provider.MediaStore |
||||
import androidx.activity.ComponentActivity |
||||
import androidx.activity.compose.rememberLauncherForActivityResult |
||||
import androidx.activity.compose.setContent |
||||
import androidx.activity.result.ActivityResultLauncher |
||||
import androidx.activity.result.contract.ActivityResultContracts |
||||
import androidx.compose.foundation.Image |
||||
import androidx.compose.foundation.background |
||||
import androidx.compose.foundation.border |
||||
import androidx.compose.foundation.layout.* |
||||
import androidx.compose.material.* |
||||
import androidx.compose.runtime.Composable |
||||
import androidx.compose.runtime.getValue |
||||
import androidx.compose.runtime.livedata.observeAsState |
||||
import androidx.compose.ui.Alignment |
||||
import androidx.compose.ui.Modifier |
||||
import androidx.compose.ui.graphics.Color |
||||
import androidx.compose.ui.graphics.asImageBitmap |
||||
import androidx.compose.ui.platform.LocalContext |
||||
import androidx.compose.ui.res.painterResource |
||||
import androidx.compose.ui.tooling.preview.Preview |
||||
import androidx.compose.ui.unit.dp |
||||
import androidx.core.content.ContextCompat |
||||
import androidx.lifecycle.viewmodel.compose.viewModel |
||||
import com.gyf.csams.R |
||||
import com.gyf.csams.association.model.RegAssociationViewModel |
||||
import com.gyf.csams.uikit.* |
||||
import com.gyf.csams.uikit.theme.CSAMSTheme |
||||
import com.orhanobut.logger.Logger |
||||
|
||||
|
||||
/** |
||||
* 注册社团 |
||||
* |
||||
*/ |
||||
class RegAssociationActivity: ComponentActivity(){ |
||||
override fun onCreate(savedInstanceState: Bundle?) { |
||||
super.onCreate(savedInstanceState) |
||||
setContent { |
||||
CSAMSTheme { |
||||
Body() |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
@Composable |
||||
fun Body(model:RegAssociationViewModel= viewModel()){ |
||||
val scaffoldState = rememberScaffoldState() |
||||
Scaffold(scaffoldState = scaffoldState) { |
||||
Surface(color = MaterialTheme.colors.background) { |
||||
MainFrame(background = { Background(BackgroundImage.reg_association,alpha = 0.7F) }) { |
||||
Spacer( |
||||
modifier = Modifier |
||||
.weight(0.1F) |
||||
) |
||||
Title(model = model) |
||||
Name(model = model) |
||||
Desc( |
||||
model = model, modifier = Modifier |
||||
.weight(0.1F) |
||||
.fillMaxWidth() |
||||
) |
||||
Spacer(modifier = Modifier.weight(0.05F)) |
||||
Logo( |
||||
model = model, modifier = Modifier |
||||
.weight(0.2F) |
||||
.fillMaxWidth() |
||||
) |
||||
Spacer(modifier = Modifier.weight(0.05F)) |
||||
BottomButton(modifier = Modifier.fillMaxWidth()) |
||||
Spacer(modifier = Modifier.weight(0.05F)) |
||||
|
||||
ShowSnackbar(scaffoldState = scaffoldState) |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
//@Composable |
||||
fun PermissionHandle(context: Context, launcher: ActivityResultLauncher<String>,onGranted:()->Unit){ |
||||
// Check permission |
||||
when (PackageManager.PERMISSION_GRANTED) { |
||||
ContextCompat.checkSelfPermission( |
||||
context, |
||||
Manifest.permission.READ_EXTERNAL_STORAGE |
||||
) -> { |
||||
// Some works that require permission |
||||
onGranted() |
||||
} |
||||
else -> { |
||||
// Asking for permission |
||||
launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 社团Logo |
||||
* |
||||
* @param modifier |
||||
*/ |
||||
@Composable |
||||
fun Logo(model:RegAssociationViewModel= viewModel(),modifier: Modifier) { |
||||
val photoIntent=Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI) |
||||
photoIntent.type = "image/*" |
||||
val uri:Uri? by model.picture.observeAsState() |
||||
|
||||
val resultLauncher=rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) { |
||||
when(it.resultCode){ |
||||
Activity.RESULT_OK->{ |
||||
Logger.i("uri=${it.data?.data}") |
||||
it.data?.data?.let { it1 -> model.setPicture(it1) } |
||||
} |
||||
} |
||||
} |
||||
|
||||
val loadPicture={ |
||||
//model.loadPicture(context) |
||||
resultLauncher.launch(photoIntent) |
||||
} |
||||
|
||||
val launcher = rememberLauncherForActivityResult( |
||||
ActivityResultContracts.RequestPermission() |
||||
) { isGranted: Boolean -> |
||||
if (isGranted) { |
||||
// Permission Accepted: Do something |
||||
loadPicture() |
||||
} else { |
||||
// Permission Denied: Do something |
||||
Logger.w(model.deninedPermission) |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
val context= LocalContext.current |
||||
|
||||
Box(contentAlignment = Alignment.Center,modifier = modifier) { |
||||
Row(verticalAlignment = Alignment.CenterVertically, |
||||
horizontalArrangement = Arrangement.Center,modifier = Modifier |
||||
.fillMaxSize() |
||||
.border(width = 1.dp, color = Color.Black)) { |
||||
|
||||
if (uri == null) { |
||||
OutlinedButton(onClick = { |
||||
when (PackageManager.PERMISSION_GRANTED) { |
||||
ContextCompat.checkSelfPermission( |
||||
context, |
||||
Manifest.permission.READ_EXTERNAL_STORAGE |
||||
) -> { |
||||
// Some works that require permission |
||||
loadPicture() |
||||
} |
||||
else -> { |
||||
// Asking for permission |
||||
launcher.launch(Manifest.permission.READ_EXTERNAL_STORAGE) |
||||
} |
||||
} |
||||
}) { |
||||
Text(text = model.piciurePlaceHolder) |
||||
} |
||||
} else { |
||||
uri.let { |
||||
if(it!=null){ |
||||
Row { |
||||
Image(bitmap = BitmapFactory.decodeStream(context.contentResolver.openInputStream(it)) |
||||
.asImageBitmap(), contentDescription = null) |
||||
IconButton(onClick = { |
||||
loadPicture() |
||||
}) { |
||||
Image(painter = painterResource(id = R.drawable.ic_exchange_rate), contentDescription = null) |
||||
} |
||||
} |
||||
|
||||
|
||||
}else{ |
||||
Text(text = model.errorPicture) |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
} |
||||
|
||||
@Composable |
||||
fun BottomButton(modifier: Modifier=Modifier,scaffoldModel: ScaffoldModel= viewModel(),model:RegAssociationViewModel= viewModel()){ |
||||
val context= LocalContext.current as RegAssociationActivity |
||||
Row(modifier = modifier,horizontalArrangement = Arrangement.Center) { |
||||
OutlinedButton(onClick = { |
||||
model.register { scaffoldModel.update(it) } |
||||
},modifier = Modifier.background(color = MaterialTheme.colors.primary)) { |
||||
Text(text = model.register) |
||||
} |
||||
Spacer(modifier = Modifier.width(10.dp)) |
||||
OutlinedButton(onClick = { |
||||
context.onBackPressed() |
||||
},modifier = Modifier.background(color = MaterialTheme.colors.secondary)) { |
||||
Text(text = model.back) |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 菜单标题 |
||||
* |
||||
*/ |
||||
@Composable |
||||
fun Title(model:RegAssociationViewModel= viewModel()){ |
||||
Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.Center) { |
||||
Text(text = model.frameDesc,style = MaterialTheme.typography.h4) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 社团名称 |
||||
* @param model |
||||
*/ |
||||
@Composable |
||||
fun Name(model:RegAssociationViewModel= viewModel()){ |
||||
BaseTextField(form = model.name,singeLine = true,modifier = Modifier.fillMaxWidth()) |
||||
} |
||||
|
||||
/** |
||||
* 社团简介 |
||||
* @param model |
||||
*/ |
||||
@Composable |
||||
fun Desc(model:RegAssociationViewModel= viewModel(),modifier:Modifier){ |
||||
BaseTextField(form = model.desc,modifier = modifier) |
||||
} |
||||
|
||||
|
||||
@Preview |
||||
@Composable |
||||
fun NamePreview(){ |
||||
val model=RegAssociationViewModel() |
||||
Body(model=model) |
||||
|
||||
} |
@ -0,0 +1,41 @@ |
||||
package com.gyf.csams.uikit |
||||
|
||||
import androidx.lifecycle.LiveData |
||||
import androidx.lifecycle.MutableLiveData |
||||
import androidx.lifecycle.ViewModel |
||||
import com.orhanobut.logger.Logger |
||||
|
||||
interface FormLength{ |
||||
val nameLengthError:String |
||||
} |
||||
|
||||
abstract class FormName<T>(val formDesc:String){ |
||||
protected val _formValue= MutableLiveData<T>() |
||||
val formValue: LiveData<T> = _formValue |
||||
val formPlaceholder="请输入$formDesc" |
||||
|
||||
abstract fun onChange(value:T) |
||||
} |
||||
|
||||
open class StringForm(formDesc: String, val textLength: Int) : FormName<String>(formDesc = formDesc), |
||||
FormLength { |
||||
override val nameLengthError="${formDesc}不能超过最大长度$textLength" |
||||
|
||||
override fun onChange(value: String) { |
||||
if(value.length>textLength){ |
||||
_formValue.value=value.slice(IntRange(0,textLength-1)) |
||||
}else{ |
||||
_formValue.value=value |
||||
} |
||||
Logger.i("${formDesc}更新值:${_formValue.value}") |
||||
} |
||||
} |
||||
|
||||
class ScaffoldModel:ViewModel(){ |
||||
private val _message=MutableLiveData<String>() |
||||
val message:LiveData<String> = _message |
||||
|
||||
fun update(message:String?=null){ |
||||
_message.value=message |
||||
} |
||||
} |
@ -1,4 +1,4 @@ |
||||
package com.gyf.csams.ui.theme |
||||
package com.gyf.csams.uikit.theme |
||||
|
||||
import androidx.compose.ui.graphics.Color |
||||
|
@ -1,4 +1,4 @@ |
||||
package com.gyf.csams.ui.theme |
||||
package com.gyf.csams.uikit.theme |
||||
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape |
||||
import androidx.compose.material.Shapes |
@ -1,4 +1,4 @@ |
||||
package com.gyf.csams.ui.theme |
||||
package com.gyf.csams.uikit.theme |
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme |
||||
import androidx.compose.material.MaterialTheme |
@ -1,4 +1,4 @@ |
||||
package com.gyf.csams.ui.theme |
||||
package com.gyf.csams.uikit.theme |
||||
|
||||
import androidx.compose.material.Typography |
||||
import androidx.compose.ui.text.TextStyle |
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue