[SuwLib] Remove button from parent after createButton
Since the button for a ButtonItem is reused, it may be moved to a
different view parent after re-binding. In order to make sure the move
is successful, the button must be first removed from the current parent
before returning.
Bug: 28317915
Change-Id: Ice2a7d1a5f33870775dfd26c1bff816de70526e9
diff --git a/library/main/src/com/android/setupwizardlib/items/ButtonItem.java b/library/main/src/com/android/setupwizardlib/items/ButtonItem.java
index 4faeff4..2ec6489 100644
--- a/library/main/src/com/android/setupwizardlib/items/ButtonItem.java
+++ b/library/main/src/com/android/setupwizardlib/items/ButtonItem.java
@@ -114,6 +114,13 @@
throw new UnsupportedOperationException("Cannot bind to ButtonItem's view");
}
+ /**
+ * Create a button according to this button item.
+ *
+ * @param parent The parent of the button, used to retrieve the theme and context for this
+ * button.
+ * @return A button that can be added to the parent.
+ */
protected Button createButton(ViewGroup parent) {
if (mButton == null) {
Context context = parent.getContext();
@@ -122,6 +129,12 @@
}
mButton = new Button(context);
mButton.setOnClickListener(this);
+ } else {
+ if (mButton.getParent() instanceof ViewGroup) {
+ // A view cannot be added to a different parent if one already exists. Remove this
+ // button from its parent before returning.
+ ((ViewGroup) mButton.getParent()).removeView(mButton);
+ }
}
mButton.setEnabled(mEnabled);
mButton.setText(mText);
diff --git a/library/test/src/com/android/setupwizardlib/test/ButtonItemTest.java b/library/test/src/com/android/setupwizardlib/test/ButtonItemTest.java
index 45342d0..3490d4d 100644
--- a/library/test/src/com/android/setupwizardlib/test/ButtonItemTest.java
+++ b/library/test/src/com/android/setupwizardlib/test/ButtonItemTest.java
@@ -21,6 +21,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.setupwizardlib.R;
@@ -66,6 +67,18 @@
assertTrue("Default button text should be empty", TextUtils.isEmpty(button.getText()));
}
+ public void testCreateButtonTwice() {
+ TestButtonItem item = new TestButtonItem();
+ final Button button = item.createButton(mParent);
+
+ FrameLayout frameLayout = new FrameLayout(getContext());
+ frameLayout.addView(button);
+
+ final Button button2 = item.createButton(mParent);
+ assertSame("createButton should be reused", button, button2);
+ assertNull("Should be removed from parent after createButton", button2.getParent());
+ }
+
public void testSetEnabledTrue() {
TestButtonItem item = new TestButtonItem();
item.setEnabled(true);