trying to create a dialogFragment to show a larger resolution image of the thumbnail that was clicked. I have narrowed it down the the doOnLayout not running using logs as there are no error or issues raised by the IDE. I have tried to include a delay and post{} separately which did not change anything. All the logs in the code show the correct information relating to the image. I feel like i am not creating the layout correctly or similar but do not have the knowledge to check how.
I have a class to create on dialog fragment when a button click to open the relevant image. Sorry the code is quite messy, i am new to this language and have been trying many different things to no avail. If there was an error code or issue i could likely debug it myself over time, however there is no error or issues present, the dialog just never opens. Some tips on debugging or any instances of code that are incorrect would be much appreciated.
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")
}
When the updatePhotoForDialog is ran the log files have the correct information relative to the image. The imageView.doOnLayout is never ran. I have tried delaying and post{}.
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")
}
}
}
This is how the code is called in my other file. Creates a newInstance, triggering the onCreateDialog, which uses the updatePhotoForDialog. So everything works until the 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")
}
}
}
i have a file provider set up in the AndroidManifest connected to a files.xml, and this is my 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")
}
I do not see in your code to set the view that you inflate anywhere in the dialog builder or in the dialog that you are returning. As a result the inflated view and it's childrent are never attached to the view and never layout. But because I see you have the viewBinding feature enabled and you are using DialogFragment, I would suggest an easier way to create your dialog: