我正在尝试使用 jetpack compose 中的 observeAsState 从 LiveData 获取值,但我收到一个奇怪的错误
类型 'State<List?>' 没有方法 'getValue(Nothing?, KProperty<*>)',因此它不能作为委托
@Composable
fun UserScreen(userViewModel:UserViewModel){
val items: List<User> by userViewModel.fetchUserList.observeAsState()
UserList(userList = items)
}
Run Code Online (Sandbox Code Playgroud)
class UserViewModel: ViewModel() {
private val dataSource = UserDataSource()
val fetchUserList = liveData {
emit(dataSource.dummyUserList)
}
}
Run Code Online (Sandbox Code Playgroud) 我试图在单击工具栏操作时显示 Toast 消息,但出现此错误
@composable 调用只能在 @composable 函数的上下文中发生
代码:
@Composable
fun Toolbar() {
TopAppBar(title = { Text(text = "Jetpack Compose") }, navigationIcon = {
IconButton(onClick = {}) {
Icon(Icons.Filled.Menu)
}
}, actions = {
IconButton(onClick = {
showMessage(message = "test")
}) {
Icon(vectorResource(id = R.drawable.ic_baseline_save_24))
}
})
}
@Preview
@Composable
fun ToolbarPreview(){
Toolbar()
}
@Composable
fun showMessage(message:String){
Toast.makeText(ContextAmbient.current, message, Toast.LENGTH_SHORT).show()
}
Run Code Online (Sandbox Code Playgroud) 我有两个活动,一个包含登录过程的所有片段,另一个包含主应用程序的所有片段。
假设我想从 Activity1(包含登录的所有导航图)导航到 Activity2(包含主应用程序的所有导航图)
class LoginActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
}
fun goToMainActivity(){
startActivity(Intent(this,MainActivity::class.java))
finish()
}
}
Run Code Online (Sandbox Code Playgroud)
这里我调用方法 goToMainActivity()
class LoginFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_login,container,false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
btn_go.setOnClickListener {
// call the method goToMainActivity() to kill all fragments contained by that Activity and move foward to MainActivity with another nav_graph
}
}
} …Run Code Online (Sandbox Code Playgroud) 这就是我正在尝试做的。
ArrayList在 Fragment 内设置对象 FragmentActivity
容器内的观察者获取该数组(承载所有片段的活动)所以,我所做的是以下。
首先,我SharedViewModel从我将设置的位置创建并从中获取数据:
class SharedViewModel: ViewModel() {
var personArrayObj:MutableLiveData<ArrayList<Person>> = MutableLiveData()
fun setPersonArray(personArray:ArrayList<Person>){
personArrayObj.value = personArray
}
val getPersonArray:LiveData<ArrayList<Person>>
get() = personArrayObj
}
Run Code Online (Sandbox Code Playgroud)
现在,我ViewModel在MainActivity承载所有片段创建的内部实例化它,因此,我可以ArrayData从任何 Fragment 集合中获取它:
class MainActivity: FragmentActivity(){
private lateinit var viewModel:SharedViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)
viewModel.getPersonArray.observe(this, Observer { it:ArrayList<Person>
Log.d("Array:",""+it)
})
}
}
Run Code Online (Sandbox Code Playgroud)
然后我需要做的最后一件事是从我想要的任何 Fragment 设置该 Array 的值,然后如果该值发生更改,将触发主机 Activity,因此,要做到这一点,我只需viewModel.setValue(personArray)在我想要的Fragment 上做一个.
因此,在我删除 API 中的特定主题后,它会向我抛出此错误消息
deleteTopic 为 null,但响应正文类型被声明为非 null
该主题已成功删除,但在我的客户端中,此响应以某种方式在我的 catch 块中解析
@DELETE("topics/{id}")
suspend fun deleteTopic(@Path("id") id:String)
Run Code Online (Sandbox Code Playgroud)
override suspend fun deleteTopic(id: String): Resource<Unit> {
return Resource.Success(RetrofitClient.webservice.deleteTopic(id))
}
Run Code Online (Sandbox Code Playgroud)
fun deleteTopic(id:String) = liveData(Dispatchers.IO) {
emit(Resource.Loading())
try {
emit(repo.deleteTopic(id))
}catch (e:Exception){
emit(Resource.Failure(e))
}
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,我成功删除了服务器中的主题,但是当它返回到我的客户端时,它会转到 catch 并返回我上面提到的这个异常,响应是 204 not content,但是我该如何修复此响应成功地告诉我这个操作是否正确完成?
我很困惑,我已经在 github 上读到我必须返回Response<Unit>,但我仍然困惑为什么我应该这样做,它还说 taht 返回将阻止我的 4xx 返回代码被抛出
android mvvm kotlin retrofit android-architecture-components
因此,我实现了一个惰性列来处理食谱元素列表,问题是它不平滑滚动,如果我快速滚动它会口吃,直到最后一个元素出现并且不平滑滚动。
这是我这边的错误还是我需要添加其他内容?
data class Recipe(
@DrawableRes val imageResource: Int,
val title: String,
val ingredients: List<String>
)
val recipeList = listOf(
Recipe(R.drawable.header,"Cake1", listOf("Cheese","Sugar","water")),
Recipe(R.drawable.header,"Cake2", listOf("Cheese1","Sugar1","Vanilla")),
Recipe(R.drawable.header,"Cake3", listOf("Bread","Sugar2","Apple")))
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RecipeList(recipeList = recipeList)
}
}
}
@Composable
fun RecipeCard(recipe:Recipe){
val image = imageResource(R.drawable.header)
Surface(shape = RoundedCornerShape(8.dp),elevation = 8.dp,modifier = Modifier.padding(8.dp)) {
Column(modifier = Modifier.padding(16.dp)) {
val imageModifier = Modifier.preferredHeight(150.dp).fillMaxWidth().clip(shape = RoundedCornerShape(8.dp))
Image(asset = image,modifier = imageModifier,contentScale = ContentScale.Crop)
Spacer(modifier = Modifier.preferredHeight(16.dp)) …Run Code Online (Sandbox Code Playgroud) 最近我一直在努力让 jetpack compose 运行......我已经遵循了所有示例代码,下载了金丝雀等等,但是 1.4.0 插件对我不起作用,我遇到了编译问题
这些是我的 gradle 文件
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.4.0"
ext.compose_version = '1.0.0-alpha01'
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.2.0-alpha08"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
Run Code Online (Sandbox Code Playgroud)
和
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
applicationId "com.example.jetexample"
minSdkVersion 21
targetSdkVersion …Run Code Online (Sandbox Code Playgroud) 有没有办法调整文本以始终根据固定高度调整大小?
我有一个固定高度的列,里面的文本应该总是适合
Column(modifier = Modifier.height(150.dp).padding(8.dp)) {
Text("My really long long long long long text that needs to be resized to the height of this Column")
}
Run Code Online (Sandbox Code Playgroud) 我正在使用 MergeAdapter(又名 ConcatAdapter)
https://medium.com/androiddevelopers/merge-adapters-sequentially-with-mergeadapter-294d2942127a
但我需要做的是,第一个适配器应显示网格布局,第二个适配器应显示线性布局,所以,如果我这样做
val headerAdapter = HeaderAdapter(requireContext(), Header("TestHeader"))
val dividerViewAdapter = DividerViewAdapter(requireContext())
val animalAdapter = DividerViewAdapter(requireContext(),DataSource.animalList) // -> this should be shown as a GridLayout
val mergeAdapter = MergeAdapter(headerAdapter,dividerViewAdapter,animalAdapter)
test_rv.layoutManager = LinearLayoutManager(requireContext())
test_rv.adapter = mergeAdapter
Run Code Online (Sandbox Code Playgroud)
现在这段代码工作正常,但由于它有一个 Linearlayoutmanager,所有内容都将显示为 LinearLayout,其中我的 AnimalAdapter 将不会按我想要的方式显示。
无论如何,是否可以为不同的适配器设置不同的布局管理器,以按照我想要的方式显示数据?
android android-adapter android-fragments kotlin android-recyclerview
我试图理解为什么我的 SnackBar 没有第二次显示,我正在从我的可组合项传播小吃栏消息和错误布尔值,我正在获取这些数据并发出单个小吃栏,但它第一次工作,而不是第二次即使我将消息设置为空,也会显示相同的消息。
当我进入注册屏幕时,如果电子邮件已存在于数据库中,我会发出一条错误消息,那么如果我再次触发相同的消息,则不会发生任何事情,并且不会出现小吃栏,有什么想法吗?
setContent {
var snackBarMessage: String? by remember { mutableStateOf(null) }
var isError by remember { mutableStateOf(false) }
val snackbarHostState = remember { SnackbarHostState() }
CryptoTheme {
Scaffold(
scaffoldState = scaffoldState,
snackbarHost = {
SnackbarHost(hostState = snackbarHostState) { data ->
Snackbar(
snackbarData = data,
backgroundColor = if (!isError) GreenProfit else Color.Red,
contentColor = Color.White
)
}
},
bottomBar = { BottomBarNavigation(navController = navController) },
backgroundColor = Color.Black
) {
NavigationGraph(
modifier = Modifier.padding(bottom = it.calculateBottomPadding()),
navController …Run Code Online (Sandbox Code Playgroud) android ×10
kotlin ×10
mvvm ×2
android-architecture-components ×1
android-architecture-navigation ×1
fragment ×1
navigation ×1
retrofit ×1