Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I need the exact same feature described in this question. Here is my solution and source code: <a href="https://github.com/laoyang/android-dynamic-views" rel="noreferrer">https://github.com/laoyang/android-dynamic-views</a>. And you can see the video demo in action here: <a href="http://www.youtube.com/watch?v=4HeqyG6FDhQ" rel="noreferrer">http://www.youtube.com/watch?v=4HeqyG6FDhQ</a></p> <h2>Layout</h2> <p>Basically you'll two xml layout files:</p> <ul> <li>A horizontal LinearLayout <strong>row view</strong> with a <code>TextEdit</code>, a <code>Spinner</code> and an <code>ImageButton</code> for deletion. </li> <li>A vertical LinearLayout <strong>container view</strong> with just a <strong>Add new</strong> button. </li> </ul> <h2>Control</h2> <p>In the Java code, you'll add and remove row views into the container dynamically, using inflate, addView, removeView, etc. There are some visibility control for better UX in the stock Android app. You need add a TextWatcher for the EditText view in each row: when the text is empty you need to hide the <strong>Add new</strong> button and the delete button. In my code, I wrote a <code>void inflateEditRow(String)</code> helper function for all the logic.</p> <h2>Other tricks</h2> <ul> <li>Set <code>android:animateLayoutChanges="true"</code> in xml to enable animation</li> <li>Use custom transparent background with <strong>pressed</strong> selector to make the buttons visually the same as the ones in the stock Android app.</li> </ul> <h2>Source code</h2> <p>The Java code of the main activity ( This explains all the logic, but quite a few properties are set in xml layout files, please refer to the Github source for complete solution):</p> <pre><code>public class MainActivity extends Activity { // Parent view for all rows and the add button. private LinearLayout mContainerView; // The "Add new" button private Button mAddButton; // There always should be only one empty row, other empty rows will // be removed. private View mExclusiveEmptyView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.row_container); mContainerView = (LinearLayout) findViewById(R.id.parentView); mAddButton = (Button) findViewById(R.id.btnAddNewItem); // Add some examples inflateEditRow("Xiaochao"); inflateEditRow("Yang"); } // onClick handler for the "Add new" button; public void onAddNewClicked(View v) { // Inflate a new row and hide the button self. inflateEditRow(null); v.setVisibility(View.GONE); } // onClick handler for the "X" button of each row public void onDeleteClicked(View v) { // remove the row by calling the getParent on button mContainerView.removeView((View) v.getParent()); } // Helper for inflating a row private void inflateEditRow(String name) { LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); final View rowView = inflater.inflate(R.layout.row, null); final ImageButton deleteButton = (ImageButton) rowView .findViewById(R.id.buttonDelete); final EditText editText = (EditText) rowView .findViewById(R.id.editText); if (name != null &amp;&amp; !name.isEmpty()) { editText.setText(name); } else { mExclusiveEmptyView = rowView; deleteButton.setVisibility(View.INVISIBLE); } // A TextWatcher to control the visibility of the "Add new" button and // handle the exclusive empty view. editText.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { // Some visibility logic control here: if (s.toString().isEmpty()) { mAddButton.setVisibility(View.GONE); deleteButton.setVisibility(View.INVISIBLE); if (mExclusiveEmptyView != null &amp;&amp; mExclusiveEmptyView != rowView) { mContainerView.removeView(mExclusiveEmptyView); } mExclusiveEmptyView = rowView; } else { if (mExclusiveEmptyView == rowView) { mExclusiveEmptyView = null; } mAddButton.setVisibility(View.VISIBLE); deleteButton.setVisibility(View.VISIBLE); } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } }); // Inflate at the end of all rows but before the "Add new" button mContainerView.addView(rowView, mContainerView.getChildCount() - 1); } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload