diff --git a/app/build.gradle b/app/build.gradle index ab1a357..49e0b35 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "org.redcross.openmapkit" minSdkVersion 16 targetSdkVersion 21 - versionCode 14 - versionName "0.14" + versionCode 15 + versionName "0.15" } buildTypes { release { @@ -25,8 +25,9 @@ repositories { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:22.2.1' - compile 'com.android.support:design:22.2.1' compile group: 'com.google.guava', name: 'guava', version: '18.0' compile project(':MapboxAndroidSDK') + compile 'com.android.support:appcompat-v7:22.2.1' + compile 'com.android.support:design:22.2.1' + compile 'com.android.support:support-v4:21.0.3' } diff --git a/app/src/main/java/org/redcross/openmapkit/odkcollect/tag/ODKTag.java b/app/src/main/java/org/redcross/openmapkit/odkcollect/tag/ODKTag.java index 71458e4..1c4583e 100644 --- a/app/src/main/java/org/redcross/openmapkit/odkcollect/tag/ODKTag.java +++ b/app/src/main/java/org/redcross/openmapkit/odkcollect/tag/ODKTag.java @@ -1,12 +1,15 @@ package org.redcross.openmapkit.odkcollect.tag; import android.app.Activity; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -17,7 +20,8 @@ public class ODKTag { private String key; private String label; private LinkedHashMap items = new LinkedHashMap<>(); - private Map radioButtonIdToODKTagItemHash = new HashMap<>(); + private Map buttonIdToODKTagItemHash = new HashMap<>(); + private List checkBoxes = new ArrayList<>(); public String getKey() { return key; @@ -47,12 +51,12 @@ public void addItem(ODKTagItem item) { items.put(item.getValue(), item); } - public void putRadioButtonIdToTagItemHash(Integer id, ODKTagItem tagItem) { - radioButtonIdToODKTagItemHash.put(id, tagItem); + public void putButtonIdToTagItemHash(Integer id, ODKTagItem tagItem) { + buttonIdToODKTagItemHash.put(id, tagItem); } - public String getTagItemValueFromRadioButtonId(Integer id) { - ODKTagItem item = radioButtonIdToODKTagItemHash.get(id); + public String getTagItemValueFromButtonId(Integer id) { + ODKTagItem item = buttonIdToODKTagItemHash.get(id); if (item != null) { return item.getValue(); } @@ -76,4 +80,47 @@ public TextView createTagValueTextView(Activity activity, String initialTagVal) } return et; } + + public void addCheckbox(CheckBox cb) { + checkBoxes.add(cb); + } + + public boolean hasCheckedTagValues() { + for (CheckBox cb : checkBoxes) { + if (cb.isChecked()) { + return true; + } + } + return false; + } + + public String getSemiColonDelimitedTagValues(String customValues) { + String values = null; + boolean firstVal = true; + for (CheckBox cb : checkBoxes) { + if (cb.isChecked()) { + int id = cb.getId(); + ODKTagItem item = buttonIdToODKTagItemHash.get(id); + if (item != null) { + if (firstVal) { + firstVal = false; + values = item.getValue(); + } else { + values += ';' + item.getValue(); + } + } + } + } + if (customValues != null) { + customValues = customValues.trim(); + if (customValues.length() > 0) { + if (firstVal) { + values = customValues; + } else { + values += ';' + customValues; + } + } + } + return values; + } } diff --git a/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectMultipleTagValueFragment.java b/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectMultipleTagValueFragment.java new file mode 100644 index 0000000..70d1b53 --- /dev/null +++ b/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectMultipleTagValueFragment.java @@ -0,0 +1,226 @@ +package org.redcross.openmapkit.tagswipe; + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.redcross.openmapkit.R; +import org.redcross.openmapkit.odkcollect.tag.ODKTag; +import org.redcross.openmapkit.odkcollect.tag.ODKTagItem; + +import java.util.Collection; + +/** + * A simple {@link Fragment} subclass. + * Activities that contain this fragment must implement the + * {@link SelectMultipleTagValueFragment.OnFragmentInteractionListener} interface + * to handle interaction events. + * Use the {@link SelectMultipleTagValueFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class SelectMultipleTagValueFragment extends Fragment { + + private static final String IDX = "IDX"; + + private TagEdit tagEdit; + private View rootView; + + private OnFragmentInteractionListener mListener; + + public SelectMultipleTagValueFragment() { + // Required empty public constructor + } + + + public static SelectMultipleTagValueFragment newInstance(int idx) { + SelectMultipleTagValueFragment fragment = new SelectMultipleTagValueFragment(); + Bundle args = new Bundle(); + args.putInt(IDX, idx); + fragment.setArguments(args); + return fragment; + } + + private void setupWidgets() { + TextView tagKeyLabelTextView = (TextView) rootView.findViewById(R.id.tagKeyLabelTextView); + TextView tagKeyTextView = (TextView) rootView.findViewById(R.id.tagKeyTextView); + + String keyLabel = tagEdit.getTagKeyLabel(); + String key = tagEdit.getTagKey(); + + if (keyLabel != null) { + tagKeyLabelTextView.setText(keyLabel); + tagKeyTextView.setText(key); + } else { + tagKeyLabelTextView.setText(key); + tagKeyTextView.setText(""); + } + + setupCheckBoxes(); + } + + @SuppressWarnings("ResourceType") + private void setupCheckBoxes() { + final LinearLayout checkboxLinearLayout = (LinearLayout)rootView.findViewById(R.id.checkboxLinearLayout); + final Activity activity = getActivity(); + ODKTag odkTag = tagEdit.getODKTag(); + if (odkTag == null) return; + + /** + * Setting up buttons with prescribed choice values. + */ + String prevTagVal = tagEdit.getTagVal(); + boolean prevTagValInTagItems = false; + Collection odkTagItems = odkTag.getItems(); + int id = 1; + for (ODKTagItem item : odkTagItems) { + String label = item.getLabel(); + String value = item.getValue(); + if (value.equals(prevTagVal)) { + prevTagValInTagItems = true; + } + CheckBox checkBox = new CheckBox(activity); + checkBox.setTextSize(18); + TextView textView = new TextView(activity); + textView.setPadding(66, 0, 0, 25); + textView.setOnClickListener(new TextViewOnClickListener(checkBox)); + if (label != null) { + checkBox.setText(label); + textView.setText(value); + } else { + checkBox.setText(value); + textView.setText(""); + } + checkboxLinearLayout.addView(checkBox); + if (prevTagVal != null && value.equals(prevTagVal)) { + checkBox.toggle(); + } + checkBox.setId(id); + odkTag.putButtonIdToTagItemHash(id++, item); + odkTag.addCheckbox(checkBox); + checkboxLinearLayout.addView(textView); + } + + final CheckBox editTextCheckBox = new CheckBox(activity); + final EditText editText = new EditText(activity); + editText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + if (!prevTagValInTagItems && prevTagVal != null) { + editText.setText(prevTagVal); + editTextCheckBox.setChecked(true); + } + editText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + if (charSequence.length() > 0) { + editTextCheckBox.setChecked(true); + } else { + editTextCheckBox.setChecked(false); + } + } + + @Override + public void afterTextChanged(Editable editable) { + } + }); + editTextCheckBox.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (editTextCheckBox.isChecked()) { + editText.setFocusableInTouchMode(true); + editText.requestFocus(); + final InputMethodManager inputMethodManager = (InputMethodManager) activity + .getSystemService(Context.INPUT_METHOD_SERVICE); + inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); + } + } + }); + tagEdit.setupEditCheckbox(editTextCheckBox, editText); + + LinearLayout customLinearLayout = new LinearLayout(activity); + customLinearLayout.setOrientation(LinearLayout.HORIZONTAL); + customLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + customLinearLayout.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS); + customLinearLayout.setFocusableInTouchMode(true); + customLinearLayout.addView(editTextCheckBox); + customLinearLayout.addView(editText); + checkboxLinearLayout.addView(customLinearLayout); + + } + + /** + * Allows us to pass a CheckBox as a parameter to onClick + */ + private class TextViewOnClickListener implements View.OnClickListener { + CheckBox checkBox; + + public TextViewOnClickListener(CheckBox cb) { + checkBox = cb; + } + + @Override + public void onClick(View v) { + checkBox.toggle(); + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if (getArguments() != null) { + int idx = getArguments().getInt(IDX); + tagEdit = TagEdit.getTag(idx); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + rootView = inflater.inflate(R.layout.fragment_select_multiple_tag_value, container, false); + setupWidgets(); + return rootView; + } + + // TODO: Rename method, update argument and hook method into UI event + public void onButtonPressed(Uri uri) { + if (mListener != null) { + mListener.onFragmentInteraction(uri); + } + } + + @Override + public void onDetach() { + super.onDetach(); + mListener = null; + } + + /** + * This interface must be implemented by activities that contain this + * fragment to allow an interaction in this fragment to be communicated + * to the activity and potentially other fragments contained in that + * activity. + *

+ * See the Android Training lesson Communicating with Other Fragments for more information. + */ + public interface OnFragmentInteractionListener { + // TODO: Update argument type and name + void onFragmentInteraction(Uri uri); + } +} diff --git a/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectOneTagValueFragment.java b/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectOneTagValueFragment.java index 8e88a5e..ce8a858 100644 --- a/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectOneTagValueFragment.java +++ b/app/src/main/java/org/redcross/openmapkit/tagswipe/SelectOneTagValueFragment.java @@ -1,6 +1,5 @@ package org.redcross.openmapkit.tagswipe; -import android.app.ActionBar; import android.app.Activity; import android.content.Context; import android.net.Uri; @@ -11,7 +10,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.ViewParent; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.LinearLayout; @@ -40,9 +38,6 @@ public class SelectOneTagValueFragment extends Fragment { private TagEdit tagEdit; private View rootView; - private TextView tagKeyLabelTextView; - private TextView tagKeyTextView; - private OnFragmentInteractionListener mListener; @@ -55,8 +50,8 @@ public static SelectOneTagValueFragment newInstance(int idx) { } private void setupWidgets() { - tagKeyLabelTextView = (TextView)rootView.findViewById(R.id.tagKeyLabelTextView); - tagKeyTextView = (TextView)rootView.findViewById(R.id.tagKeyTextView); + TextView tagKeyLabelTextView = (TextView) rootView.findViewById(R.id.tagKeyLabelTextView); + TextView tagKeyTextView = (TextView) rootView.findViewById(R.id.tagKeyTextView); String keyLabel = tagEdit.getTagKeyLabel(); String key = tagEdit.getTagKey(); @@ -152,8 +147,8 @@ public void onClick(View view) { if (prevTagVal != null && value.equals(prevTagVal)) { button.toggle(); } - int buttonId = button.getId(); - odkTag.putRadioButtonIdToTagItemHash(buttonId, item); + int id = button.getId(); + odkTag.putButtonIdToTagItemHash(id, item); tagValueRadioGroup.addView(textView); } if (!prevTagValInTagItems) { diff --git a/app/src/main/java/org/redcross/openmapkit/tagswipe/TagEdit.java b/app/src/main/java/org/redcross/openmapkit/tagswipe/TagEdit.java index 2612a04..f0bd81b 100644 --- a/app/src/main/java/org/redcross/openmapkit/tagswipe/TagEdit.java +++ b/app/src/main/java/org/redcross/openmapkit/tagswipe/TagEdit.java @@ -1,5 +1,6 @@ package org.redcross.openmapkit.tagswipe; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioButton; @@ -35,9 +36,16 @@ public class TagEdit { private String tagVal; private ODKTag odkTag; private boolean readOnly; + private boolean checkBoxMode = false; private int idx = -1; private EditText editText; private RadioGroup radioGroup; + + /** + * For CheckBox mode. + */ + private CheckBox editTextCheckBox; + private EditText checkBoxEditText; public static List buildTagEdits() { int idx = 0; @@ -135,12 +143,34 @@ public void setEditText(EditText editText) { public void setRadioGroup(RadioGroup radioGroup) { this.radioGroup = radioGroup; } + + public void setupEditCheckbox(CheckBox cb, EditText et) { + checkBoxMode = true; + editTextCheckBox = cb; + checkBoxEditText = et; + } public ODKTag getODKTag() { return odkTag; } private void updateTagInOSMElement() { + // check boxes + if (odkTag != null && checkBoxMode) { + boolean editTextCheckBoxChecked = editTextCheckBox.isChecked(); + if (odkTag.hasCheckedTagValues() || editTextCheckBoxChecked) { + if (editTextCheckBoxChecked) { + tagVal = odkTag.getSemiColonDelimitedTagValues(checkBoxEditText.getText().toString()); + } else { + tagVal = odkTag.getSemiColonDelimitedTagValues(null); + } + osmElement.addOrEditTag(tagKey, tagVal); + } else { + osmElement.deleteTag(tagKey); + } + return; + } + // radio buttons if (radioGroup != null && odkTag != null) { LinearLayout customLL = (LinearLayout)radioGroup.getChildAt(radioGroup.getChildCount() - 1); RadioButton customRadio = (RadioButton)customLL.getChildAt(0); @@ -150,12 +180,14 @@ private void updateTagInOSMElement() { tagVal = et.getText().toString(); osmElement.addOrEditTag(tagKey, tagVal); } else if (checkedId != -1) { - tagVal = odkTag.getTagItemValueFromRadioButtonId(checkedId); + tagVal = odkTag.getTagItemValueFromButtonId(checkedId); osmElement.addOrEditTag(tagKey, tagVal); } else { osmElement.deleteTag(tagKey); } - } else if (editText != null) { + } + // edit text + else if (editText != null) { tagVal = editText.getText().toString(); osmElement.addOrEditTag(tagKey, tagVal); } diff --git a/app/src/main/java/org/redcross/openmapkit/tagswipe/TagSwipeActivity.java b/app/src/main/java/org/redcross/openmapkit/tagswipe/TagSwipeActivity.java index 186e2fa..62d43e0 100644 --- a/app/src/main/java/org/redcross/openmapkit/tagswipe/TagSwipeActivity.java +++ b/app/src/main/java/org/redcross/openmapkit/tagswipe/TagSwipeActivity.java @@ -179,6 +179,7 @@ public Fragment getItem(int position) { return fragment; } else if (tagEdit.isSelectOne()) { fragment = SelectOneTagValueFragment.newInstance(position); +// fragment = SelectMultipleTagValueFragment.newInstance(position); return fragment; } else { fragment = StringTagValueFragment.newInstance(position); diff --git a/app/src/main/res/layout/fragment_select_multiple_tag_value.xml b/app/src/main/res/layout/fragment_select_multiple_tag_value.xml new file mode 100644 index 0000000..dfaadd1 --- /dev/null +++ b/app/src/main/res/layout/fragment_select_multiple_tag_value.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 144f164..83bfea5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -19,7 +19,7 @@ Save Cancel + - + openmapkit/mbtiles @@ -58,9 +58,9 @@ Tags - + Hello blank fragment - + Confirm Save tag edits to ODK Collect? Add or Confirm