Finish UI for Mapillary Filters
This commit is contained in:
parent
948925eb3e
commit
6c03572c25
6 changed files with 264 additions and 45 deletions
29
OsmAnd/res/layout/auto_complete_suggestion.xml
Normal file
29
OsmAnd/res/layout/auto_complete_suggestion.xml
Normal 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>
|
|
@ -26,6 +26,30 @@
|
|||
tools:text="Username" />
|
||||
</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
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
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
|
||||
-->
|
||||
<string name="wrong_user_name">Wrong user name!</string>
|
||||
<string name="shared_string_to">To</string>
|
||||
<string name="mapillary_menu_date_from">From</string>
|
||||
<string name="mapillary_menu_descr_dates">View images added in a certain period.</string>
|
||||
|
|
|
@ -3,10 +3,8 @@ package net.osmand.plus;
|
|||
import android.app.Activity;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.IdRes;
|
||||
|
@ -15,7 +13,6 @@ import android.support.v4.app.FragmentActivity;
|
|||
import android.support.v7.widget.AppCompatImageView;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.TypedValue;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.View;
|
||||
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.dialogs.ConfigureMapMenu;
|
||||
import net.osmand.plus.dialogs.HelpArticleDialogFragment;
|
||||
import net.osmand.plus.mapillary.MapillaryAutoCompleteAdapter;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
|
@ -44,7 +42,6 @@ import java.text.DateFormat;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
@ -356,36 +353,11 @@ public class ContextMenuAdapter {
|
|||
|
||||
final View autoCompleteTextView = convertView.findViewById(R.id.auto_complete_text_view);
|
||||
if (autoCompleteTextView != null) {
|
||||
AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView;
|
||||
final ArrayAdapter<String> adapter;
|
||||
|
||||
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);
|
||||
final AutoCompleteTextView textView = (AutoCompleteTextView) autoCompleteTextView;
|
||||
textView.setAdapter(new MapillaryAutoCompleteAdapter(getContext(), R.layout.auto_complete_suggestion, app));
|
||||
|
||||
String selectedUsername = app.getSettings().MAPILLARY_FILTER_USERNAME.get();
|
||||
if (!selectedUsername.equals("")) {
|
||||
if (!selectedUsername.equals("") && app.getSettings().USE_MAPILLARY_FILTER.get()) {
|
||||
textView.setText(selectedUsername);
|
||||
textView.setSelection(selectedUsername.length());
|
||||
}
|
||||
|
@ -398,20 +370,25 @@ public class ContextMenuAdapter {
|
|||
|
||||
@Override
|
||||
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
|
||||
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);
|
||||
if (dateFromEditText != null) {
|
||||
final EditText dateFrom = (EditText) dateFromEditText;
|
||||
final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
|
||||
final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
|
||||
@Override
|
||||
|
@ -421,7 +398,7 @@ public class ContextMenuAdapter {
|
|||
from.set(Calendar.MONTH, monthOfYear);
|
||||
from.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
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()) {
|
||||
long from = settings.MAPILLARY_FILTER_FROM_DATE.get();
|
||||
if (from != 0) {
|
||||
dateFrom.setText(dateFormat.format(new Date(from)));
|
||||
}
|
||||
}
|
||||
dateFrom.setCompoundDrawablesWithIntrinsicBounds(null, null,
|
||||
mIconsCache.getThemedIcon(R.drawable.ic_action_arrow_drop_down), null);
|
||||
|
@ -448,6 +427,7 @@ public class ContextMenuAdapter {
|
|||
if (dateToEditText != null) {
|
||||
final EditText dateTo = (EditText) dateToEditText;
|
||||
final DateFormat dateFormat = SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
|
||||
final OsmandSettings settings = app.getSettings();
|
||||
|
||||
final DatePickerDialog.OnDateSetListener date = new DatePickerDialog.OnDateSetListener() {
|
||||
@Override
|
||||
|
@ -457,7 +437,7 @@ public class ContextMenuAdapter {
|
|||
to.set(Calendar.MONTH, monthOfYear);
|
||||
to.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
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()) {
|
||||
long to = settings.MAPILLARY_FILTER_TO_DATE.get();
|
||||
if (to != 0) {
|
||||
dateTo.setText(dateFormat.format(new Date(to)));
|
||||
}
|
||||
}
|
||||
dateTo.setCompoundDrawablesWithIntrinsicBounds(null, 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();
|
||||
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);
|
||||
}
|
||||
if (username.equals("")) {
|
||||
settings.MAPILLARY_FILTER_USERNAME.set("");
|
||||
if (!username.equals("") && settings.MAPILLARY_FILTER_USERNAME.get().equals("")) {
|
||||
list.findViewById(R.id.warning_linear_layout).setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (dateFrom.equals("")) {
|
||||
settings.MAPILLARY_FILTER_FROM_DATE.set(0L);
|
||||
|
@ -522,6 +504,7 @@ public class ContextMenuAdapter {
|
|||
((EditText) list.findViewById(R.id.date_to_edit_text)).setText("");
|
||||
|
||||
settings.USE_MAPILLARY_FILTER.set(false);
|
||||
settings.MAPILLARY_FILTER_USER_KEY.set("");
|
||||
settings.MAPILLARY_FILTER_USERNAME.set("");
|
||||
settings.MAPILLARY_FILTER_FROM_DATE.set(0L);
|
||||
settings.MAPILLARY_FILTER_TO_DATE.set(0L);
|
||||
|
|
|
@ -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<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<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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue