Finish UI for Mapillary Filters

This commit is contained in:
Alexander Sytnyk 2017-06-22 12:50:13 +03:00
parent 948925eb3e
commit 6c03572c25
6 changed files with 264 additions and 45 deletions

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/bg_color">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:visibility="gone" />
<android.support.v7.widget.AppCompatTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginBottom="16dp"
android:layout_marginLeft="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:textAppearance="@style/TextAppearance.ListItemTitle"
tools:text="Username" />
</LinearLayout>

View file

@ -26,6 +26,30 @@
tools:text="Username" /> tools:text="Username" />
</android.support.design.widget.TextInputLayout> </android.support.design.widget.TextInputLayout>
<LinearLayout
android:id="@+id/warning_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:visibility="gone">
<ImageView
android:id="@+id/warning_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:text="@string/wrong_user_name"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_sub_text_size"
tools:text="Wrong user name!" />
</LinearLayout>
<View <View
android:id="@+id/divider" android:id="@+id/divider"
android:layout_width="wrap_content" android:layout_width="wrap_content"

View file

@ -9,6 +9,7 @@
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated). 3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
--> -->
<string name="wrong_user_name">Wrong user name!</string>
<string name="shared_string_to">To</string> <string name="shared_string_to">To</string>
<string name="mapillary_menu_date_from">From</string> <string name="mapillary_menu_date_from">From</string>
<string name="mapillary_menu_descr_dates">View images added in a certain period.</string> <string name="mapillary_menu_descr_dates">View images added in a certain period.</string>

View file

