[android] Edit cuisine.

This commit is contained in:
Dmitry Yunitsky 2016-01-28 20:20:31 +03:00 committed by Sergey Yershov
parent bfa4d51762
commit d7a10cffa8
10 changed files with 311 additions and 27 deletions

View file

@ -77,8 +77,8 @@
tools:ignore="UnusedAttribute"/>
<RelativeLayout
style="@style/MwmWidget.Editor.MetadataBlock"
android:background="?clickableBackground"
android:id="@+id/block_street"
style="@style/MwmWidget.Editor.MetadataBlock.Clickable"
android:paddingBottom="@dimen/margin_half"
android:paddingTop="@dimen/margin_half">
@ -100,7 +100,6 @@
style="@style/MwmWidget.Editor.FieldLayout"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/margin_base"
android:background="?clickableBackground"
android:drawableEnd="@drawable/ic_arrow_down"
android:drawableRight="@drawable/ic_arrow_down"
android:gravity="center_vertical"
@ -252,7 +251,7 @@
<RelativeLayout
android:id="@+id/block_cuisine"
style="@style/MwmWidget.Editor.MetadataBlock"
style="@style/MwmWidget.Editor.MetadataBlock.Clickable"
android:paddingBottom="@dimen/margin_half"
android:paddingTop="@dimen/margin_half">
@ -265,6 +264,7 @@
style="@style/MwmWidget.Editor.FieldLayout"
android:layout_alignParentBottom="true"
android:layout_marginBottom="@dimen/margin_base"
android:drawableEnd="@drawable/ic_arrow_down"
android:drawableRight="@drawable/ic_arrow_down"
android:gravity="center_vertical"
android:textAppearance="@style/MwmTextAppearance.Body1"
@ -283,8 +283,7 @@
<RelativeLayout
android:id="@+id/block_wifi"
style="@style/MwmWidget.Editor.MetadataBlock"
android:background="?clickableBackground">
style="@style/MwmWidget.Editor.MetadataBlock.Clickable">
<ImageView
style="@style/MwmWidget.Editor.MetadataIcon"

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/height_item_oneline"
android:background="?clickableBackground"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="@dimen/margin_base">
<CheckBox
android:id="@+id/selected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_double"
android:layout_marginRight="@dimen/margin_double"/>
<TextView
android:id="@+id/cuisine"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:textAppearance="@style/MwmTextAppearance.Body1"/>
</LinearLayout>

View file

@ -23,6 +23,10 @@
<item name="android:layout_marginBottom">@dimen/margin_base</item>
</style>
<style name="MwmWidget.Editor.MetadataBlock.Clickable">
<item name="android:background">?clickableBackground</item>
</style>
<style name="MwmWidget.Editor.MetadataIcon">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
@ -53,6 +57,8 @@
<style name="MwmWidget.Editor.FieldLayout">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:lines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:layout_marginLeft">@dimen/editor_margin_left</item>
<item name="android:layout_marginStart" tools:targetApi="jelly_bean_mr1">@dimen/editor_margin_left</item>
</style>

View file

@ -140,25 +140,24 @@ public class MapObject implements Parcelable
* @return properly formatted and translated cuisine string.
*/
@NonNull
public String getCuisine()
public String getFormattedCuisine()
{
final String rawCuisine = mMetadata.getMetadata(Metadata.MetadataType.FMD_CUISINE);
if (TextUtils.isEmpty(rawCuisine))
final String rawCuisines = mMetadata.getMetadata(Metadata.MetadataType.FMD_CUISINE);
if (TextUtils.isEmpty(rawCuisines))
return "";
// cuisines translations can contain unsupported symbols, and res ids
// replace them with supported "_"( so ', ' and ' ' are replaced with underlines)
final String[] cuisines = rawCuisine.split(";");
String result = "";
final StringBuilder result = new StringBuilder();
// search translations for each cuisine
final Resources resources = MwmApplication.get().getResources();
for (String cuisineRaw : cuisines)
for (String rawCuisine : Metadata.splitCuisines(rawCuisines))
{
final String cuisineKey = cuisineRaw.replace(", ", "_").replace(' ', '_').toLowerCase();
int resId = resources.getIdentifier("cuisine_" + cuisineKey, "string", BuildConfig.APPLICATION_ID);
result += resId == 0 ? cuisineRaw : resources.getString(resId);
int resId = resources.getIdentifier(Metadata.osmCuisineToStringName(Metadata.normalizeCuisine(rawCuisine)), "string", BuildConfig.APPLICATION_ID);
if (result.length() > 0)
result.append(", ");
result.append(resId == 0 ? rawCuisine : resources.getString(resId));
}
return result;
return result.toString();
}
public String getStreet()

View file

