Material design Spinner using TextInputLayout.OutlinedBox styling - android

I am currently using Material Design TextInputLayout OutlinedBox as shown below:
<android.support.design.widget.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:inputType="text"/>
</android.support.design.widget.TextInputLayout>
I am trying to add a dropdown box Spinner under my TextInputEditText, and would like to keep the same styling: OutlinedBox.
I see that dropdowns seem to be supported in Material Design, Material Design Text Fields. As shown on here for the Area:
I am currently using a Spinner to generate the Dropdown.
<Spinner
style="#style/Widget.AppCompat.Spinner.DropDown"
android:id="#+id/option"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:dropDownWidth="match_parent" />
It doesn't seem possible to add a dropdown following the OutlinedBox design. Is there a library out there that would allow me to make this happen, or is there a better way to implement this within Material Design?

I am assuming you want to have an Exposed drop-down menu inside the TextInputLayout I had the same problem, what you can do is use AutoCompleteTextView inside your TextInputLayout as in the following in the XML. here's an example of how I approached the issue.
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingRight="30dp"
android:paddingEnd="30dp"
tools:ignore="RtlSymmetry"
android:layout_margin="5dp">
<ImageView
android:layout_width="30dp"
android:layout_margin="10dp"
android:layout_height="match_parent"
app:srcCompat="#drawable/ic_location_city_black_24dp"
android:layout_gravity="center"
/>
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type"
android:orientation="horizontal"
>
<AutoCompleteTextView
android:id="#+id/filled_exposed_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"/>
</com.google.android.material.textfield.TextInputLayout>
</LinearLayout>
</LinearLayout>
You will also need an item layout resource to populate the dropdown popup. The example below provides a layout that follows the Material Design guidelines.
res/layout/dropdown_menu_popup_item.xml
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:ellipsize="end"
android:maxLines="1"
android:textAppearance="?attr/textAppearanceSubtitle1"/>
In your class add the following code depending on what you want.
String[] type = new String[] {"Bed-sitter", "Single", "1- Bedroom", "2- Bedroom","3- Bedroom"};
ArrayAdapter<String> adapter =
new ArrayAdapter<>(
this,
R.layout.dropdown_menu_popup_item,
type);
AutoCompleteTextView editTextFilledExposedDropdown =
findViewById(R.id.filled_exposed_dropdown);
editTextFilledExposedDropdown.setAdapter(adapter);
incase this doesn't help kindly check Exposed Dropdown Menus in material design page.
[https://material.io/develop/android/components/menu/][1]
This is my first answer on stack overflow I hope it helps.

Just use the TextInputLayout included in the Material Components Library with the style Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu.
Something like:
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:hint="Hint text"
...>
<AutoCompleteTextView
android:id="#+id/outlined_exposed_dropdown_editable"
.../>
</com.google.android.material.textfield.TextInputLayout>

I believe that this document isn't showing a Spinner at all. I think it's showing a TextInputLayout with a dropdown icon.
In the Anatomy section, at the Icons subsection, it says
5. Dropdown icon
A dropdown arrow indicates that a text field has a nested selection component.
Now, how you provide the "nested selection component" I'm not sure...

From the other answers, "AutoCompleteTextView" is the answer but it does not do the same as a spinner does.
Here is my solution. Just put normal edittext inside TextInputLayout and make this editText disabled for inputs. And put a 0dp,0dp spinner for normal spinner working.
Don't make spinner visibility=gone, because if it's gone, spinner listener does not work
layout.xml
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/_10dp"
android:theme="#style/ThemeOverlay.App.TextInputLayout">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableEnd="#drawable/arrow_down_pacific_blue"
android:focusable="false"
android:hint="şehir"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
<Spinner
android:id="#+id/spinner"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="10dp"
android:background="#android:color/transparent"
android:spinnerMode="dialog"
tools:listitem="#layout/general_spinner_item" />
java code
set click listener to edittext for trigger spinner click
findViewById(R.id.editText).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinner.performClick();
}
});
in spinner listener, set edittext text from selected item,
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
selectedCity= (City) parent.getAdapter().getItem(position);
editText.setText(selectedCity.getScreenText());
RDALogger.debug("selectedObject " + selectedCity);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
and the result view

I am using the below material libs to get spinner
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.2.1'
Here is my layout look like
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="500dp"
android:layout_height="wrap_content"
android:hint="#string/select_wifi"
app:hintTextAppearance="#style/hintStyle"
app:startIconDrawable="#drawable/wifi">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
style="#style/textInputEdittext"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
Check out this image for the spinner

It seems like they actually use a TextInputLayout wrapping up an AutoCompleteTextView. Note that they are already the material Components theme [https://github.com/material-components/material-components-android/blob/master/docs/getting-started.md].
See:
https://material.io/design/components/menus.html#exposed-dropdown-menu
https://material.io/develop/android/components/menu/

I solved my problem using this:
in XML:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/layout"
style="#style/AppTheme.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="#+id/my_spinner_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
in code:
layout.keyListener=null
ArrayAdapter(it, android.R.layout.simple_list_item_1, list).also {
adapter ->
layout.setAdapter(adapter)
}
Credits:How to make EditText not editable through XML in Android?

You can check my Medium article where I introduce a custom MaterialSpinner which supports two-way data binding and selection tracking. The resulting layout can look as simple as this:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/input_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="#string/selection_hint"
app:startIconDrawable="#drawable/selection_icon"
app:boxBackgroundMode="outline"
app:endIconMode="#{viewModel.items == null || viewModel.items.size() != 0 ? TextInputLayout.END_ICON_DROPDOWN_MENU : TextInputLayout.END_ICON_NONE}">
<com.example.MaterialSpinner
android:id="#+id/items"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:items="#{viewModel.items}"
app:selectedPosition="#={viewModel.selectedItemPosition}"
app:emptyText="#string/selection_no_item_text" />
</com.google.android.material.textfield.TextInputLayout>

I know its too late to answer this question, but somebody like me stuck in issue like this or similar may find this very useful. Visit this repo its perfect solution as requested. This library support all material TextInputLayout styles. Thanks to "Mamoon Al-hawamdeh" for this amazing library.

All this answers are helpful but the one important note that is if you set app:endIconMode attribute, your Drop down menu not work.

Just change inputType from "text" to "none"
<android.support.design.widget.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:id="#+id/myEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Title"
android:inputType="none"/>
</android.support.design.widget.TextInputLayout>

Related

Keyboard showed when focus is on AutoCompleteTextView

I don't understand what I'm doing wrong. I would like to show only dropdown menu. The result is like the photo below: I can edit on it and keyboard is showed. What I'm missing?
Aspected (without pointer enabled):
Result:
XML layout
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/gender_container"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:hint="Gender"
app:layout_constraintTop_toBottomOf="#+id/year_of_bird_container">
<AutoCompleteTextView
android:id="#+id/gender_spinner"
android:layout_width="match_parent"
android:inputType="none"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
From Fragment
private fun setAdapter() {
val genderList = mutableListOf(
Gender.MALE.toString(),
Gender.FEMALE.toString(),
Gender.OTHER.toString(),
Gender.PREFER_NOT_TO_SAY.toString()
)
val adapter = ArrayAdapter(
requireContext(), R.layout.simple_spinner_dropdown_item, genderList
)
binding.genderSpinner.setAdapter(adapter)
}
I used AutoCompleteTextView in my previous project and the usage was same. But to be sure i just created fresh project and added your code, it's working fine too.
Maybe adding android:imeOptions="actionDone" to the previous EditText might solve it, because it can be use the keyboard and when you finish with it, if it's not actionDone keyboard stays for next component.
Other than that, check about your other code parts that effect this, like onFocus or onClick events. If it is not about them i suggest you to create new project and try this again step by step to find what is causing this.
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/gender_container"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="20dp"
android:layout_marginVertical="10dp"
android:hint="Gender"
app:layout_constraintTop_toBottomOf="#+id/year_of_bird_container">
<AutoCompleteTextView
android:id="#+id/gender_spinner"
android:layout_width="match_parent"
android:inputType="none"
android:clickable="false"
android:cursorVisible="false"
android:focusable="false"
android:layout_height="match_parent"/>
</com.google.android.material.textfield.TextInputLayout>
You can try this if you don't want to show the Softkeyboad but retain the cursor/caret. Put this in your activity
window.setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
Screenshot showing the cursor/caret active with no SoftKeyboard
I suggest you to use spinner like below. AutoCompleteTextView not a spinner actually.
<androidx.appcompat.widget.AppCompatSpinner
android:id="#+id/spinner"
style="#style/AddressSpinnerTheme"
android:layout_width="match_parent"
android:layout_height="44dp"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="5dp"
app:entries="#{viewModel.uiState.value.spinnerItemList}"
app:newValue="#{viewModel.uiState.value.spinnerSelectedItem}"
app:onItemSelected="#{listener}" />

Android: View.Gone not working for AutoCompleteTextview as ExposedDropdownMenu

I have an ExposedDropDownMenu as a Spinner as recommended from Material.IO. My problem is that, View.Gone does not work and leaves an arrow in the view and therefore still occupies space.
Screenshot
XML
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
android:layout_width="0dp"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="#+id/calibrate_message_dropdown_menu_TWO"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
tools:ignore="LabelFor" />
</com.google.android.material.textfield.TextInputLayout>
Code
calibrate_message_dropdown_menu_TWO.visibility = View.GONE
I appreciate any help. Thank you!
Can you try hiding the TextInputLayout instead of the contained AutoCompleteTextView. Add an id for the outer TextInputLayout like this:
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense.ExposedDropdownMenu"
android:id="#+id/dropdown_layout"
android:layout_width="0dp"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="#+id/calibrate_message_dropdown_menu_TWO"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
tools:ignore="LabelFor" />
</com.google.android.material.textfield.TextInputLayout>
and then in code:
dropdown_layout.visibility = View.GONE
If you want to remove the dropdown icon just use:
textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE

Default text for TextInputLayout with AutoCompleteTextView

I am using this to display a Spinner type of view for TextInputLayout but I am not getting how can I set any default value to it.
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextColor="#color/primary_color_3">
<AutoCompleteTextView
android:id="#+id/accType_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundTint="#android:color/transparent"
android:inputType="none"
android:text="#={viewModel.mytext}"
android:lineSpacingExtra="5sp"
android:textColor="#color/name_primary_color"
android:textSize="14sp" />
</com.google.android.material.textfield.TextInputLayout>
The placeholder only works when it is in focus mode so please suggest a workaround.
Edit:
I am using two way data binding in this textview and it seems due to this no solution is working in my case. Even i try to set default value for binded object then it automatically pop ups the spinner on application launch which i don't need so please suggest me something.
The AutoCompleteTextView can work with an Adapter.
Just for example:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/til"
..>
<com.google.android.material.textfield.MaterialAutoCompleteTextView
.../>
</com.google.android.material.textfield.TextInputLayout>
Create the adapter:
ArrayList<String> items = new ArrayList<>();
items.add("Material");
items.add("Design");
items.add("Components");
ArrayAdapter<String> adapter = new ArrayAdapter<>(this,R.layout.item, items);
TextInputLayout textInputLayout = findViewById(R.id.til);
Set the default value and the adapter:
((MaterialAutoCompleteTextView) textInputLayout.getEditText()).setAdapter(adapter);
((MaterialAutoCompleteTextView) textInputLayout.getEditText()).setText(adapter.getItem(1),false);
It is important to set the filter false in setText(...,false) to
display the entire list in dropdown and not only the single value.
Use android:text attribute on AutoCompleteTextView like this
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:hintTextColor="#color/primary_color_3">
<AutoCompleteTextView
android:id="#+id/accType_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select Something"
android:backgroundTint="#android:color/transparent"
android:inputType="none"
android:lineSpacingExtra="5sp"
android:textColor="#color/name_primary_color"
android:textSize="14sp" />
</com.google.android.material.textfield.TextInputLayout>

Material OutlinedBox hint with androidx

I am referring this: Outlined Edit Text from Material Design where the answer relates to the outdated support libraries rather than androidx.
How to achieve creating the OutlinedBox with the hint on the top left frame rather than inside the box? Have spent the entire morning unsuccessful. What I want is this:
My graddle:
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0'
My app Theme:
style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"
My layout:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:hint="Full name" >
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</com.google.android.material.textfield.TextInputLayout>
My result (the frame is continuous, without the hint embedded in the top left corner):
Try below code:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/etlFirst"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
app:hintTextColor="#color/colorPrimary"
android:focusable="true"
android:hint="Label">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/etFirst"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColorHint="#color/colorAccent"
android:hint="PlaceHolder"/>
</com.google.android.material.textfield.TextInputLayout>
To displaying two hints try below code in .java file:
etFirst.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
etFirst.setHint("Place Holder");
} else {
etFirst.setHint("Label");
}
}
});
Output for above code is:
I hope this helps you
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/etProposalTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/medium"
android:hint="Title."
android:inputType="text"
android:textSize="18sp" />
</com.google.android.material.textfield.TextInputLayout>
If you want to display at the same time the hint label on top left and a placeholder text inside the EditText you can use:
app:placeholderText: to add a placeholder text in the EditText
android:hint: to add a floating label
They can work together:
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:hint="Label"
app:placeholderText="Placeholder Text"
Note: it requires at least the version 1.2.0-alpha03.

