I wanted to create a custom Alertdialog Layout with a dropdown list and a few other things. I'm using Kotlin and I'm pretty new to it
Currently I'm stuck at the dropdown list as it doesn't show anything
Here is the Layout.xml:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/backButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:text="Zurück"
app:icon="#drawable/ic_baseline_arrow_back_24"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="#+id/pizzaSelection"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="100dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And here is how I call up the dialog in my activity:
private fun showPizzaDialog(){
val pizzaDialogBuilder = AlertDialog.Builder(this)
pizzaDialogBuilder.setView(R.layout.pizza_alertdialog)
val pizzaDropdown = findViewById<Spinner>(R.id.pizzaSelection)
val pizzaTypes = resources.getStringArray(R.array.pizzaTypes)
if (pizzaDropdown != null) {
val adapter = ArrayAdapter(this,
android.R.layout.simple_spinner_item, pizzaTypes)
pizzaDropdown.adapter = adapter
}
pizzaDialogBuilder.show()
}
The Items are currently hardcoded in the strings.xml resource file as a string-array.
The AlertDialog shows up and i can see and click on the arrow for the dropdown menu, but when I click on it nothing happens.
You're calling findViewById on your current Activity, which doesn't contain R.id.pizza_selection. Therefore I suspect you'll see
val pizzaDropdown = findViewById<Spinner>(R.id.pizzaSelection)
return null.
Try something like this:
// inflate your layout
val dialogView = LayoutInflater.from(this).inflate(R.layout.pizza_alert_dialog, null, false)
// and set it as dialog view
pizzaDialogBuilder.setView(dialogView)
// then call findViewById on this ViewGroup to get the Spinner
val pizzaDropdown = dialogView.findViewById<Spinner>(R.id.pizzaSelection)
my Kotlin syntax might not be correct, sorry. Important is that we're calling findViewById on dialogView, instead of the implicit this.findViewById()
Related
I created an alertDialog which basically contains two editTexts to enter the data(component Id, component name).When the user clicks on yes button in the alert dialog new component is added to the datbase(as of now I haven't added any on click listeners for yes and no buttons in the dialog) but for some reason I can't get the data from the edit text. I'm new to android app development please help me out guys.....Thanks in Advance :)
Note : 1. I'm using viewModel.flag so that the alertDialog stays persistent with rotations.
onCancel() method simply cancels the alertDialog(I intend to use this for updating certain parameters).
This is kotlin code which creates the alert dialogs.
fun onAddComponent()
{
val builder = AlertDialog.Builder(requireActivity())
builder?.setTitle("New Component Info")
val inflater = requireActivity().layoutInflater
builder?.setView(inflater.inflate(R.layout.new_comp, null))
builder?.setPositiveButton(R.string.Okay_button){ dialogInterface, which->
viewModel.flag = false
val editText : EditText? = compAlert?.findViewById(R.id.new_Component)
println(editText.toString())
}
builder?.setNegativeButton(R.string.NO){ dialogInterface, which->
viewModel.flag = false
}
compAlert= builder?.create()
compAlert?.setOnCancelListener{OnCancel()}
viewModel.flag = true
compAlert?.show()
}
This is the xml layout which I inflated in the onAddComponent()
<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:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/new_Component"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:ems="10"
android:hint="comp Id"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="#+id/new_component_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:ems="10"
android:hint="comp name"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="#+id/new_Component"
app:layout_constraintStart_toStartOf="#+id/new_Component"
app:layout_constraintTop_toBottomOf="#+id/new_Component" />
</androidx.constraintlayout.widget.ConstraintLayout>
To get the text inside the EditText you need to do editText.getText().toString() and NOT editText.toString() which you have in your code.
In your code, editText.toString() will return the string representation of the editText object. See the documentation of String's toString() method here.
I have question to answer my curiosity. I have implemented dropdown with material design like snippet code xml at the below
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/provinsi_register_form"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/address_register_form">
<AutoCompleteTextView
android:id="#+id/filled_dropdown_provinsi"
style="#style/greySubText"
android:layout_width="match_parent"
android:layout_height="55dp"
android:hint="#string/provinsi_form"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
You can see the result implementation on this link
picture result dropdown
for the list, I got from ViewModel like on this snipet code below:
konfirmasiViewModel.provinsi.observe(this, { provinsi ->
for (i in provinsi.indices) {
provinsiNama.add(provinsi[i].provinsi!!)
}
val adapter =
ArrayAdapter(this, R.layout.support_simple_spinner_dropdown_item, provinsiNama)
filled_dropdown_provinsi.setAdapter(adapter)
filled_dropdown_provinsi.setOnItemClickListener { adapterView, view, i, l ->
lifecycleScope.launch {
siscaPreference.saveId(provinsi[i].id!!)
}
prov = provinsi[i].id.toString()
}
})
How to make condition if user doesn't choose anything either click by button or not?
Thanks for much attention
I want to set button style programmatically. Reason for that is I have CustomView containing Button. I send style id to my CustomView using custom parameter inside <declare-styleable>. Now I need to set button style for only Button not whole view in my CustomView.
CustomView:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ProgressBar
android:id="#+id/progressBar"
android:layout_width="40dp"
android:layout_height="40dp"
android:indeterminate="true"
android:layout_gravity="center"
android:indeterminateTint="#color/colorText"/>
<Button
android:id="#+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</FrameLayout>
CustomView in my code:
<myproject.CustomView
android:id="#+id/btn"
app:progressColor="#color/colorText"
app:l_buttonText="#string/text"
app:l_buttonStyle="#style/dialog_outlined"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="48dp" />
What I want to achieve is to set style for Button only (value obtained from app:l_buttonStyle) But I have to do this programmatically, because if I set style in XML it will be applied to FrameLayout as a root view. Here is function to init parts of my CustomView
private fun init(context: Context) {
//Init default values
View.inflate(context, R.layout.loading_button, this)
button = findViewById(R.id.button)
progressBar = findViewById(R.id.progressBar)
progressBar?.setGone()
//Now I need to set style for my inflated Button from XML layout
}
The views in custom view has to be created programmatically and at the time of initializing the view custom style has to be applied. Once the view is initialized, style cannot be set.
val button = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Button(this, null, 0, R.style.BtnStyle)
} else {
var themeWrapper = ContextThemeWrapper(this, R.style.BtnStyle)
Button(themeWrapper, null, 0)
}
I am following Android Archt. component to build a project. Following the guidelines I have created a custom Adapter named CataloguesAdapter extending DataBoundListAdapter as :
public class CataloguesAdapter extends DataBoundListAdapter<CatalogueEntity, CatalogueItemBinding> {
private final android.databinding.DataBindingComponent dataBindingComponent;
private final ContributorClickCallback callback;
private CatalogueItemBinding mBinding;
public CataloguesAdapter(DataBindingComponent dataBindingComponent,
ContributorClickCallback callback) {
this.dataBindingComponent = dataBindingComponent;
this.callback = callback;
}
#Override
protected CatalogueItemBinding createBinding(ViewGroup parent) {
mBinding = DataBindingUtil
.inflate(LayoutInflater.from(parent.getContext()),
R.layout.catalogue_item, parent, false,
dataBindingComponent);
//while this click event is working fine
mBinding.getRoot().setOnClickListener(v -> {
CatalogueEntity catalogueEntity = mBinding.getCatalogue();
if (catalogueEntity != null && callback != null) {
callback.onClick(catalogueEntity);
}
});
//todo:not working, this event is not firing
mBinding.deleteIcon.setOnClickListener(v-> callback.onItemDelete());
return mBinding;
}
}
I am implementing swipe to delete layout on Recycler view item. Below is the XML layout of list item:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="catalogue"
type="com.mindtree.igxbridge.traderapp.datasource.local.entity.CatalogueEntity" />
</data>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:id="#+id/view_background"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorRed">
<ImageView
android:id="#+id/delete_icon"
android:layout_width="#dimen/dimen_30_dp"
android:layout_height="#dimen/dimen_30_dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/dimen_10_dp"
app:srcCompat="#drawable/ic_delete"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/dimen_10_dp"
android:layout_toStartOf="#id/delete_icon"
android:text="#string/text_delete"
android:textColor="#color/Material.87.white"
android:textSize="14sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/view_foreground"
android:layout_width="match_parent"
android:background="#FFFFFF"
android:layout_height="wrap_content">
<android.support.v7.widget.AppCompatImageView
android:id="#+id/arrow_icon"
android:layout_width="#dimen/dimen_30_dp"
android:layout_height="#dimen/dimen_30_dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="#dimen/dimen_10_dp"
app:srcCompat="#drawable/ic_arrow_right" />
</RelativeLayout>
</FrameLayout>
</android.support.v7.widget.CardView>
</layout>
Another operation like swipe left/right is working fine but clicking on Delete button event is not getting called.
I tried checking findViewbyId and register click event by that, but no luck with that too.
While CatalogueItemBinding is registered correctly, I am not able to find any other source of error.
Thanks.
Correct me if I have misunderstood your code. You used a FrameLayout to host two relative layouts one top of each other (foreground and background). The delete button is in the background and foreground has match_parent in its width attribute. Therefore, I think the delete button is getting covered by the foreground, leading to "not firing of the event".
Possible Solution
Try incorporating the delete button in the foreground. It makes sense to put UI components in the front.
I think you forget to tell your adapter class to where your XML is set or not to adapter class. just create a variable in XML which will import your adapter class have look.
<variable
name="myAdapter"
type="import your adapter class">
</variable>
Now set this variable to your adapter.
#Override
protected CatalogueItemBinding createBinding(ViewGroup parent) {
mBinding = DataBindingUtil
.inflate(LayoutInflater.from(parent.getContext()),
R.layout.catalogue_item, parent, false,
dataBindingComponent);
mBinding .setmyAdapter(this);
return mBinding;
}
}
then your click will work. Hope it will help you.
I have a custom class that extends a dialog fragment that I will later be putting in an activity, however no matter what I do I cannot find the Textview associated with the XML used to create the custom AlertDialog.
EDIT: Mike was right, the onCreateDialog(Bundle ...) is not called before I try to access the textViews, thus leading to the null pointer exception, I cannot, however for the life of me figure out how to create the dialog then try and access the fields, I have attempted to place the code that finds the views in the onAttach(...) method of a fragment because it is the earliest in the lifecycle, however the code the always calls the getter (to get the textView instance in the fragments first and not onCreateDialog or onAttach, is there anyway to ENSURE that the fragment's onCreateDialog or onAttach is called before the getters?
This is in the activity that that will host the fragment
win_frag is an already instantiated instance of the custom fragment, appendStreak is the getter to attempt to get the textView instances from the fragment.
mainPanel.getThread().onPause();
win_frag.show(fragmentManager, "winning");
// Set the text in the views accordingly by calling a method from
// the fragment
Log.d(TAG, "Attempting to append to the fragment textView");
win_frag.appendStreak(pongApplication.getStreak());
win_frag.appendBonus(pongApplication.getBonus());
win_frag.appendTotal(total);
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder build = new AlertDialog.Builder(getActivity());
// Get the layout inflater (needed to put in custom XML)
LayoutInflater inflater = getActivity().getLayoutInflater();
View inflatedView = inflater.inflate(R.layout.win_screen, null, false);
build.setView(inflatedView);
streakView= (TextView)inflatedView.findViewById(R.id.streak_box);
bonusView= (TextView)inflatedView.findViewById(R.id.bonus_box);
totalView= (TextView)inflatedView.findViewById(R.id.total_box);
}
win_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/metal_background">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:height="50dp"
android:textColor="#android:color/white"
android:text="#string/win_title"
android:textSize="30sp"
android:typeface="monospace"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:height="50dp"
android:gravity="left|center"
android:text="#string/streak_title"
android:textSize="20sp"
android:textColor="#ffffff"
android:id="#+id/streak_box"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:height="50dp"
android:gravity="left|center"
android:text="#string/bonus_title"
android:textSize="20sp"
android:textColor="#ffffff"
android:id="#+id/bonus_box"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:height="50dp"
android:gravity="left|center"
android:text="#string/total_title"
android:textSize="20sp"
android:textColor="#ffffff"
android:id="#+id/total_box"
/>
</LinearLayout>
Try this
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder build = new AlertDialog.Builder(getActivity());
// Get the layout inflater (needed to put in custom XML)
LayoutInflater inflater = getActivity().getLayoutInflater();
View inflatedView = inflater.inflate(R.layout.win_screen, null);
build.setView(inflatedView);
streakView= (TextView) inflatedView.findViewById(R.id.streak_box);
bonusView= (TextView) inflatedView.findViewById(R.id.bonus_box);
totalView= (TextView) inflatedView.findViewById(R.id.total_box);
return builder.create();
}
try changing
inflater.inflate(R.layout.win_screen, null, false);
to
inflater.inflate(R.layout.win_screen, null);