@ -60,8 +60,58 @@ public class Metadata implements Parcelable
}
}
private static final String CUISINE_TRANSLATION_PREFIX = "cuisine_";
private Map<MetadataType, String> mMetadataMap = new HashMap<>();
public static String osmCuisineToStringName(String cuisineKey)
{
return CUISINE_TRANSLATION_PREFIX + cuisineKey;
}
public static String stringNameToOsmCuisine(String cuisineTranslation)
{
return cuisineTranslation.replace(CUISINE_TRANSLATION_PREFIX, "");
}
public static boolean isCuisineString(String cuisineTranslation)
{
return cuisineTranslation.startsWith(CUISINE_TRANSLATION_PREFIX);
}
/**
* Cuisines translations can contain unsupported symbols,
* replace them with supported "_"( so ', ' and ' ' are replaced with underlines)
*/
public static String normalizeCuisine(String cuisineRaw)
{
return cuisineRaw.replace(", ", "_").replace(' ', '_').toLowerCase();
}
/**
* Splits cuisine from osm format.
*/
public static String[] splitCuisines(String cuisines)
{
return cuisines.split(";");
}
/**
* Combines cuisines to osm format.
*/
public static String combineCuisines(@NonNull String[] cuisines)
{
final StringBuilder builder = new StringBuilder();
for (String cuisine : cuisines)
{
if (builder.length() > 0)
builder.append(";");
builder.append(cuisine);
}
return builder.toString();
}
/**
* Adds metadata with type code and value. Returns false if metaType is wrong or unknown
*

View file

@ -0,0 +1,156 @@
package com.mapswithme.maps.editor;
import android.content.res.Resources;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.Metadata;
public class CuisineAdapter extends RecyclerView.Adapter<CuisineAdapter.ViewHolder>
{
private static class Item implements Comparable<Item>
{
String translatedCuisine;
String cuisineStringName;
boolean selected;
public Item(String cuisine, String cuisineKey, boolean selected)
{
this.translatedCuisine = cuisine;
this.cuisineStringName = cuisineKey;
this.selected = selected;
}
@Override
public int compareTo(@NonNull Item another)
{
return translatedCuisine.compareTo(another.translatedCuisine);
}
}
private List<Item> mTranslatedItems;
private List<Item> mItems;
public CuisineAdapter(@NonNull String cuisine)
{
initAllCuisinesFromStrings();
String[] selectedCuisines = Metadata.splitCuisines(cuisine);
Arrays.sort(selectedCuisines);
mItems = new ArrayList<>(mTranslatedItems.size());
for (Item item : mTranslatedItems)
{
final String cuisineString = item.translatedCuisine;
mItems.add(new Item(cuisineString, item.cuisineStringName,
Arrays.binarySearch(selectedCuisines, Metadata.stringNameToOsmCuisine(item.cuisineStringName)) >= 0));
}
}
private void initAllCuisinesFromStrings()
{
if (mTranslatedItems != null)
return;
mTranslatedItems = new ArrayList<>();
final Resources resources = MwmApplication.get().getResources();
for (Field stringField : R.string.class.getDeclaredFields())
{
try
{
final String fieldName = stringField.getName();
if (Metadata.isCuisineString(fieldName))
{
int resId = stringField.getInt(stringField);
final String cuisine = resources.getString(resId);
mTranslatedItems.add(new Item(cuisine, fieldName, false));
}
} catch (IllegalAccessException ignored) { }
}
Collections.sort(mTranslatedItems);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_cuisine, parent, false));
}
@Override
public void onBindViewHolder(ViewHolder holder, int position)
{
holder.bind(position);
}
@Override
public int getItemCount()
{
return mTranslatedItems.size();
}
public String getCuisine()
{
final List<String> selectedList = new ArrayList<>();
for (Item item : mItems)
{
if (item.selected)
selectedList.add(Metadata.stringNameToOsmCuisine(item.cuisineStringName));
}
String[] cuisines = new String[selectedList.size()];
cuisines = selectedList.toArray(cuisines);
return Metadata.combineCuisines(cuisines);
}
protected class ViewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener
{
final TextView cuisine;
final CheckBox selected;
public ViewHolder(View itemView)
{
super(itemView);
cuisine = (TextView) itemView.findViewById(R.id.cuisine);
selected = (CheckBox) itemView.findViewById(R.id.selected);
selected.setOnCheckedChangeListener(this);
itemView.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
selected.toggle();
}
});
}
public void bind(int position)
{
final String text = mTranslatedItems.get(position).translatedCuisine;
cuisine.setText(text);
selected.setOnCheckedChangeListener(null);
selected.setChecked(mItems.get(position).selected);
selected.setOnCheckedChangeListener(this);
}
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
Item item = mItems.get(getAdapterPosition());
item.selected = isChecked;
}
}
}

View file

@ -0,0 +1,36 @@
package com.mapswithme.maps.editor;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.base.BaseMwmRecyclerFragment;
public class CuisineFragment extends BaseMwmRecyclerFragment
{
public static final String EXTRA_CURRENT_CUISINE = "Cuisine";
private String mCurrentCuisine;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mCurrentCuisine = getArguments().getString(EXTRA_CURRENT_CUISINE, "");
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
protected RecyclerView.Adapter createAdapter()
{
return new CuisineAdapter(mCurrentCuisine);
}
@NonNull
public String getCuisine()
{
return ((CuisineAdapter) getAdapter()).getCuisine();
}
}

View file

@ -72,7 +72,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
mEtPhone.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER));
mEtWebsite.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_WEBSITE));
mEtEmail.setText(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_EMAIL));
mTvCuisine.setText(mEditedPoi.getCuisine());
mTvCuisine.setText(mEditedPoi.getFormattedCuisine());
mSwWifi.setChecked(!TextUtils.isEmpty(mEditedPoi.getMetadata(Metadata.MetadataType.FMD_INTERNET)));
refreshOpeningTime();
@ -208,8 +208,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
mAddressBlock = view.findViewById(R.id.cv__address);
mMetadataBlock = view.findViewById(R.id.cv__metadata);
mEtName = findInput(view.findViewById(R.id.name));
view.findViewById(R.id.block_street).setOnClickListener(this);
mTvStreet = (TextView) view.findViewById(R.id.street);
mTvStreet.setOnClickListener(this);
mEtHouseNumber = findInput(view.findViewById(R.id.building));
mPhoneBlock = view.findViewById(R.id.block_phone);
mEtPhone = findInput(mPhoneBlock);
@ -218,6 +218,7 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
mEmailBlock = view.findViewById(R.id.block_email);
mEtEmail = findInput(mEmailBlock);
mCuisineBlock = view.findViewById(R.id.block_cuisine);
mCuisineBlock.setOnClickListener(this);
mTvCuisine = (TextView) view.findViewById(R.id.tv__cuisine);
mWifiBlock = view.findViewById(R.id.block_wifi);
mSwWifi = (SwitchCompat) view.findViewById(R.id.sw__wifi);
@ -245,9 +246,12 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
case R.id.block_wifi:
mSwWifi.toggle();
break;
case R.id.street:
case R.id.block_street:
mParent.editStreet();
break;
case R.id.block_cuisine:
mParent.editCuisine();
break;
}
}
}

View file

@ -110,7 +110,13 @@ public class EditorHostFragment extends BaseMwmToolbarFragment
protected void editCuisine()
{
mMode = Mode.CUISINE;
// TODO choose cuisine
mToolbarController.setTitle("Cuisine");
final Bundle args = new Bundle();
args.putString(CuisineFragment.EXTRA_CURRENT_CUISINE, mEditedObject.getMetadata(Metadata.MetadataType.FMD_CUISINE));
final Fragment cuisineFragment = Fragment.instantiate(getActivity(), CuisineFragment.class.getName(), args);
getChildFragmentManager().beginTransaction()
.replace(R.id.fragment_container, cuisineFragment, CuisineFragment.class.getName())
.commit();
}
@Override
@ -131,14 +137,16 @@ public class EditorHostFragment extends BaseMwmToolbarFragment
editMapObject();
break;
case CUISINE:
// get cuisine
final String cuisine = ((CuisineFragment) getChildFragmentManager().findFragmentByTag(CuisineFragment.class.getName())).getCuisine();
mEditedObject.addMetadata(Metadata.MetadataType.FMD_CUISINE.toInt(), cuisine);
editMapObject();
break;
case MAP_OBJECT:
final EditorFragment editorFragment = (EditorFragment) getChildFragmentManager().findFragmentByTag(EditorFragment.class.getName());
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER.toInt(), editorFragment.getPhone());
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_WEBSITE.toInt(), editorFragment.getWebsite());
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_EMAIL.toInt(), editorFragment.getEmail());
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_CUISINE.toInt(), editorFragment.getCuisine());
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_CUISINE.toInt(), mEditedObject.getMetadata(Metadata.MetadataType.FMD_CUISINE));
Editor.nativeSetMetadata(Metadata.MetadataType.FMD_INTERNET.toInt(), editorFragment.getWifi());
Editor.nativeSetName(editorFragment.getName());
Editor.nativeEditFeature(editorFragment.getStreet(), editorFragment.getHouseNumber());

View file

@ -418,8 +418,8 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene
mTvTitle.setText(mMapObject.getName());
if (mToolbar != null)
mToolbar.setTitle(mMapObject.getName());
String subtitle = mMapObject.getCuisine().isEmpty() ? mMapObject.getTypeName()
: mMapObject.getTypeName() + ", " + mMapObject.getCuisine();
String subtitle = mMapObject.getFormattedCuisine().isEmpty() ? mMapObject.getTypeName()
: mMapObject.getTypeName() + ", " + mMapObject.getFormattedCuisine();
mTvSubtitle.setText(subtitle);
mAvDirection.setVisibility(View.GONE);
}
@ -432,7 +432,7 @@ public class PlacePageView extends RelativeLayout implements View.OnClickListene
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_PHONE_NUMBER), mPhone, mTvPhone);
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_EMAIL), mEmail, mTvEmail);
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_OPERATOR), mOperator, mTvOperator);
refreshMetadataOrHide(mMapObject.getCuisine(), mCuisine, mTvCuisine);
refreshMetadataOrHide(mMapObject.getFormattedCuisine(), mCuisine, mTvCuisine);
// TODO @yunikkk uncomment wiki display when data with correct wiki representation(urlencoded once) will be ready
// refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIPEDIA), mWiki, null);
refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_INTERNET), mWifi, null);