在Compose之前,我使用LiveDataUI组件和数据之间的连接,当数据类型LiveData发生变化时,UI组件将被更新。当我使用 Compose 后,我被告知这MutableState<T>就像LiveData,但它是在 Compose 中使用的。
在下面的代码中,Aval count是MutableState<T>在第1部分中输入的,因此当我单击第3部分中的按钮时,第2部分中的文本将被更改。上面的过程很容易理解,就像我之前使用LiveData一样。
但是"3 times clicked"当我点击按钮3次时就会显示,我不明白为什么会启动第4部分,你知道if (count.value == 3)...这是一个逻辑代码,它与任何UI组件无关。
1:是否意味着系统会观察与 相关的所有代码val count,并在count.value发生变化时自动运行它?
2:当我点击第3部分中的按钮时,第5部分总是会重新启动吗?
代码A
@Composable
fun Counter() {
Column {
//Part 1
val count = remember { mutableStateOf(0) }
//Part 2
Text(
text = "I've been clicked ${count.value} times",
)
//Part 3
Button(onClick = { count.value++ }) {
Text("Click me")
}
//Part 4
if (count.value == …Run Code Online (Sandbox Code Playgroud) 代码 A 来自此处的官方示例项目。
定义InterestsViewModel为uiStateas ,并在 Composable 函数中将StateFlow其转换为State<T>by 。collectAsState()rememberTabContent
我很奇怪为什么作者不直接在中 定义uiState为,所以我写了代码B。State<T>InterestsViewModel
代码B可以编译,并且可以运行,但是屏幕上没有任何显示,代码B有什么问题?
代码A
data class InterestsUiState(
val topics: List<InterestSection> = emptyList(),
val people: List<String> = emptyList(),
val publications: List<String> = emptyList(),
val loading: Boolean = false,
)
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
// UI state exposed to the UI
private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
val uiState: StateFlow<InterestsUiState> = …Run Code Online (Sandbox Code Playgroud) uiState中,代码A和代码B可以根据流量的最新值自动更新UI MutableStateFlow。 ViewModel()
handleMeter.uiState.collectAsState()1\xef\xbc\x9a Kotlin和Kotlin之间有什么区别remember { handleMeter.uiState }?
2\xef\xbc\x9aCode C 是错误的,我不能用 包裹handleMeter.uiState.collectAsState()起来remember,为什么?如何记住流量的最新值?
代码A
\n@Composable\nfun Greeting(handleMeter: HandleMeter,lifecycleScope: LifecycleCoroutineScope) {\n Column(\n modifier = Modifier.fillMaxSize()\n \n ) { \n var dataInfo = handleMeter.uiState.collectAsState()\n Text(text = "My ${dataInfo.value}")\n }\n ..\n}\n\nclass HandleMeter: ViewModel() {\n val uiState = MutableStateFlow<Int>(10)\n ...\n}\nRun Code Online (Sandbox Code Playgroud)\n代码B
\n@Composable\nfun Greeting(handleMeter: HandleMeter,lifecycleScope: LifecycleCoroutineScope) {\n Column(\n modifier = Modifier.fillMaxSize()\n \n ) { \n var dataInfo = remember { handleMeter.uiState }\n …Run Code Online (Sandbox Code Playgroud) 通常,我可以使用以下代码来获取图像的宽度,但它需要API级别16.如何在android:minSdkVersion ="8"时获取图像的高度和宽度
Cursor cur = mycontext.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null,
MediaStore.Images.Media._ID + "=?", new String[] { id }, "");
string width=cur.getString(cur.getColumnIndex(MediaStore.Images.Media.HEIGHT));
Run Code Online (Sandbox Code Playgroud) 在下面的布局中,我认为三个控件textTotalTitle,textTotalValue和chAll将定位UI的右侧,但实际上,这三个控件仍然保留在左侧,为什么?
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:background="#DCDCDC"
android:orientation="horizontal" >
<TextView
android:id="@+id/textSMSFilter"
style="@style/myTextAppearance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="4dip"
android:layout_gravity="left|center_vertical"
android:text="@string/filter" >
</TextView>
<Spinner
android:id="@+id/spinnerMsgFolder"
android:layout_width="133dp"
android:layout_height="wrap_content"
android:layout_gravity="left|center_vertical"
android:gravity="center" />
<TextView
android:id="@+id/textTotalTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="right|center_vertical"
android:text="@string/totalAndSelectedTitle" >
</TextView>
<TextView
android:id="@+id/textTotalValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="3dip"
android:paddingRight="2dip"
android:layout_gravity="right|center_vertical"
android:text="0/1" >
</TextView>
<CheckBox
android:id="@+id/chAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|center_vertical"
android:paddingRight="5dip" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud) 我希望获得视频(.mp4)视频文件的持续时间,分辨率,如何在Android中以编程方式执行此操作?我的minSdkVersion是21.
顺便说一句,我可以使用以下代码获取视频的文件大小.
String recVideoPath = Environment.getExternalStorageDirectory() + videoRecordedFileName;
File file = new File(recVideoPath);
long fileVideo = file.length();
Run Code Online (Sandbox Code Playgroud)
谢谢!
我是Kotlin的初学者,以下代码来自网页,val box3是正确的.
我被告知val box1和val box2都是正确的.为什么?
class Box<T>(val value: T)
val box1: Box<Int> = Box<Int>(1)
val box2: Box<Int> = Box(1)
val box3 = Box(1)
Run Code Online (Sandbox Code Playgroud) 我尝试运行以下代码,但代码无法通过编译,我收到错误:
智能转换为'Long'是不可能的,因为'i'是一个可变的属性,可以在这个时候改变
为什么?
class MyClass1(var i: Long?) {
fun change(): Long? {
if (i != null) {
return i + 10L
} else {
return 5L
}
}
}
Run Code Online (Sandbox Code Playgroud)
我用Java编写了代码MyClass2,它可以很好地工作,为什么?
class MyClass2{
private Long i;
public MyClass2(Long k){
i=k;
}
public Long change(){
if (i!=null){
return i+10L;
}else {
return 5L;
}
}
}
Run Code Online (Sandbox Code Playgroud) 我是Kotlin的初学者,以下示例代码来自网页.
我认为Application()是一个类,UIApp继承自Application()类.
但是在Android Studio 3.01中,Application()的提示显示为方法,你可以看到iamge,它让我感到困惑!
Android Studio 3.01中提示的图像
class UIApp : Application() {
companion object {
var instance: UIApp by NotNullSingleValueVar()
}
override fun onCreate() {
super.onCreate()
instance = this
}
class NotNullSingleValueVar<T> {
private var value: T? = null
operator fun getValue(thisRef: Any?, property: KProperty<*>): T =
value ?: throw IllegalStateException("${property.name} not initialized")
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
this.value = if (this.value == null) value
else throw IllegalStateException("${property.name} already initialized")
}
}
}
Run Code Online (Sandbox Code Playgroud) 代码 B 是一个带有单选按钮的自定义 RecyclerView。
代码A中的fun methodA()和fun methodB()中的mCustomAdapter都发生了变化,因此其引用get () = mCustomAdapter.getSelectedIndex()也发生了变化,这意味着val属性mySelectedIndex从不同的地址获取值。
在我看来,val属性无法更改,为什么应用程序不会导致错误?
代码A
private lateinit var mCustomAdapter: CustomAdapter
private val mySelectedIndex get () = mCustomAdapter.getSelectedIndex()
private fun methodA(){
mCustomAdapter= CustomAdapter(allListA)
mRecyclerView.adapter= mCustomAdapter
backup(mySelectedIndex)
}
private fun methodB(){
mCustomAdapter= CustomAdapter(allListB)
mRecyclerView.adapter= mCustomAdapter
restore(mySelectedIndex)
}
Run Code Online (Sandbox Code Playgroud)
代码B
class CustomAdapter (val backupItemList: List<MSetting>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {
val noRecord=-1
private var mSelectedIndex = noRecord
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.item_recyclerview, parent, false)
return ViewHolder(v)
}
fun getSelectedIndex():Int{
return …Run Code Online (Sandbox Code Playgroud)