Search code examples
androidrubymotion

How do I create list view of edit texts?


I want to create a layout where there need to be multiple key-value pairs in a list view that the user can edit. I want to programmatically create a layout that looks something like this.

[Title] [Button that adds a row to the list]
[ [EditText for key] [EditText for value] ]
[ [EditText for key] [EditText for value] ]

I'm new to Android development so I'm not sure if nesting EditText views inside a ListView is the correct approach. Also, I'm using RubyMotion, which allows me to write the app in Ruby so that's why I want to do this programmatically.


Solution

  • This is Activity

    public class MainActivity extends Activity {
    
            private LinearLayout root;
            private KeyValueAdapter adapter;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
        /**
         * create content view
         */
                root = new LinearLayout(this);
                root.setOrientation(LinearLayout.VERTICAL);
                ViewGroup.LayoutParams rootParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                root.setLayoutParams(rootParams);
                setContentView(root);
    
        /**
         * create header view (title + button)
         */
                LinearLayout header = new LinearLayout(this);
                ViewGroup.LayoutParams headerParams = new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                header.setLayoutParams(headerParams);
                header.setGravity(Gravity.CENTER_VERTICAL);
                TextView textView = new TextView(this);
                textView.setText("Some title");
                header.addView(textView);
                Button button = new Button(this);
                button.setText("Add row");
                header.addView(button);
                root.addView(header);
    
                adapter = new KeyValueAdapter(this);
    
        /**
         * create list view
         */
                ListView listView = new ListView(this);
                listView.setLayoutParams(rootParams);
                listView.setAdapter(adapter);
                root.addView(listView);
    
        /**
         * set click listener
         */
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        adapter.addRow();
                    }
                });
    
    
    
            }
        }
    

    Adapter implementation

    static class KeyValueAdapter extends BaseAdapter{
    
            private List<Entry> data;
            private Context context;
    
            KeyValueAdapter(Context context) {
                data = new ArrayList<>();
                this.context = context;
            }
    
            @Override
            public int getCount() {
                return data.size();
            }
    
            @Override
            public Object getItem(int position) {
                return data.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                return 0;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                LinearLayout rootView = new LinearLayout(context);
                rootView.setOrientation(LinearLayout.HORIZONTAL);
                rootView.setGravity(Gravity.CENTER_VERTICAL);
                final Entry entry = data.get(position);
    
                EditText keyEditText = new EditText(context);
                keyEditText.setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
                keyEditText.setHint("Key");
                keyEditText.setText(entry.key);
                keyEditText.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                    }
    
                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        entry.key = s.toString();
                    }
    
                    @Override
                    public void afterTextChanged(Editable s) {
    
                    }
                });
    
                EditText valueEditText = new EditText(context);
                valueEditText.setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
                valueEditText.setHint("Value");
                valueEditText.setText(entry.value);
                valueEditText.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                    }
    
                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        entry.value = s.toString();
                    }
    
                    @Override
                    public void afterTextChanged(Editable s) {
    
                    }
                });
    
                rootView.addView(keyEditText);
                rootView.addView(valueEditText);
                return rootView;
            }
    
            public void addRow(Entry entry){
                data.add(0, entry);
                notifyDataSetChanged();
            }
    
            public void addRow(){
                data.add(0, new Entry("", ""));
                notifyDataSetChanged();
            }
        }
    

    Entry as a list item

    public static class Entry{
            public String key;
            public String value;
    
            public Entry(String key, String value) {
                this.key = key;
                this.value = value;
            }
        }
    

    I have all of this was in the same file, I divide the class for you