Remove dropdown arrow from AutoCompleteTextView

I want to remove dropdown arrow which is created by AutoCompleteTextView when I use TextInputLayout and use Style: ExposedDropdownMenu
Below is my code:
<com.google.android.material.textfield.TextInputLayout
android:layout_marginTop="10dp"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:hint="Marital Status"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:boxStrokeColor="#color/colorPrimaryDark">
<AutoCompleteTextView
android:background="#null"
android:focusable="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edt_marital" />
</com.google.android.material.textfield.TextInputLayout>
If you would like to avoid the dropdown icon just use the app:endIconMode attribute.
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
app:endIconMode="none"
...>
Before and after:
Hello guys, after having searched a lot and found little. I was trying to achieve how I wanted and I wanted to share the experience and result with you.
As the same Material Design documentation says.
A result Image Dropdown Menu similar to a Spinner, following the documentation. Next code:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/txtAnswer"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_top_15dp"
android:layout_marginEnd="10dp"
app:endIconDrawable="#drawable/ic_arrow_down"
app:hintTextAppearance="#style/styleFilterLabelLatoRegular"
app:layout_constraintEnd_toStartOf="#+id/txtAssignedTo"
app:layout_constraintStart_toStartOf="#+id/guideLineBegin"
app:layout_constraintTop_toBottomOf="#+id/txtSearchQuestionnaire">
<AutoCompleteTextView
android:id="#+id/actvTypesAnswer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none"
android:hint="#string/text_answer" />
Now a result as expected from an AutoCompleteTextView Image AutoCompleteTextView. Code xml.
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/txtSearchQuestionnaire"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_top_15dp"
app:endIconMode="none"
app:hintTextAppearance="#style/styleFilterLabelLatoRegular"
app:layout_constraintEnd_toEndOf="#id/guideLineEnd"
app:layout_constraintStart_toStartOf="#+id/guideLineBegin"
app:layout_constraintTop_toBottomOf="#+id/txtPeriodActivation">
<AutoCompleteTextView
android:id="#+id/actvNameQuestionnaire"
style="#style/textAppearanceSettingInputEdittextFilter.Enabled"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableEnd="#drawable/ic_search"
android:hint="#string/text_search_name_questionnaire" />
</com.google.android.material.textfield.TextInputLayout>
The only changes were to add the attribute app: endIconMode = "none" in TextInputLayout and in the AutoCompleteTextView the attribute android: drawableEnd="#drawable/ic_search"
Excuse my level of English!!

Categories

Resources