I have a custom component that extends RelativeLayout which in turns holds a GridLayout(named mFormLayout). I have a public method that adds two spinners with their proper adapter source and an imageview which acts as a button to remove rows.
public class EditableTwinSpinnerGridForm extends EditableGridForm
{
public void addTwinSpinnerRow(final Locale.MapKey spinner1DefVal, final Locale.MapKey spinner2DefVal)
{
Spinner spinner1 = createSpinner(mTSP.getFirstSpinnerRes(), spinner1DefVal.getId());
spinner1.setOnItemSelectedListener(mTSP.getIsl());
Spinner spinner2 = createSpinner(mTSP.getSecondSpinnerRes(), spinner2DefVal.getId());
ImageView rmvBtn = createRemoveBtn();
mFormLayout.addView(spinner1);
mFormLayout.addView(spinner2);
mFormLayout.addView(rmvBtn);
}
}
For some reason, this method works when I am adding rows from a call to onCreate in an activity, but when I am calling this method after the activity is created(from an onclicklistener) the Spinners are either not there or only one of them shows up. They do take the space because I see the row and the removable image view.
I have also noticed that when I focus on a EditText in the same activity and the keyboard pops up, the added spinners show up when I press back to remove the keyboard.
Here's the code I use to create a spinner :
protected Spinner createSpinner(Integer spinnerSrc, String defaultSpinnerValue)
{
Spinner spinner = new Spinner(mCtx, Spinner.MODE_DIALOG);
// Setting the bg color to the containing color to remove the spinner arrow.
spinner.setBackgroundResource(R.color.container_bg);
SparseArray<Phrase> map = Locale.getInstance().getMap(spinnerSrc);
PhraseArrayAdapter adapter = createSpinnerFromMap(spinnerSrc);
spinner.setAdapter(adapter);
if (defaultSpinnerValue.equals(Utilities.EMPTY_STRING) || defaultSpinnerValue.isEmpty())
{
throw new IllegalStateException();
}
else
{
Utilities.getInstance().setMapSpinnerPosByValue(map, defaultSpinnerValue, spinner);
}
adapter.setDropDownViewResource(R.layout.editable_spinner_dropdown_item);
setSpinnerLayoutParams(spinner);
return spinner;
}
protected void setSpinnerLayoutParams(Spinner spinner)
{
GridLayout.LayoutParams lp = createDefaultGridParams();
lp.setGravity(Gravity.FILL_HORIZONTAL);
lp.width = 250;
lp.rightMargin = 0;
spinner.setLayoutParams(lp);
}
The code works when the activity is loaded so I'm a bit stumped. I looked around and some people suggested I set LayoutParams in addView, but why would this method work in onCreate, but not afterwards?
Here's what's happening visually(The first three rows are added from a loop in onCreate(), the two second ones are added by pressing "Add +"). As you can see the second spinner isn't showing up, sometimes both aren't showing up. I also tried calling invalidate and requestLayout to no avail.
I had looked into the invalidate method, here's where it is located currently :
public abstract class EditableForm extends RelativeLayout implements ObservableInt
{
private class OnAddClicked implements OnClickListener
{
@Override
public void onClick(View v)
{
onAddClicked(v);
EditableForm.this.invalidate();
mFormLayout.invalidate();
}
}
}
Which calls(In a subclass of EditableGrid) :
@Override
protected void onAddClicked(View clickedView)
{
addTwinSpinnerRow();
notifyObservers(new ObservableData(EDITABLE_ADD_GRID_CLICKED, null));
}
protected void addTwinSpinnerRow()
{
Locale.MapKey v1 = Locale.getInstance().getMap(mTSP.getFirstSpinnerRes()).get(0).getMapId();
Locale.MapKey v2 = Locale.getInstance().getMap(mTSP.getSecondSpinnerRes()).get(0).getMapId();
addTwinSpinnerRow(v1, v2);
}