I have a form in Android where the user has to enter their height. However, I have a spinner where the user can select the measurement units (feet/inches, and centimeters), and then an EditText
where they can enter the actual value
If the user selects cm as their units, I want a single EditText
. If they select feet/inches, I want to display 2 EditText
fields
The way I'm currently handling this seems inefficient. I have 3 EditText
fields: 1 for cm, 1 for feet, and 1 for inches
I then attach an onItemSelected
listener to the spinner. If the user selects the cm option, I setVisibility(view.VISIBLE)
on the cm EditText
, and setVisibility(view.INVISIBLE)
on both the feet and inches EditText
fields. If they select the feet/inches option, I just do the visibility in reverse and show/hide the corresponding fields.
Is there a more appropriate way to handle multiple unit types that require a different number of EditText
fields?
Note: my EditText
are actually wrapped up in TextInputLayouts
so I can get Material animations on hints, and its on the TextInputLayouts
that I'm setting visibility.
The code looks something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Height unit spinner
String [] values = {"cm","ft"};
Spinner spinner = (Spinner) view.findViewById(R.id.input_height_spinner);
spinner.setOnItemSelectedListener(this);
ArrayAdapter<String> LTRadapter = new ArrayAdapter<>(this.getActivity(), android.R.layout.simple_spinner_item, values);
LTRadapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
spinner.setAdapter(LTRadapter);
heightCMWrapper = (TextInputLayout) view.findViewById(R.id.input_height_cm_wrapper);
heightFTWrapper = (TextInputLayout) view.findViewById(R.id.input_height_ft_wrapper);
heightINWrapper = (TextInputLayout) view.findViewById(R.id.input_height_in_wrapper);
//Some other code for inflating layout etc.
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
heightCMWrapper.setVisibility(view.VISIBLE);
heightCMWrapper.setHint("Height (cm)");
heightCMWrapper.requestFocus();
heightFTWrapper.setVisibility(view.INVISIBLE);
heightFTWrapper.setHint("");
heightINWrapper.setVisibility(view.INVISIBLE);
heightINWrapper.setHint("");
break;
case 1:
heightCMWrapper.setVisibility(view.INVISIBLE);
heightCMWrapper.setHint("");
heightFTWrapper.setVisibility(view.VISIBLE);
heightFTWrapper.setHint("Feet");
heightFTWrapper.requestFocus();
heightINWrapper.setVisibility(view.VISIBLE);
heightINWrapper.setHint("Inches");
break;
}
}
You could do it using just 2 EditTexts instead of 3. Have a primary EditText
for both feet and cms and a secondary one for inches if they choose feet and inches. Then you just have to set the hint of the primary EditText
and toggle the secondary EditText
visibility.
If you want to optimise your current solution with 3 EditText
theres a few things you can do. You shouldn't have to set the hint every time they toggle the units, you should be able to just set it once in onCreateView
since each unit has its own EditText
. This will drop 6 lines from your method. You could take it further and make a method toggleVisibility(EditText editText, boolean visible, boolean giveFocus)
but thats up to you.
As a side note you might want to use View.GONE
instead of View.INVISIBLE
. View.INVISIBLE
just makes it not visible but it still consumes its space in the layout. So if this is your layout:
(input1) (input 2)
and you set (input1) to invisible, this is what the layout would look like:
(blank) (input2)
instead if you set (input1) to View.GONE
this is what it would look like
(input 2)