Android Studio - Kotlin doOnLayout 从未初始化

问题描述 投票:0回答:1

尝试创建一个dialogFragment来显示所单击的缩略图的更高分辨率图像。 我已经使用日志缩小了 doOnLayout 未运行的范围,因为 IDE 没有出现任何错误或问题。 我尝试分别添加延迟和发布,但没有改变任何内容。 代码中的所有日志都显示与图像相关的正确信息。 我觉得我没有正确或类似地创建布局,但不具备检查如何进行的知识。

当单击按钮打开相关图像时,我要在对话框片段上创建一个类。抱歉,代码非常混乱,我是这门语言的新手,并且尝试了很多不同的方法但无济于事。如果存在错误代码或问题,我可能会随着时间的推移自己进行调试,但是不存在错误或问题,该对话框永远不会打开。一些关于调试或任何不正确的代码实例的提示将非常感激。

class PictureDialogFragment: DialogFragment() {

    companion object {
        private const val ARG_IMAGE = "ARG_IMAGE"

        fun newInstance(photoFile: String?): PictureDialogFragment {
            val args = Bundle().apply { putString(ARG_IMAGE, photoFile) }
            return PictureDialogFragment().apply { arguments = args }
        }
    }

    @RequiresApi(Build.VERSION_CODES.TIRAMISU)

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return activity?.let { it ->
            val builder = AlertDialog.Builder(it)
            val inflater = requireActivity().layoutInflater
            val view = inflater.inflate(R.layout.dialog_photo, null)
            
            val photoFileName = arguments?.getString(ARG_IMAGE)
            Log.d("debug", "$photoFileName retrieved photofilename")

            val photoFile = photoFileName?.let {
                File(requireContext().applicationContext.filesDir, it)
            }
            Log.d("debug", "$photoFile retrieved photoFile")

            val imageView = view.findViewById(R.id.dialog_photo_viewer) as ImageView
            Log.d("debug", "$imageView retrieved imageview")

            updatePhotoForDialog(photoFile, imageView)
            builder.create()

        } ?: throw IllegalStateException("Activity cannot be null")
    }

运行 updatePhotoForDialog 时,日志文件具有与图像相关的正确信息。 imageView.doOnLayout 从未运行。我尝试过延迟发布{}。

private fun updatePhotoForDialog(photoFile: File?, imageView: ImageView) {
    Log.d("debug", "updatePhotoForDialog called $imageView, $photoFile")
    if (photoFile != null && photoFile.exists()) {
        Log.d("debug", "photoFile called inside updatePhotoForDialog: $photoFile")
            imageView.doOnLayout {
                Log.d("debug", "doOnLayout: $photoFile")
                val scaledBitmap = getScaledBitmap(
                    photoFile.path,
                    imageView.width,
                    imageView.height
                )
                imageView.setImageBitmap(scaledBitmap)
                Log.d("debug", "setImageBitmap error")
            }
        } else {
            imageView.setImageBitmap(null)
            Log.d("debug", "updatePhotoForDialog error")
        }
    }
}

这就是我的其他文件中调用代码的方式。 创建一个newInstance,触发onCreateDialog,它使用updatePhotoForDialog。所以一切正常,直到 imageView.doOnLayout。

plantPhoto.setOnClickListener{
                if (photoName?.isNotBlank() == true) {
                    Log.d("Debug", "photoName contains: $photoName")
                    photoName?.let { it1 ->
                        val dialogFragment = PictureDialogFragment.newInstance(it1)
                        dialogFragment.show(parentFragmentManager, "PictureDialogFragmentTag")
                    }
                }
            }

我在 AndroidManifest 中设置了一个连接到 files.xml 的文件提供程序,这是我的 build.gradle

plugins {
    id("com.android.application")
    id("org.jetbrains.kotlin.android")
    id("com.google.devtools.ksp")
    id("androidx.navigation.safeargs")
}

android {
    namespace = "com.example.greenspot"
    compileSdk = 33

    defaultConfig {
        applicationId = "com.example.greenspot"
        minSdk = 25
        targetSdk = 33
        versionCode = 1
        versionName = "1.0"

        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

    }


    buildTypes {
        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_1_8
        targetCompatibility = JavaVersion.VERSION_1_8

    }
    kotlinOptions {
        jvmTarget = "1.8"
    }
    buildFeatures {
        viewBinding = true
    }
}

dependencies {
    implementation("com.github.bumptech.glide:glide:4.12.0")
    annotationProcessor("com.github.bumptech.glide:compiler:4.12.0")
    implementation("androidx.core:core-ktx:1.9.0")
    implementation("androidx.appcompat:appcompat:1.6.1")
    implementation("com.google.android.material:material:1.9.0")
    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
    implementation("androidx.fragment:fragment-ktx:1.6.1")
    implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1")
    implementation("androidx.recyclerview:recyclerview:1.2.1")
    testImplementation("junit:junit:4.13.2")
    androidTestImplementation("androidx.test.ext:junit:1.1.5")
    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
    debugImplementation ("androidx.fragment:fragment-testing:1.6.1")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
    implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
    implementation("androidx.room:room-runtime:2.5.0")
    implementation("androidx.room:room-ktx:2.5.0")
    ksp("androidx.room:room-compiler:2.5.0")
    implementation("androidx.navigation:navigation-fragment-ktx:2.4.1")
    implementation("androidx.navigation:navigation-ui-ktx:2.4.1")


}
android kotlin android-dialogfragment
1个回答
0
投票

我没有在您的代码中看到设置您在对话框生成器或您返回的对话框中任何地方膨胀的视图。因此,膨胀的视图及其子视图永远不会附加到视图上,也不会进行布局。 但是因为我看到您启用了 viewBinding 功能并且您正在使用 DialogFragment,所以我建议您使用一种更简单的方法来创建对话框:

  //Pass to the constructor the layout, so the onViewCreated will be called    
  class PictureDialogFragment: DialogFragment(R.layout.dialog_photo) {
    
            var _binding: DialogPhotoBinding? = null
            val bindind get() = _binding!!
        
            companion object {
                private const val ARG_IMAGE = "ARG_IMAGE"
        
                fun newInstance(photoFile: String?): PictureDialogFragment {
                    val args = Bundle().apply { putString(ARG_IMAGE, photoFile) }
                    return PictureDialogFragment().apply { arguments = args }
                }
            }
        
            @RequiresApi(Build.VERSION_CODES.TIRAMISU)
            override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
                    //Initialize the binding here so you can use it's properties
                    _binding = DialogPhotoBinding.bind(view)
                    super.onViewCreated(view, savedInstanceState)
                    
                    val photoFileName = arguments?.getString(ARG_IMAGE)
                    Log.d("debug", "$photoFileName retrieved photofilename")
        
                    val photoFile = photoFileName?.let {
                        File(requireContext().applicationContext.filesDir, it)
                    }
                    Log.d("debug", "$photoFile retrieved photoFile")
        
                    
                    Log.d("debug", "${binding.dialogPhotoViewer} retrieved imageview")
                    //Pass the imageView from the binding object
                    updatePhotoForDialog(photoFile, binding.dialogPhotoViewer)   
               
            }

            private fun updatePhotoForDialog(photoFile: File?, imageView: ImageView) {
                ...
            }

            override fun onDestroyView() {
                _binding = null
                super.onDestroyView()
            }

    }
© www.soinside.com 2019 - 2024. All rights reserved.