Cannot change Views at Runtime in Dialogfragment - android

I want to set the drawable of a ImageView and a ProgressBar in a DialogFragment at runtime. Therefore i want to set the drawable in the onViewCreated and set the ProgressBar visible when the Positive Button of the Dialog is clicked.
But for reasons i do not know absolutely nothing happens. i also tried to call invalidate on the view to actively trigger a redraw but also nothing happens.
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_view, container, false)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val inflater = requireActivity().layoutInflater
val layout = inflater.inflate(R.layout.dialog_view, null)
val dialog = AlertDialog.Builder(requireContext())
.setTitle(R.string.dialog_title)
.setMessage(R.string.dialog_text)
.setView(layout)
.setPositiveButton(R.string.start, null)
.setNegativeButton(R.string.cancel, null)
.create()
return dialog
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
imageView.setImageDrawable(image) //image is a drawable
}
override fun onResume() {
super.onResume()
val d = dialog as AlertDialog?
d?.getButton(Dialog.BUTTON_POSITIVE)?.setOnClickListener {
progressBar.visibility = View.VISIBLE
}
}
Edit:
Found out that if i directly call something on the layout i pass to the dialog it is possible to change visibility of views.
val layout = inflater.inflate(R.layout.dialog_view, null)
layout.findViewById ....
This works but i still wonder why i cannot simply call with kotlin synthetics on the view.

The action that you want to be performed when the positive button is pressed should be added in the dialog build
.setPositiveButton(R.string.start){ _, _ ->
progressBar.visibility = View.VISIBLE
}

Related

Updating View of AlertDialog from Fragment

I am not sure why I cannot update the imageView of a custom dialog layout xml which is opened from inside a fragment.
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(R.layout.qr_code_layout_dialog);
imageFromLayout.setImageBitmap(myBitmap);
builder.show();
I have also tried to use a Dialog object (not AlertDialog) but it will not even open, therefore AlertDialog opens but will not show any images. Nor will it allow me to update the images from within the java code.
How can I update the imageView image of the layout dialog from within the fragment?
You can try make realisation of it
abstract class ObservableDialog<T>(private val callBack: (T) -> Unit): DialogFragment(){
companion object{
const val TAG = "MY_TAG"
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return super.onCreateView(inflater, container, savedInstanceState)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setLayoutParam()
}
fun doMyChoice(obj: T){
callBack(obj)
dismiss()
}
private fun setLayoutParam(){
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
}
Call it like
val dialog = ObservableDialog<String>{
//do something with result
}
dialog.show(supportFragmentManager, ObservableDialog.TAG)

Visibilty gone layout of custom dialog from another function

I have a custom dialog in kotlin fragment which have 2 button and a progress bar in fuction submitSpk()
class RincianPembelianFragment : androidx.fragment.app.Fragment(), BlockingStep {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.fragment_spk_rincian_bayar, container, false)
//initialize your UI
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity?.supportFragmentManager?.popBackStack(null, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE)
setContext(activity!!.applicationContext)
}
fun submitSpks (){
val inflater = context?.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
val builder = AlertDialog.Builder(context!!)
val dialogView = inflater.inflate(R.layout.activity_signature, null)
builder.setView(dialogView)
builder.setTitle("Tanda Tangan Pembeli")
//builder.show()
builder.setCancelable(false)
dialogView.clear.setOnClickListener {
dialogView.signature_view.clearCanvas()
}
dialogView.save.setOnClickListener {
submitTtd() // or some fuction else
dialogView.save.visibility = View.INVISIBLE
dialogView.progressBar.visibility = View.VISIBLE
}
builder.setNegativeButton(""){ dialog: DialogInterface?, which: Int ->
}
builder.show()
}
fun submitTtd(){
// here there will be a crud transaction and visible/invisible button save
}
}
my custom dialog is look like this
i want to visibility gone the button save dialogView.save.visibility = View.VISIBLE from another fuction e.g saveTtd()
how can i do this? i have tried this but my dialog can't show.. anyone can help me? Thanks before
Storing the dialogView in a global variable should do the job.
Also, call the build() method on the AlertDialog.Builder instance before showing the dialog:
class RincianPembelianFragment : androidx.fragment.app.Fragment(), BlockingStep {
private lateinit var dialogView: View
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val v = inflater.inflate(R.layout.fragment_spk_rincian_bayar, container, false)
//initialize your dialog view
dialogView = inflater.inflate(R.layout.activity_signature, null)
return v
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
activity?.supportFragmentManager?.popBackStack(null, androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE)
setContext(activity!!.applicationContext)
}
fun submitSpks() {
// Using requireContext() is suggested
val builder = AlertDialog.Builder(requireContext())
builder.setView(dialogView)
builder.setTitle("Tanda Tangan Pembeli")
builder.setCancelable(false)
dialogView.clear.setOnClickListener {
dialogView.signature_view.clearCanvas()
}
dialogView.save.setOnClickListener {
submitTtd() // or some fuction else
}
builder.setNegativeButton(""){ dialog: DialogInterface?, which: Int ->
}
// Build the dialog builder before showing it
val dialog = builder.build()
dialog.show()
}
fun submitTtd(){
// here there will be a crud transaction and visible/invisible button save
dialogView.save.visibility = View.INVISIBLE
dialogView.progressBar.visibility = View.VISIBLE
}
}

