2

Each row of my listview consists of a TextView and a EditText and I've a button outside the ListView. When that button is clicked, I want to retrieve all the ExitText Values.

I've generated the ListView inside a DialogFragment. It is the saveButton onClick I'm trying to accomplish. Here's my code. Any help would be appreciated.

public class SubVitalsEntryDialogFragment extends DialogFragment {

    ArrayList<SubVitals> subVitalList = new ArrayList<SubVitals>();
    ListView mylist;
    Button saveButton;
    Button cancelButton;
    EditText entryEditText;

    public static SubVitalsEntryDialogFragment newInstance(ArrayList<SubVitals> sub) {
        SubVitalsEntryDialogFragment f = new SubVitalsEntryDialogFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putParcelableArrayList("subVitalList", sub);
        f.setArguments(args);
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.subvitals_dialog_layout, null, false);
        mylist = (ListView) view.findViewById(R.id.vitalEntryListView);
        saveButton = (Button) view.findViewById(R.id.entrySaveButton);
        cancelButton = (Button) view.findViewById(R.id.entryCancelButton);
        //getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().setTitle("Enter your vitals");

        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getDialog().dismiss();
            }
        });

        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ///??????????

            }
        });
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);
        subVitalList = getArguments().getParcelableArrayList("subVitalList");
        ArrayAdapter<SubVitals> adapter = new MyListAdapter(subVitalList);
        mylist.setAdapter(adapter);

    }

    private class MyListAdapter extends ArrayAdapter<SubVitals>{

        public MyListAdapter(ArrayList<SubVitals> subVitalList){

            super(getActivity(), R.layout.subvitals_dialog_layout, subVitalList);
            Log.d("Tag", "super okay");
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View itemView = convertView;
            if (itemView == null)
                itemView = LayoutInflater.from(this.getContext()).inflate(R.layout.sub_vital_template, parent, false);

            String currentVital = subVitalList.get(position).getSubVitalName();

            //Fill the view

            TextView vitalText = (TextView) itemView.findViewById((R.id.vitalEntryTextView));
            vitalText.setText(currentVital);

            return itemView;
        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return subVitalList.size();
        }
    }

}

This is what it looks like

--------------EDIT------------------

public class SubVitalsEntryDialogFragment extends DialogFragment {

    ArrayList<SubVitals> subVitalList = new ArrayList<SubVitals>();
    ListView mylist;
    Button saveButton;
    Button cancelButton;
    EditText entryEditText;
    List<String> vitalsEntered = new ArrayList<>();
    private HashMap<String, String> textValues = new HashMap<String, String>();

    public static SubVitalsEntryDialogFragment newInstance(ArrayList<SubVitals> sub) {
        SubVitalsEntryDialogFragment f = new SubVitalsEntryDialogFragment();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putParcelableArrayList("subVitalList", sub);
        f.setArguments(args);
        return f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.subvitals_dialog_layout, null, false);
        mylist = (ListView) view.findViewById(R.id.vitalEntryListView);
        saveButton = (Button) view.findViewById(R.id.entrySaveButton);
        cancelButton = (Button) view.findViewById(R.id.entryCancelButton);
        //getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getDialog().setTitle("Enter your vitals");

        cancelButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getDialog().dismiss();
            }
        });

        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("SAVE INSIDE","OK");
                for (Map.Entry<String,String> entry : textValues.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    Log.d("HASHCHECK","Key: " + key + " Value" + value);
                    // do stuff
                }


            }
        });
        return view;
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);
        subVitalList = getArguments().getParcelableArrayList("subVitalList");
        ArrayAdapter<SubVitals> adapter = new MyListAdapter(subVitalList);
        mylist.setAdapter(adapter);

    }

    private class MyListAdapter extends ArrayAdapter<SubVitals>{



        public MyListAdapter(ArrayList<SubVitals> subVitalList){

            super(getActivity(), R.layout.subvitals_dialog_layout, subVitalList);
            Log.d("Tag", "super okay");
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //return super.getView(position, convertView, parent);
            //Making sure we've a view to work with(may have been given null
            Log.d("TAG","Inside get view");
            View itemView = convertView;
            boolean convertViewWasNull = false;

            if (itemView == null){
                itemView = LayoutInflater.from(this.getContext()).inflate(R.layout.sub_vital_template, parent, false);
            convertViewWasNull = true;
            }

            TextView vitalText = (TextView) itemView.findViewById((R.id.vitalEntryTextView));
            EditText vitalEditText = (EditText) itemView.findViewById(R.id.vitalEntryEditText);

            if(convertViewWasNull ){
                vitalEditText.addTextChangedListener(new GenericTextWatcher(vitalEditText));
            }

            String currentVital = subVitalList.get(position).getSubVitalName();

            //Fill the view

            vitalText.setText(currentVital);
            return itemView;

        }
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return subVitalList.size();
        }

        private class GenericTextWatcher implements TextWatcher {

            private View view;
            private GenericTextWatcher(View view) {
                this.view = view;
            }

            public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
            public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}

            public void afterTextChanged(Editable editable) {

                String text = editable.toString();
                //save the value for the given tag :
                textValues.put(view.getTag().toString(), editable.toString());
            }
        }

    }

}
Drunken Daddy
  • 7,326
  • 14
  • 70
  • 104
  • Where is EditText related code in Adapter? – ρяσѕρєя K Apr 09 '15 at 06:19
  • EditText is not taking any values when populating the ListView. So I've not used it in adapter. – Drunken Daddy Apr 09 '15 at 06:22
  • According to me, you can do a thing create static to the `EditText` or the `String` of `EditText`. And when you click on the button just call the all `EditTexts` Strings together like `Adapter.edittext_value` – Anshul Tyagi Apr 09 '15 at 06:23
  • @AnshulTyagi Sorry, I dont understand. Can you explain your answer? – Drunken Daddy Apr 09 '15 at 06:24
  • Your question saying you have textview and edittext and there is no edittext defined in adpater. Breaking bad the code............ – Pankaj Apr 09 '15 at 06:24
  • Please tell me what needed to be added – Drunken Daddy Apr 09 '15 at 06:28
  • You can prevent views to be recycled, but this is a very bad thing because a listView is designed for recycling because of better performance...I would follow Kiril Aleksandrow answer, but if You really want to stop recycling (WARNING!!)...here: http://stackoverflow.com/questions/6921462/listview-reusing-views-when-i-dont-want-it-to – Opiatefuchs Apr 09 '15 at 06:34
  • Don't get confused just look at http://stackoverflow.com/a/23953846/4404791 – Anshul Tyagi Apr 09 '15 at 06:36

1 Answers1

3

Do not use a ListView. It is not designed to be used for such purposes. Rows from the ListView are recycled and it is possible to lose data that has already been entered when scrolling. Use LinearLayout instead. This way you will have a direct access to the views in it.

Kiril Aleksandrov
  • 2,601
  • 20
  • 27
  • I'm using ListView because the contents are dynamically generated. – Drunken Daddy Apr 09 '15 at 06:36
  • You can dynamically (programmatically) add views to the ```LinearLayout```. Using ```ListView``` can bring you a lot of trouble. It is designed to show scrollable data, not for dynamically loaded input fields. In addition as far as I remember there were issues when using ```EditText``` in ```ListView``` on some devices - the keyboard was not showing. – Kiril Aleksandrov Apr 09 '15 at 06:40
  • So, there's no other option than changing everything? – Drunken Daddy Apr 09 '15 at 07:18
  • 1
    You can do it but I don't think this is the right way. You can add ```TextWatcher```s to the ```EditText``` views that populates the data entered to some temporary variable (a proper data structure) When the user clicks the **Save** button, The data is taken from the temporary variable and is set to your data (persisted to the database, send through the Internet, etc.). Don't hesitate to ask if you have any further questions :) – Kiril Aleksandrov Apr 09 '15 at 07:25
  • @HeisenBerg, if my answer helped you, may I ask you accept it as the correct one :) – Kiril Aleksandrov Apr 09 '15 at 08:48
  • I've added the textwatcher method. Please see my edit. Now my app crashes when I enter someting to the textbox. Please tell me what I'm doing wrong. – Drunken Daddy Apr 09 '15 at 09:57
  • What's the error? I strongly advise you to not use this approach... do not hack your implementation.. you can just do it the right way with a ```LinearLayout```. – Kiril Aleksandrov Apr 09 '15 at 10:05
  • yeah, I'll definitely try that too. But for now, view.getTag().toString() is making my app crash. – Drunken Daddy Apr 09 '15 at 10:16
  • I guess the tag is null? Have you set it before trying to get it? – Kiril Aleksandrov Apr 09 '15 at 10:18