Bu soruda açıklanan aynı özelliğe ihtiyacım var. İşte benim çözümüm ve kaynak kodum: https://github.com/laoyang/android-dynamic-views . Video demosunu burada çalışırken görebilirsiniz: http://www.youtube.com/watch?v=4HeqyG6FDhQ
Yerleşim
Temel olarak iki xml düzen dosyası olacak:
- A , a ve an ile yatay bir LinearLayout satır görünümü
TextEdit
Spinner
ImageButton
Silme için .
- Yalnızca Yeni ekle düğmesiyle dikey bir LinearLayout kapsayıcı görünümü .
Kontrol
Java kodunda, şişirme, addView, removeView vb. Kullanarak, satır görünümlerini dinamik olarak kapsayıcıya ekler ve kaldırırsınız. Stok Android uygulamasında daha iyi UX için bazı görünürlük kontrolü vardır. Her satırda EditText görünümü için bir TextWatcher eklemeniz gerekir: metin boşken Yeni ekle düğmesini ve sil düğmesini gizlemeniz gerekir . void inflateEditRow(String)
Kodumda, tüm mantık için bir yardımcı işlev yazdım .
Diğer numaralar
android:animateLayoutChanges="true"
Animasyonu etkinleştirmek için xml olarak ayarlayın
- Düğmeleri görsel olarak hisse senedi Android uygulamasındakilerle aynı yapmak için basılan seçiciyle özel şeffaf arka plan kullanın .
Kaynak kodu
Ana etkinliğin Java kodu (Bu, tüm mantığı açıklar, ancak pek çok özellik xml düzen dosyalarında ayarlanmıştır, tam çözüm için lütfen Github kaynağına bakın):
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 && !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
&& 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);
}