[android] Added map layers buttons to main menu header

This commit is contained in:
Александр Зацепин 2020-04-20 17:11:01 +03:00 committed by yoksnod
parent f7118b1696
commit 9e3e5f8040
8 changed files with 262 additions and 119 deletions

View file

@ -7,6 +7,25 @@
android:layout_marginTop="@dimen/margin_half"
android:layout_marginBottom="@dimen/margin_half"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="@dimen/margin_base">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/layers_title"
android:textAppearance="?fontHeadline6"
android:textStyle="bold" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/layers_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="@dimen/margin_base_plus"
android:minHeight="@dimen/toggle_map_layer_frame_height" />
</LinearLayout>
<TextView
android:id="@+id/add_place"
style="@style/MwmTheme.Menu.Content.ListItem"

View file

@ -2829,5 +2829,23 @@ public class MwmActivity extends BaseMwmFragmentActivity
Statistics.INSTANCE.trackToolbarMenu(MainMenu.Item.SHARE_MY_LOCATION);
closeMenu(MwmActivity.this::shareMyLocation);
}
@Override
public void onSubwayLayerOptionSelected()
{
onSubwayLayerSelected();
}
@Override
public void onTrafficLayerOptionSelected()
{
onTrafficLayerSelected();
}
@Override
public void onIsolinesLayerOptionSelected()
{
onIsolinesLayerSelected();
}
}
}

View file

@ -0,0 +1,50 @@
package com.mapswithme.maps.maplayer;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.adapter.OnItemClickListener;
import java.util.Objects;
class LayerHolder extends RecyclerView.ViewHolder
{
@NonNull
final ImageView mButton;
@NonNull
final TextView mTitle;
@Nullable
BottomSheetItem mItem;
@Nullable
OnItemClickListener<BottomSheetItem> mListener;
LayerHolder(@NonNull View root)
{
super(root);
mButton = root.findViewById(R.id.btn);
mTitle = root.findViewById(R.id.name);
mButton.setOnClickListener(this::onItemClicked);
}
@NonNull
public BottomSheetItem getItem()
{
return Objects.requireNonNull(mItem);
}
@NonNull
public OnItemClickListener<BottomSheetItem> getListener()
{
return Objects.requireNonNull(mListener);
}
private void onItemClicked(@NonNull View v)
{
getListener().onItemClick(v, getItem());
}
}

View file

@ -0,0 +1,57 @@
package com.mapswithme.maps.maplayer;
import android.content.Context;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.adapter.OnItemClickListener;
import java.util.List;
public class LayersAdapter extends RecyclerView.Adapter<LayerHolder>
{
@NonNull
private final List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> mItems;
public LayersAdapter(@NonNull List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> modes)
{
mItems = modes;
}
@Override
public LayerHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View root = inflater.inflate(R.layout.item_bottomsheet_dialog, parent, false);
return new LayerHolder(root);
}
@Override
public void onBindViewHolder(LayerHolder holder, int position)
{
Context context = holder.itemView.getContext();
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> pair = mItems.get(position);
BottomSheetItem item = pair.first;
holder.mItem = item;
boolean isEnabled = item.getMode().isEnabled(context);
holder.mButton.setSelected(isEnabled);
holder.mTitle.setSelected(isEnabled);
holder.mTitle.setText(item.getTitle());
holder.mButton.setImageResource(isEnabled ? item.getEnabledStateDrawable()
: item.getDisabledStateDrawable());
holder.mListener = pair.second;
}
@Override
public int getItemCount()
{
return mItems.size();
}
}

View file

@ -0,0 +1,31 @@
package com.mapswithme.maps.maplayer;
import android.content.Context;
import android.util.Pair;
import androidx.annotation.NonNull;
import com.mapswithme.maps.adapter.OnItemClickListener;
import java.util.Arrays;
import java.util.List;
public class LayersUtils
{
@NonNull
public static List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> createItems(
@NonNull Context context, @NonNull OnItemClickListener<BottomSheetItem> subwayListener,
@NonNull OnItemClickListener<BottomSheetItem> trafficListener,
@NonNull OnItemClickListener<BottomSheetItem> isoLinesListener)
{
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> subway
= new Pair<>(BottomSheetItem.Subway.makeInstance(context), subwayListener);
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> traffic
= new Pair<>(BottomSheetItem.Traffic.makeInstance(context), trafficListener);
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> isoLines
= new Pair<>(BottomSheetItem.Isolines.makeInstance(context), isoLinesListener);
return Arrays.asList(traffic, isoLines, subway);
}
}

View file

@ -1,48 +1,40 @@
package com.mapswithme.maps.maplayer;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetBehavior;
import com.google.android.material.bottomsheet.BottomSheetDialog;
import com.mapswithme.maps.R;
import com.mapswithme.maps.adapter.OnItemClickListener;
import com.mapswithme.maps.maplayer.subway.OnSubwayLayerToggleListener;
import com.mapswithme.maps.maplayer.traffic.OnTrafficLayerToggleListener;
import com.mapswithme.maps.widget.recycler.SpanningLinearLayoutManager;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class ToggleMapLayerDialog extends DialogFragment
{
@NonNull
@SuppressWarnings("NullableProblems")
private ModeAdapter mAdapter;
private LayersAdapter mAdapter;
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
BottomSheetDialog dialog = new BottomSheetDialog(getActivity());
LayoutInflater inflater = getActivity().getLayoutInflater();
BottomSheetDialog dialog = new BottomSheetDialog(requireActivity());
LayoutInflater inflater = requireActivity().getLayoutInflater();
View root = inflater.inflate(R.layout.fragment_toggle_map_layer, null, false);
dialog.setOnShowListener(this::onShow);
dialog.setContentView(root);
@ -73,32 +65,16 @@ public class ToggleMapLayerDialog extends DialogFragment
private void initRecycler(@NonNull View root)
{
RecyclerView recycler = root.findViewById(R.id.recycler);
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(getContext(),
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(requireContext(),
LinearLayoutManager.HORIZONTAL,
false);
recycler.setLayoutManager(layoutManager);
mAdapter = new ModeAdapter(createItems());
mAdapter = new LayersAdapter(LayersUtils.createItems(requireContext(), new SubwayItemClickListener(),
new TrafficItemClickListener(),
new IsolinesItemClickListener()));
recycler.setAdapter(mAdapter);
}
@NonNull
private List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> createItems()
{
SubwayItemClickListener subwayListener = new SubwayItemClickListener();
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> subway
= new Pair<>(BottomSheetItem.Subway.makeInstance(getContext()), subwayListener);
TrafficItemClickListener trafficListener = new TrafficItemClickListener();
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> traffic
= new Pair<>(BottomSheetItem.Traffic.makeInstance(getContext()), trafficListener);
IsolinesItemClickListener isoLinesListener = new IsolinesItemClickListener();
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> isoLines
= new Pair<>(BottomSheetItem.Isolines.makeInstance(getContext()), isoLinesListener);
return Arrays.asList(traffic, isoLines, subway);
}
public static void show(@NonNull AppCompatActivity activity)
{
ToggleMapLayerDialog frag = new ToggleMapLayerDialog();
@ -113,91 +89,12 @@ public class ToggleMapLayerDialog extends DialogFragment
fm.executePendingTransactions();
}
private static class ModeAdapter extends RecyclerView.Adapter<ModeHolder>
{
@NonNull
private final List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> mItems;
private ModeAdapter(@NonNull List<Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>>> modes)
{
mItems = modes;
}
@Override
public ModeHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View root = inflater.inflate(R.layout.item_bottomsheet_dialog, parent, false);
return new ModeHolder(root);
}
@Override
public void onBindViewHolder(ModeHolder holder, int position)
{
Context context = holder.itemView.getContext();
Pair<BottomSheetItem, OnItemClickListener<BottomSheetItem>> pair = mItems.get(position);
BottomSheetItem item = pair.first;
holder.mItem = item;
boolean isEnabled = item.getMode().isEnabled(context);
holder.mButton.setSelected(isEnabled);
holder.mTitle.setSelected(isEnabled);
holder.mTitle.setText(item.getTitle());
holder.mButton.setImageResource(isEnabled ? item.getEnabledStateDrawable()
: item.getDisabledStateDrawable());
holder.mListener = pair.second;
}
@Override
public int getItemCount()
{
return mItems.size();
}
}
private static class ModeHolder extends RecyclerView.ViewHolder
{
@NonNull
private final ImageView mButton;
@NonNull
private final TextView mTitle;
@Nullable
private BottomSheetItem mItem;
@Nullable
private OnItemClickListener<BottomSheetItem> mListener;
ModeHolder(@NonNull View root)
{
super(root);
mButton = root.findViewById(R.id.btn);
mTitle = root.findViewById(R.id.name);
mButton.setOnClickListener(this::onItemClicked);
}
@NonNull
public BottomSheetItem getItem()
{
return Objects.requireNonNull(mItem);
}
@NonNull
public OnItemClickListener<BottomSheetItem> getListener()
{
return Objects.requireNonNull(mListener);
}
private void onItemClicked(@NonNull View v)
{
getListener().onItemClick(v, getItem());
}
}
private abstract class DefaultClickListener implements OnItemClickListener<BottomSheetItem>
{
@Override
public final void onItemClick(@NonNull View v, @NonNull BottomSheetItem item)
{
item.getMode().toggle(getContext());
item.getMode().toggle(requireContext());
onItemClickInternal(v, item);
mAdapter.notifyDataSetChanged();
}
@ -210,7 +107,7 @@ public class ToggleMapLayerDialog extends DialogFragment
@Override
void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
OnSubwayLayerToggleListener listener = (OnSubwayLayerToggleListener) getActivity();
OnSubwayLayerToggleListener listener = (OnSubwayLayerToggleListener) requireActivity();
listener.onSubwayLayerSelected();
}
}
@ -220,7 +117,7 @@ public class ToggleMapLayerDialog extends DialogFragment
@Override
void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
OnTrafficLayerToggleListener listener = (OnTrafficLayerToggleListener) getActivity();
OnTrafficLayerToggleListener listener = (OnTrafficLayerToggleListener) requireActivity();
listener.onTrafficLayerSelected();
}
}

View file

@ -8,4 +8,7 @@ public interface MainMenuOptionListener
void onDownloadMapsOptionSelected();
void onSettingsOptionSelected();
void onShareLocationOptionSelected();
void onSubwayLayerOptionSelected();
void onTrafficLayerOptionSelected();
void onIsolinesLayerOptionSelected();
}

View file

@ -4,7 +4,14 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.mapswithme.maps.R;
import com.mapswithme.maps.adapter.OnItemClickListener;
import com.mapswithme.maps.maplayer.BottomSheetItem;
import com.mapswithme.maps.maplayer.LayersUtils;
import com.mapswithme.maps.maplayer.LayersAdapter;
import com.mapswithme.maps.widget.recycler.SpanningLinearLayoutManager;
import java.util.Objects;
@ -12,6 +19,12 @@ public class MainMenuRenderer implements MenuRenderer
{
@NonNull
private final MainMenuOptionListener mListener;
@SuppressWarnings("NullableProblems")
@NonNull
private RecyclerView mLayersRecycler;
@NonNull
@SuppressWarnings("NullableProblems")
private LayersAdapter mLayersAdapter;
MainMenuRenderer(@NonNull MainMenuOptionListener listener)
{
@ -28,6 +41,7 @@ public class MainMenuRenderer implements MenuRenderer
public void initialize(@Nullable View view)
{
Objects.requireNonNull(view);
initLayersRecycler(view);
View addPlace = view.findViewById(R.id.add_place);
addPlace.setOnClickListener(v -> mListener.onAddPlaceOptionSelected());
View downloadGuides = view.findViewById(R.id.download_guides);
@ -42,9 +56,63 @@ public class MainMenuRenderer implements MenuRenderer
share.setOnClickListener(v -> mListener.onShareLocationOptionSelected());
}
private void initLayersRecycler(@NonNull View view)
{
mLayersRecycler = view.findViewById(R.id.layers_recycler);
RecyclerView.LayoutManager layoutManager = new SpanningLinearLayoutManager(mLayersRecycler.getContext(),
LinearLayoutManager.HORIZONTAL,
false);
mLayersRecycler.setLayoutManager(layoutManager);
mLayersAdapter = new LayersAdapter(LayersUtils.createItems(mLayersRecycler.getContext(),
new SubwayItemClickListener(),
new TrafficItemClickListener(),
new IsolinesItemClickListener()));
mLayersRecycler.setAdapter(mLayersAdapter);
}
@Override
public void destroy()
{
// TODO: Implement.
}
private abstract class DefaultClickListener implements OnItemClickListener<BottomSheetItem>
{
@Override
public final void onItemClick(@NonNull View v, @NonNull BottomSheetItem item)
{
item.getMode().toggle(v.getContext());
onItemClickInternal(v, item);
mLayersAdapter.notifyDataSetChanged();
}
abstract void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item);
}
private class SubwayItemClickListener extends DefaultClickListener
{
@Override
void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mListener.onSubwayLayerOptionSelected();
}
}
private class TrafficItemClickListener extends DefaultClickListener
{
@Override
void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mListener.onTrafficLayerOptionSelected();
}
}
private class IsolinesItemClickListener extends DefaultClickListener
{
@Override
void onItemClickInternal(@NonNull View v, @NonNull BottomSheetItem item)
{
mListener.onIsolinesLayerOptionSelected();
}
}
}