@ -3,10 +3,8 @@ package net.osmand.plus;
import android.app.Activity; import android.app.Activity;
import android.app.DatePickerDialog; import android.app.DatePickerDialog;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.support.annotation.ColorRes; import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes; import android.support.annotation.DrawableRes;
import android.support.annotation.IdRes; import android.support.annotation.IdRes;
@ -15,7 +13,6 @@ import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.AppCompatImageView; import android.support.v7.widget.AppCompatImageView;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.ContextThemeWrapper; import android.view.ContextThemeWrapper;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -37,6 +34,7 @@ import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.actions.AppModeDialog; import net.osmand.plus.activities.actions.AppModeDialog;
import net.osmand.plus.dialogs.ConfigureMapMenu; import net.osmand.plus.dialogs.ConfigureMapMenu;
import net.osmand.plus.dialogs.HelpArticleDialogFragment; import net.osmand.plus.dialogs.HelpArticleDialogFragment;
import net.osmand.plus.mapillary.MapillaryAutoCompleteAdapter;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -44,7 +42,6 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
@ -356,36 +353,11 @@ public class ContextMenuAdapter {
final View autoCompleteTextView = convertView.findViewById(R.id.auto_complete_text_view); final View autoCompleteTextView = convertView.findViewById(R.id.auto_complete_text_view);
if (autoCompleteTextView != null) { if (autoCompleteTextView != null) {
AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView; final AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView;
final ArrayAdapter<String> adapter; textView.setAdapter(new MapillaryAutoCompleteAdapter(getContext(), R.layout.auto_complete_suggestion, app));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
adapter = new ArrayAdapter<>(getContext(), R.layout.list_textview, new String[]{"username1", "name1", "user1"});
} else {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getContext().getTheme();
theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
final int textColor = typedValue.data;
adapter = new ArrayAdapter<String>(getContext(), R.layout.list_textview, new String[]{"username1", "name1", "user1"}) {
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final View view = super.getView(position, convertView, parent);
((TextView) view.findViewById(R.id.textView)).setTextColor(textColor);
return view;
}
};
}
adapter.sort(new Comparator<String>() {
@Override
public int compare(String first, String second) {
return first.compareTo(second);
}
});
textView.setAdapter(adapter);
String selectedUsername = app.getSettings().MAPILLARY_FILTER_USERNAME.get(); String selectedUsername = app.getSettings().MAPILLARY_FILTER_USERNAME.get();
if (!selectedUsername.equals("")) { if (!selectedUsername.equals("") && app.getSettings().USE_MAPILLARY_FILTER.get()) {
textView.setText(selectedUsername); textView.setText(selectedUsername);
textView.setSelection(selectedUsername.length()); textView.setSelection(selectedUsername.length());
} }
@ -398,20 +370,25 @@ public class ContextMenuAdapter {
@Override @Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
((View)textView.getParent().getParent()).findViewById(R.id.warning_linear_layout).setVisibility(View.GONE);
} }
@Override @Override
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
app.getSettings().MAPILLARY_FILTER_USERNAME.set(editable.toString());
} }
}); });
ImageView imageView = (ImageView) ((View) textView.getParent().getParent()).findViewById(R.id.warning_image_view);
imageView.setImageDrawable(mIconsCache.getPaintedIcon(R.drawable.ic_small_warning,
app.getResources().getColor(R.color.color_warning)));
} }
final View dateFromEditText = convertView.findViewById(R.id.date_from_edit_text); final View dateFromEditText = convertView.findViewById(R.id.date_from_edit_text);
if (dateFromEditText != null) { if (dateFromEditText != null) {
final EditText dateFrom = (EditText) dateFromEditText; final EditText dateFrom = (EditText) dateFromEditText;
final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
final OsmandSettings settings = app.getSettings();
final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
@Override @Override
@ -421,7 +398,7 @@ public class ContextMenuAdapter {
from.set(Calendar.MONTH, monthOfYear); from.set(Calendar.MONTH, monthOfYear);
from.set(Calendar.DAY_OF_MONTH, dayOfMonth); from.set(Calendar.DAY_OF_MONTH, dayOfMonth);
dateFrom.setText(dateFormat.format(from.getTime())); dateFrom.setText(dateFormat.format(from.getTime()));
app.getSettings().MAPILLARY_FILTER_FROM_DATE.set(from.getTimeInMillis()); settings.MAPILLARY_FILTER_FROM_DATE.set(from.getTimeInMillis());
} }
}; };
@ -436,9 +413,11 @@ public class ContextMenuAdapter {
} }
}); });
long from = app.getSettings().MAPILLARY_FILTER_FROM_DATE.get(); if (settings.USE_MAPILLARY_FILTER.get()) {
if (from != 0) { long from = settings.MAPILLARY_FILTER_FROM_DATE.get();
dateFrom.setText(dateFormat.format(new Date(from))); if (from != 0) {
dateFrom.setText(dateFormat.format(new Date(from)));
}
} }
dateFrom.setCompoundDrawablesWithIntrinsicBounds(null, null, dateFrom.setCompoundDrawablesWithIntrinsicBounds(null, null,
mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null); mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null);
@ -448,6 +427,7 @@ public class ContextMenuAdapter {
if (dateToEditText != null) { if (dateToEditText != null) {
final EditText dateTo = (EditText) dateToEditText; final EditText dateTo = (EditText) dateToEditText;
final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM); final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
final OsmandSettings settings = app.getSettings();
final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() { final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
@Override @Override
@ -457,7 +437,7 @@ public class ContextMenuAdapter {
to.set(Calendar.MONTH, monthOfYear); to.set(Calendar.MONTH, monthOfYear);
to.set(Calendar.DAY_OF_MONTH, dayOfMonth); to.set(Calendar.DAY_OF_MONTH, dayOfMonth);
dateTo.setText(dateFormat.format(to.getTime())); dateTo.setText(dateFormat.format(to.getTime()));
app.getSettings().MAPILLARY_FILTER_TO_DATE.set(to.getTimeInMillis()); settings.MAPILLARY_FILTER_TO_DATE.set(to.getTimeInMillis());
} }
}; };
@ -472,9 +452,11 @@ public class ContextMenuAdapter {
} }
}); });
long to = app.getSettings().MAPILLARY_FILTER_TO_DATE.get(); if (settings.USE_MAPILLARY_FILTER.get()) {
if (to != 0) { long to = settings.MAPILLARY_FILTER_TO_DATE.get();
dateTo.setText(dateFormat.format(new Date(to))); if (to != 0) {
dateTo.setText(dateFormat.format(new Date(to)));
}
} }
dateTo.setCompoundDrawablesWithIntrinsicBounds(null, null, dateTo.setCompoundDrawablesWithIntrinsicBounds(null, null,
mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null); mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null);
@ -492,11 +474,11 @@ public class ContextMenuAdapter {
String dateTo = ((EditText) list.findViewById(R.id.date_to_edit_text)).getText().toString(); String dateTo = ((EditText) list.findViewById(R.id.date_to_edit_text)).getText().toString();
OsmandSettings settings = app.getSettings(); OsmandSettings settings = app.getSettings();
if (!username.equals("") || !dateFrom.equals("") || !dateTo.equals("")) { if (!settings.MAPILLARY_FILTER_USERNAME.get().equals("") || !dateFrom.equals("") || !dateTo.equals("")) {
settings.USE_MAPILLARY_FILTER.set(true); settings.USE_MAPILLARY_FILTER.set(true);
} }
if (username.equals("")) { if (!username.equals("") && settings.MAPILLARY_FILTER_USERNAME.get().equals("")) {
settings.MAPILLARY_FILTER_USERNAME.set(""); list.findViewById(R.id.warning_linear_layout).setVisibility(View.VISIBLE);
} }
if (dateFrom.equals("")) { if (dateFrom.equals("")) {
settings.MAPILLARY_FILTER_FROM_DATE.set(0L); settings.MAPILLARY_FILTER_FROM_DATE.set(0L);
@ -522,6 +504,7 @@ public class ContextMenuAdapter {
((EditText) list.findViewById(R.id.date_to_edit_text)).setText(""); ((EditText) list.findViewById(R.id.date_to_edit_text)).setText("");
settings.USE_MAPILLARY_FILTER.set(false); settings.USE_MAPILLARY_FILTER.set(false);
settings.MAPILLARY_FILTER_USER_KEY.set("");
settings.MAPILLARY_FILTER_USERNAME.set(""); settings.MAPILLARY_FILTER_USERNAME.set("");
settings.MAPILLARY_FILTER_FROM_DATE.set(0L); settings.MAPILLARY_FILTER_FROM_DATE.set(0L);
settings.MAPILLARY_FILTER_TO_DATE.set(0L); settings.MAPILLARY_FILTER_TO_DATE.set(0L);

View file

@ -706,6 +706,7 @@ public class OsmandSettings {
public final CommonPreference<RulerMode> RULER_MODE = new EnumIntPreference<>("ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal(); public final CommonPreference<RulerMode> RULER_MODE = new EnumIntPreference<>("ruler_mode", RulerMode.FIRST, RulerMode.values()).makeGlobal();
public final CommonPreference<Boolean> USE_MAPILLARY_FILTER = new BooleanPreference("use_mapillary_filters", false).makeGlobal(); public final CommonPreference<Boolean> USE_MAPILLARY_FILTER = new BooleanPreference("use_mapillary_filters", false).makeGlobal();
public final CommonPreference<String> MAPILLARY_FILTER_USER_KEY = new StringPreference("mapillary_filter_user_key", "").makeGlobal();
public final CommonPreference<String> MAPILLARY_FILTER_USERNAME = new StringPreference("mapillary_filter_username", "").makeGlobal(); public final CommonPreference<String> MAPILLARY_FILTER_USERNAME = new StringPreference("mapillary_filter_username", "").makeGlobal();
public final CommonPreference<Long> MAPILLARY_FILTER_FROM_DATE = new LongPreference("mapillary_filter_from_date", 0).makeGlobal(); public final CommonPreference<Long> MAPILLARY_FILTER_FROM_DATE = new LongPreference("mapillary_filter_from_date", 0).makeGlobal();
public final CommonPreference<Long> MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal(); public final CommonPreference<Long> MAPILLARY_FILTER_TO_DATE = new LongPreference("mapillary_filter_to_date", 0).makeGlobal();

View file

@ -0,0 +1,181 @@
package net.osmand.plus.mapillary;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Build;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.osm.io.NetworkUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
public class MapillaryAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private static final String TAG = MapillaryAutoCompleteAdapter.class.getSimpleName();
private ArrayList<String> names;
private OsmandApplication app;
private boolean wrong;
public MapillaryAutoCompleteAdapter(@NonNull Context context, @LayoutRes int resource, OsmandApplication app) {
super(context, resource);
names = new ArrayList<>();
this.app = app;
}
@Override
public int getCount() {
return names.size();
}
@Nullable
@Override
public String getItem(int position) {
return names.get(position);
}
@NonNull
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
try {
Pair<String, String> user = new GetMapillaryUserAsyncTask().execute(constraint.toString()).get();
names.clear();
OsmandSettings settings = app.getSettings();
if (!settings.isInternetConnectionAvailable()) {
names.add(app.getResources().getString(R.string.no_inet_connection));
wrong = true;
} else if (user != null) {
settings.MAPILLARY_FILTER_USER_KEY.set(user.first);
settings.MAPILLARY_FILTER_USERNAME.set(user.second);
names.add(user.second);
wrong = false;
} else {
settings.MAPILLARY_FILTER_USER_KEY.set("");
settings.MAPILLARY_FILTER_USERNAME.set("");
names.add(getContext().getResources().getString(R.string.wrong_user_name));
wrong = true;
}
} catch (InterruptedException e) {
Log.e(TAG, e.toString());
} catch (ExecutionException e) {
Log.e(TAG, e.toString());
}
filterResults.values = names;
filterResults.count = names.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(getContext());
final View view = inflater.inflate(R.layout.auto_complete_suggestion, parent, false);
TextView nameTv = (TextView) view.findViewById(R.id.title);
ImageView iconIv = (ImageView) view.findViewById(R.id.icon);
nameTv.setText(names.get(position));
if (wrong) {
Drawable icon = app.getIconsCache().getPaintedIcon(R.drawable.ic_warning, app.getResources().getColor(R.color.color_warning));
iconIv.setImageDrawable(icon);
iconIv.setVisibility(View.VISIBLE);
}
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = getContext().getTheme();
theme.resolveAttribute(android.R.attr.textColorSecondary, typedValue, true);
nameTv.setTextColor(typedValue.data);
}
return view;
}
private class GetMapillaryUserAsyncTask extends AsyncTask<String, Void, Pair<String, String>> {
private final String TAG = GetMapillaryUserAsyncTask.class.getSimpleName();
private static final String DOWNLOAD_PATH = "https://a.mapillary.com/v3/users?usernames=%s&client_id=%s";
private static final String CLIENT_ID = "LXJVNHlDOGdMSVgxZG5mVzlHQ3ZqQTo0NjE5OWRiN2EzNTFkNDg4";
@Override
protected Pair<String, String> doInBackground(String... params) {
try {
URL url = new URL(String.format(DOWNLOAD_PATH, params[0], CLIENT_ID));
URLConnection conn = NetworkUtils.getHttpURLConnection(url);
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder json = new StringBuilder(1024);
String tmp;
while ((tmp = reader.readLine()) != null) {
json.append(tmp).append("\n");
}
reader.close();
JSONArray data = new JSONArray(json.toString());
if (data.length() > 0) {
JSONObject user = data.getJSONObject(0);
String name = user.getString("username");
String key = user.getString("key");
if (name != null && key != null) {
return new Pair<>(key, name);
}
}
} catch (MalformedURLException e) {
Log.e(TAG, "Unable to create url", e);
} catch (IOException e) {
Log.e(TAG, "Unable to open connection", e);
} catch (JSONException e) {
Log.e(TAG, "Unable to create json", e);
}
return null;
}
}
}