目前,我正在将我的一个应用程序迁移到 Material Design 3,该应用程序完全使用 Jetpack Compose 用 Kotlin 编写。
在使用 Material Design 2 时,我可以使用下面的代码更改文本的重点。
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
Text(
text = "Hello, world",
style = MaterialTheme.typography.h6,
fontWeight = FontWeight.SemiBold,
)
}
Run Code Online (Sandbox Code Playgroud)
但是,相同的代码不适用于 Material Design 3,并且文本具有默认强调。另外,我在Material Design 3中找不到相关功能。我想知道是否有任何官方方法可以达到相同的效果。
android android-jetpack-compose android-jetpack-compose-text material-you material-design-3
在使用基于视图的系统时,我们可以使用以下代码来协调颜色。
MaterialColors.harmonizeWithPrimary(context, colorToHarmonize)
Run Code Online (Sandbox Code Playgroud)
在完全迁移到 Jetpack Compose 并且所有颜色值都存储在文件中的项目中Color.kt,如何在运行时对颜色应用协调?
android android-jetpack-compose material-you android-jetpack-compose-material3 material3
我最近使用Google推出的Activity Transition API来检测用户何时进出车辆.下面是我用来实现相同的代码.
val intent = Intent(context, ActivityTransitionReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)
transitions.apply {
add(ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build())
add(ActivityTransition.Builder()
.setActivityType(DetectedActivity.IN_VEHICLE)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build())
}
var transitionRequest = ActivityTransitionRequest(transitions)
// myPendingIntent is the instance of PendingIntent where the app receives callbacks.
val task = ActivityRecognition.getClient(context).requestActivityTransitionUpdates(transitionRequest, pendingIntent)
task.addOnSuccessListener {
// Handle success
context.toast("Task added successfully")
}
task.addOnFailureListener {
// Handle error
context.toast("Error adding task")
}
Run Code Online (Sandbox Code Playgroud)
该应用程序工作正常,并在未从最近的应用程序选项卡中删除时接收广播.但是,当应用程序从最近的应用程序选项卡中删除或被系统杀死时,我无法接收广播.我不知道我做错了什么.还有其他方法可以达到同样的目的吗?
我考虑使用前台服务,以便应用程序不被杀死,但后来认为显示永久通知只是为了检测用户活动过渡不是一个好主意.任何帮助将不胜感激.谢谢.
编辑:我已经看到一些应用程序要求特殊权限,例如"忽略电池优化",当获得此权限时,该应用程序似乎始终有效并且不断发送通知.
android broadcastreceiver android-location activity-recognition
我已使用应用内结算库在应用中添加订阅。一切正常,但是我找不到如何获得用户当前有效的订阅?
根据docs,该方法queryPurchaseHistoryAsync将返回用户针对每个SKU进行的最新购买,即使该购买已过期,取消或消费了。因此,我不知道当前的订阅是否处于活动状态。
根据此帖子,如果我们取消订阅,则该订阅仍将被视为当天有效。但是我得到的响应中的订阅已在15天之前被取消。
任何帮助将不胜感激。提前致谢。
android in-app-billing google-play in-app-subscription play-billing-library
我正在使用android studio 2.2预览3发布我的应用程序并生成签名的apk.但是,当我上传apk到谷歌播放时,我收到错误
You uploaded an APK that is not zip aligned. You will need to run a zip align tool on your APK and upload it again.
Run Code Online (Sandbox Code Playgroud)
此外,我试图手动使用zipalign工具,但我得到错误验证失败.
这是我的build.gradle文件
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "blackdogs.newaomsi"
minSdkVersion 16
targetSdkVersion 23
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
zipAlignEnabled true
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}}
Run Code Online (Sandbox Code Playgroud) 我在我的应用程序中使用具有一个活动和两个片段的Jetpack Navigation(片段A也是家庭片段,而片段B可以从片段A导航)。
有一个intent-filter添加到MainActivity如下所示它可以接受纯文本。
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="@string/text_mime_type_text_plain"/>
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)
当用户选择从Android sharesheet我的应用程序,最终目标是通过从接收到的意图的片段B目前数据,我接收到意图在片段A(家庭片段),然后使用NavController导航到片段B使用下面的代码。
private fun checkReceivedIntent() {
val receivedUrlIntent = activity?.intent
val intentAction = receivedUrlIntent?.action
val intentType = receivedUrlIntent?.type
if (intentAction == Intent.ACTION_SEND && intentType != null) {
if (intentType == getString(R.string.text_mime_type_text_plain) ) {
val receivedText = receivedUrlIntent.getStringExtra(Intent.EXTRA_TEXT)
val action = FragmentADirections.actionFragmentAToFragmentB(receivedText)
findNavController().navigate(action)
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题在于,当打开片段B时,按下工具栏的后退按钮或后退箭头(即使多次按下),也不会出现片段A,并且片段B会继续出现。
我不知道我在想什么。当用户从另一个应用程序内的共享表打开该应用程序时,这是打开特定片段的正确方法吗?
编辑
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> …Run Code Online (Sandbox Code Playgroud) android android-fragments android-jetpack android-jetpack-navigation
我的应用程序中有两个屏幕。Paging3第一个屏幕通过使用垂直网格中的库显示设备上的图像列表。现在,当用户单击图像时,我将单击位置传递到第二个屏幕,我在第二个屏幕上使用HorizontalPager伴奏来全屏显示图像。两个屏幕共享相同的 ViewModel 以使用Paging3.
在 HorizontalPager 中显示图像的代码如下所示。
val images: LazyPagingItems<MediaStoreImage> =
viewModel.getImages(initialLoadSize = args.currentImagePosition + 1, pageSize = 50)
.collectAsLazyPagingItems()
val pagerState = rememberPagerState(initialPage = currentImagePosition)
Box(modifier = modifier) {
HorizontalPager(
count = images.itemCount,
state = pagerState,
itemSpacing = 16.dp
) { page ->
ZoomableImage(
modifier = modifier,
imageUri = images[page]?.contentUri
)
}
}
Run Code Online (Sandbox Code Playgroud)
这里,currentImagePosition是在第一个屏幕上单击的图像的索引。我正在设置initialLoadSize确保currentImagePosition + 1分页库已获取要显示的单击图像。
当第二个屏幕打开时,单击的图像将按预期全屏显示。但是,当用户滑动获取下一个图像时,不会加载下一个图像,而是随着50用户进一步滑动而加载带有索引等的图像。
我不确定我在这里缺少什么。任何帮助将不胜感激。
编辑:添加了 ViewModel、存储库和分页代码
视图模型
fun getImages(initialLoadSize: Int = 50): …Run Code Online (Sandbox Code Playgroud) android android-jetpack-compose jetpack-compose-accompanist android-jetpack-compose-pager
我在NestestScrollView中使用Constraint布局,如下所示.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/clProfileFragment"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/appCompatImageView8"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHeight_percent="0.7"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/bg_nature" />
<de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/ivProfileFragment"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:src="@drawable/ic_profile"
android:visibility="visible"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvUserName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:fontFamily="@font/raleway_medium"
android:letterSpacing="0.2"
android:textAlignment="center"
android:textColor="@color/darkBlue"
app:layout_constraintBottom_toBottomOf="@+id/ivProfileFragment"
app:layout_constraintStart_toEndOf="@+id/ivProfileFragment"
app:layout_constraintTop_toTopOf="@+id/ivProfileFragment"
tools:text="Mehul Kanzriya" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/ivCloseProfileFragment"
style="@style/VectorImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_close" />
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:fillViewport="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ivProfileFragment"
app:layout_constraintBottom_toTopOf="@id/button">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="8dp" …Run Code Online (Sandbox Code Playgroud) 我使用viewModelScope在ViewModel其中要求暂停在库函数如下图所示:
视图模型
class DeepFilterViewModel(val repo: DeepFilterRepository) : ViewModel() {
var deepFilterLiveData: LiveData<Result>? = null
fun onImageCompressed(compressedImage: File): LiveData<Result>? {
if (deepFilterLiveData == null) {
viewModelScope.launch {
deepFilterLiveData = repo.applyFilter(compressedImage)
}
}
return deepFilterLiveData
}
}
Run Code Online (Sandbox Code Playgroud)
资料库
class DeepFilterRepository {
suspend fun applyFilter(compressedImage: File): LiveData<Result> {
val mutableLiveData = MutableLiveData<Result>()
mutableLiveData.value = Result.Loading
withContext(Dispatchers.IO) {
mutableLiveData.value = Result.Success("Done")
}
return mutableLiveData
}
}
Run Code Online (Sandbox Code Playgroud)
我正在观察片段中的LiveData,如下所示:
viewModel.onImageCompressed(compressedImage)?.observe(this, Observer { result ->
when (result) {
is Result.Loading -> {
loader.makeVisible() …Run Code Online (Sandbox Code Playgroud) android kotlin android-livedata android-viewmodel kotlin-coroutines
android ×10
google-play ×2
material-you ×2
android-jetpack-compose-material3 ×1
android-jetpack-compose-pager ×1
android-jetpack-compose-text ×1
apk ×1
firebase ×1
jetpack-compose-accompanist ×1
kotlin ×1
material3 ×1
zipalign ×1