From fcfa28c62db501bdfe062cfd2eda7b4bb93c3095 Mon Sep 17 00:00:00 2001 From: Gabor Keszthelyi Date: Fri, 2 Sep 2016 17:09:24 +0200 Subject: [PATCH] Implement location field opening maps with new LocationFieldView and opentasks_location_field_view.xml layout. --- .../org/dmfs/tasks/model/DefaultModel.java | 3 +- .../java/org/dmfs/tasks/model/XmlModel.java | 2 +- .../dmfs/tasks/widget/LocationFieldView.java | 151 ++++++++++++++++++ .../layout/opentasks_location_field_view.xml | 23 +++ 4 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 opentasks/src/main/java/org/dmfs/tasks/widget/LocationFieldView.java create mode 100644 opentasks/src/main/res/layout/opentasks_location_field_view.xml diff --git a/opentasks/src/main/java/org/dmfs/tasks/model/DefaultModel.java b/opentasks/src/main/java/org/dmfs/tasks/model/DefaultModel.java index 5b4fae100..06a20551f 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/model/DefaultModel.java +++ b/opentasks/src/main/java/org/dmfs/tasks/model/DefaultModel.java @@ -34,6 +34,7 @@ public class DefaultModel extends Model { final static LayoutDescriptor TEXT_VIEW = new LayoutDescriptor(R.layout.text_field_view).setOption(LayoutDescriptor.OPTION_LINKIFY, Linkify.ALL); final static LayoutDescriptor TEXT_VIEW_NO_LINKS = new LayoutDescriptor(R.layout.text_field_view).setOption(LayoutDescriptor.OPTION_LINKIFY, 0); + private final static LayoutDescriptor LOCATION_VIEW = new LayoutDescriptor(R.layout.opentasks_location_field_view).setOption(LayoutDescriptor.OPTION_LINKIFY, 0); private final static LayoutDescriptor TEXT_EDIT = new LayoutDescriptor(R.layout.text_field_editor); private final static LayoutDescriptor TEXT_EDIT_SINGLE_LINE = new LayoutDescriptor(R.layout.text_field_editor).setOption(LayoutDescriptor.OPTION_MULTILINE, false); @@ -101,7 +102,7 @@ public void inflate() .setEditorLayout(CHOICES_EDIT).setChoices(aca).setIcon(R.drawable.ic_detail_status)); // location - addField(new FieldDescriptor(context, R.id.task_field_location, R.string.task_location, TaskFieldAdapters.LOCATION).setViewLayout(TEXT_VIEW) + addField(new FieldDescriptor(context, R.id.task_field_location, R.string.task_location, TaskFieldAdapters.LOCATION).setViewLayout(LOCATION_VIEW) .setEditorLayout(TEXT_EDIT).setIcon(R.drawable.ic_detail_location)); // description diff --git a/opentasks/src/main/java/org/dmfs/tasks/model/XmlModel.java b/opentasks/src/main/java/org/dmfs/tasks/model/XmlModel.java index a5a0dc2d5..ee12a3991 100644 --- a/opentasks/src/main/java/org/dmfs/tasks/model/XmlModel.java +++ b/opentasks/src/main/java/org/dmfs/tasks/model/XmlModel.java @@ -504,7 +504,7 @@ public FieldInflater addEditLayoutOption(String key, int value) FIELD_INFLATER_MAP.put("title", new FieldInflater(TaskFieldAdapters.TITLE, R.id.task_field_title, R.string.task_title, -1, R.layout.text_field_editor, R.drawable.ic_detail_description).addEditLayoutOption(LayoutDescriptor.OPTION_MULTILINE, false)); FIELD_INFLATER_MAP.put("location", new FieldInflater(TaskFieldAdapters.LOCATION, R.id.task_field_location, R.string.task_location, - R.layout.text_field_view, R.layout.text_field_editor, R.drawable.ic_detail_location).addDetailsLayoutOption(LayoutDescriptor.OPTION_LINKIFY, 0)); + R.layout.opentasks_location_field_view, R.layout.text_field_editor, R.drawable.ic_detail_location).addDetailsLayoutOption(LayoutDescriptor.OPTION_LINKIFY, 0)); FIELD_INFLATER_MAP.put("description", new FieldInflater(TaskFieldAdapters.DESCRIPTION, R.id.task_field_description, R.string.task_description, R.layout.text_field_view, R.layout.text_field_editor, R.drawable.ic_detail_description)); FIELD_INFLATER_MAP.put("checklist", new FieldInflater(TaskFieldAdapters.CHECKLIST, R.id.task_field_checklist, R.string.task_checklist, diff --git a/opentasks/src/main/java/org/dmfs/tasks/widget/LocationFieldView.java b/opentasks/src/main/java/org/dmfs/tasks/widget/LocationFieldView.java new file mode 100644 index 000000000..ad69f3f0d --- /dev/null +++ b/opentasks/src/main/java/org/dmfs/tasks/widget/LocationFieldView.java @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2013 Marten Gajda + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.dmfs.tasks.widget; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; +import org.dmfs.tasks.R; +import org.dmfs.tasks.model.ContentSet; +import org.dmfs.tasks.model.FieldDescriptor; +import org.dmfs.tasks.model.adapters.FieldAdapter; +import org.dmfs.tasks.model.layout.LayoutOptions; + + +/** + * A widget that shows the location. When clicked, it opens maps. + * + * @author Gabor Keszthelyi + */ +public class LocationFieldView extends AbstractFieldView implements View.OnClickListener +{ + /** + * The {@link FieldAdapter} of the field for this view. + */ + private FieldAdapter mAdapter; + + /** + * The {@link TextView} to show the text in. + */ + private TextView mTextView; + + private String mText; + + + public LocationFieldView(Context context) + { + super(context); + } + + + public LocationFieldView(Context context, AttributeSet attrs) + { + super(context, attrs); + } + + + public LocationFieldView(Context context, AttributeSet attrs, int defStyle) + { + super(context, attrs, defStyle); + } + + + @Override + protected void onFinishInflate() + { + super.onFinishInflate(); + mTextView = (TextView) findViewById(R.id.text); + setOnClickListener(this); + } + + + @Override + public void setFieldDescription(FieldDescriptor descriptor, LayoutOptions layoutOptions) + { + super.setFieldDescription(descriptor, layoutOptions); + mAdapter = descriptor.getFieldAdapter(); + } + + + @Override + public void onContentChanged(ContentSet contentSet) + { + if (mValues != null) + { + Object adapterValue = mAdapter.get(mValues); + String adapterStringValue = adapterValue != null ? adapterValue.toString() : null; + + if (!TextUtils.isEmpty(adapterStringValue)) + { + mText = adapterStringValue; + mTextView.setText(adapterStringValue); + setVisibility(View.VISIBLE); + } + else + { + // don't show empty values + setVisibility(View.GONE); + } + } + } + + + @Override + public void onClick(View v) + { + openMapWithLocation(mText); + } + + + private void openMapWithLocation(String locationQuery) + { + boolean resolved = tryOpeningMapApplication(locationQuery); + if (!resolved) + { + tryOpenGoogleMapsInBrowser(locationQuery); + } + } + + + private boolean tryOpeningMapApplication(String locationQuery) + { + Uri mapAppUri = Uri.parse("geo:0,0?q=" + Uri.encode(locationQuery)); + Intent mapAppIntent = new Intent(Intent.ACTION_VIEW, mapAppUri); + if (mapAppIntent.resolveActivity(getContext().getPackageManager()) != null) + { + getContext().startActivity(mapAppIntent); + return true; + } + return false; + } + + + private void tryOpenGoogleMapsInBrowser(String locationQuery) + { + Uri googleMapInBrowserUri = Uri.parse("http://maps.google.com/?q=" + Uri.encode(locationQuery)); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, googleMapInBrowserUri); + if (browserIntent.resolveActivity(getContext().getPackageManager()) != null) + { + getContext().startActivity(browserIntent); + } + } +} diff --git a/opentasks/src/main/res/layout/opentasks_location_field_view.xml b/opentasks/src/main/res/layout/opentasks_location_field_view.xml new file mode 100644 index 000000000..bbf861493 --- /dev/null +++ b/opentasks/src/main/res/layout/opentasks_location_field_view.xml @@ -0,0 +1,23 @@ + + + + + + + + + + \ No newline at end of file