Android DialogFragment not dismissing on taping outside of it

So I have a DialogFragment which I want it to be cancelable, the thing is that I need to apply match_parent as width and height to see the dialog in the screen well formated , but when clicking outside it does not dismiss the dialog
class InformationDialogFragment : DialogFragment() {
lateinit var viewState: InformationDialogViewState
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NORMAL, R.style.ModalTheme)
}
override fun onStart() {
super.onStart()
val dialog = dialog
if (dialog != null) {
val width = ViewGroup.LayoutParams.MATCH_PARENT
val height = ViewGroup.LayoutParams.MATCH_PARENT
dialog.window!!.setLayout(width, height)
}
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = Dialog(requireContext(), R.style.MyDialog)
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog.window?.requestFeature(Window.FEATURE_NO_TITLE)
dialog.window?.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN)
return dialog
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View {
val binding: InformationDialogBinding = DataBindingUtil.inflate(inflater, R.layout.account_information_dialog, container, false)
binding.viewState = viewState
return binding.root
}
}
I don't need to put isCancelable, setCancelableOnTouch, setCancelable because the dialog itself is cancealable as default, and I have tried it all
when I remove the onStart code, the touch outside works and dismisses the dialog, but the dialog is all shown wrong and vertically
Changing height to wrap content let me dismiss the dialog clicking outside of it
override fun onStart() {
super.onStart()
val dialog = dialog
if (dialog != null) {
val width = ViewGroup.LayoutParams.MATCH_PARENT
val height = ViewGroup.LayoutParams.WRAP_CONTENT
dialog.window!!.setLayout(width, height)
}
}

Is it possible to invoke DialogFragment from custom view?

I've tried to invoke DialogFragment from custom view:
DetailsDialogFragment
.newInstance(newSelectedDate, adapterItems[newPosition].progress)
.apply {
show(childFragmentManager, SCORE_DETAILS_DIALOG_TAG)
}
where DetailsDialogFragment looks like this:
class DetailsDialogFragment : AppCompatDialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return requireActivity().let {
val dialog = Dialog(requireContext(), R.style.CustomDialog)
dialog.window?.setDimAmount(BaseDialogFragment.SCRIM_OPACITY)
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
dialog
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_details_dialog, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.rootView.apply {
findViewById<TextView>(R.id.titleTextView).text = arguments?.getString(ARGS_MONTH)
findViewById<ActionButton>(R.id.button).setOnClickListener {
dismiss()
}
findViewById<ImageView>(R.id.closeImageView).setOnClickListener {
dismiss()
}
}
}
companion object {
fun newInstance(
month: String,
score: Int
): DetailsDialogFragment {
return DetailsDialogFragment()
.apply {
arguments = bundleOf(
ARGS_MONTH to month,
ARGS_SCORE to score
)
}
}
}
}
But I receive the following error:
IllegalStateException: Fragment DetailsDialogFragment has not been attached yet.
at androidx.fragment.app.Fragment.getChildFragmentManager(Fragment.java:980)
...
Is it possible to invoke DialogFragment from custom view at all?
The reason of this exception is that you're trying to use the childFragmentManager of your freshly newly created instance, which is of course not possible since the Dialog fragment hasn't yet has its internals initialized yet (including its childFragmentManager).
If you're using AndroidX I'd use the findFragment extension method inside your custom view and try to do:
Inside your custom view
val dialogFragment = DetailsDialogFragment
.newInstance(newSelectedDate, adapterItems[newPosition].progress)
dialogFragment.show(findFragment().childFragmentManager, SCORE_DETAILS_DIALOG_TAG)

DialogFragment rounded corners - how to set transparency

I've made custom layout for dialogFragment with rounded corners but when dialog is called corners are rounded he looks like below.
https://i.imgur.com/aE4PMhZ.png
I know i need to set transparency dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
but I dont know where to put this in my code, additionally I'm using Kotlin.
Below is the part of code where Dialog is called.
myDialog = Event_Dialog.newInstance(args,args1)
myDialog.show(fragmentManager, "MyDialog")
This is Event_Dialog class.
class Event_Dialog : DialogFragment() {
companion object {
fun newInstance(bundle: String, bundle1: String): Event_Dialog {
//description
val args: Bundle = Bundle()
args.putString("desc", bundle)
//link
args.putString("link", bundle1)
val fragmentDialog = Event_Dialog()
fragmentDialog.arguments = args
return fragmentDialog
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val x = inflater.inflate(R.layout.event_detail, container, false)
some code.......
return x
Could you tell me guys where I should set the transparency of custom background ?
Thanks !
just put it in oncreatedialog like :
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
return dialog
}
and i suggest that you use a framelayout as a root view for your dialog ( match parent frame ) and design your center layout in it

Categories

Resources