Change multi selection menu

This commit is contained in:
PavelRatushny 2017-12-20 12:39:51 +02:00
parent 99e0bd7e71
commit c66eef9fb6
10 changed files with 303 additions and 180 deletions

View file

@ -5,16 +5,49 @@
android:layout_width="@dimen/dashboard_land_width"
android:layout_height="match_parent"
android:layout_gravity="bottom"
android:background="?attr/left_menu_view_bg"
android:orientation="vertical">
tools:background="?attr/left_menu_view_bg"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools">
<ListView
android:id="@+id/list"
<LinearLayout
android:orientation="vertical"
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="0dp">
android:layout_height="match_parent">
</ListView>
<ListView
android:clipToPadding="false"
android:paddingBottom="@dimen/bottom_sheet_content_padding_small"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="@null"
android:dividerHeight="0dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/cancel_row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_close"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -2,78 +2,68 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="?attr/expandable_list_item_background"
android:minHeight="@dimen/list_item_height"
android:orientation="horizontal"
android:orientation="vertical"
android:baselineAligned="false">
<LinearLayout
android:id="@+id/context_menu_icon_layout"
android:layout_width="42dp"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/context_menu_icon_view"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:layout_marginLeft="16dp"
android:layout_marginStart="12dp"
android:layout_marginTop="17dp"
android:src="@drawable/ic_action_building_number"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="14dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/context_menu_line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:text="@string/search_address_building"
android:maxLines="3"
android:ellipsize="end"
android:textColor="?android:textColorPrimary"
android:textSize="@dimen/default_list_text_size_large"/>
<TextView
android:id="@+id/context_menu_line2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="4dp"
android:text="@string/other_location"
android:textColor="?android:textColorSecondary"
android:textSize="@dimen/default_desc_text_size"/>
</LinearLayout>
<LinearLayout
android:id="@+id/context_menu_close_btn_layout"
android:layout_width="32dp"
android:layout_height="match_parent"
android:id="@+id/content"
android:background="?attr/expandable_list_item_background"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding"
android:orientation="horizontal"
android:visibility="gone">
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/close_btn_view"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="12dp"
android:scaleType="center"
android:src="@drawable/ic_action_remove_dark"/>
android:paddingBottom="@dimen/content_padding_small"
android:paddingTop="@dimen/list_content_padding"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/context_menu_line1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/search_address_building"
style="@style/TextAppearance.ContextMenuTitle"/>
<TextView
android:id="@+id/context_menu_line2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/context_menu_second_line_top_margin"
android:text="@string/other_location"
style="@style/TextAppearance.ContextMenuSubtitle"/>
</LinearLayout>
<LinearLayout
android:paddingTop="@dimen/list_content_padding"
android:id="@+id/context_menu_icon_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal">
<ImageView
android:id="@+id/context_menu_icon_view"
android:layout_width="@dimen/standard_icon_size"
android:layout_height="@dimen/standard_icon_size"
android:src="@drawable/ic_action_building_number"/>
</LinearLayout>
</LinearLayout>
<View
android:layout_marginLeft="@dimen/list_content_padding"
android:layout_marginStart="@dimen/list_content_padding"
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
</LinearLayout>

View file

@ -5,16 +5,49 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="?attr/bottom_menu_view_bg"
android:orientation="vertical">
tools:background="?attr/bottom_menu_view_bg"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools">
<ListView
android:id="@+id/list"
<LinearLayout
android:id="@+id/content"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@null"
android:dividerHeight="0dp">
android:layout_height="wrap_content">
</ListView>
<ListView
android:clipToPadding="false"
android:paddingBottom="@dimen/bottom_sheet_content_padding_small"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="@null"
android:dividerHeight="0dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dashboard_divider"/>
<FrameLayout
android:id="@+id/cancel_row"
android:layout_width="match_parent"
android:layout_height="@dimen/bottom_sheet_cancel_button_height"
android:background="?attr/selectableItemBackground">
<TextView
android:id="@+id/cancel_row_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/shared_string_close"
android:textAllCaps="true"
android:textColor="?attr/color_dialog_buttons"
android:textSize="@dimen/default_desc_text_size"
android:textStyle="bold"/>
</FrameLayout>
</LinearLayout>
</LinearLayout>

View file

@ -0,0 +1,20 @@
<?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/multi_selection_header_height"
xmlns:osmand="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:paddingLeft="@dimen/list_content_padding"
android:paddingRight="@dimen/list_content_padding">
<net.osmand.plus.widgets.TextViewEx
android:id="@+id/header_title"
android:textAppearance="@style/TextAppearance.ListItemTitle"
osmand:typeface="@string/font_roboto_medium"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/ctx_menu_subtitle_color"
android:text="@string/what_is_here"/>
</LinearLayout>

View file

@ -173,4 +173,6 @@
<dimen name="route_info_divider_margin">66dp</dimen>
<dimen name="route_info_modes_height">72dp</dimen>
<dimen name="multi_selection_header_height">78dp</dimen>
</resources>

View file

@ -245,4 +245,6 @@
<dimen name="route_info_icon_padding_right">16dp</dimen>
<dimen name="route_info_divider_margin">52dp</dimen>
<dimen name="route_info_modes_height">48dp</dimen>
<dimen name="multi_selection_header_height">52dp</dimen>
</resources>

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).
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="what_is_here">What\'s here:</string>
<string name="parked_at">parked at</string>
<string name="pick_up_till">Pick up till</string>
<string name="without_time_limit">Without time limit</string>

View file

@ -188,7 +188,11 @@ public class AndroidUtils {
public static void addStatusBarPadding21v(Context ctx, View view) {
if (Build.VERSION.SDK_INT >= 21) {
view.setPadding(0, getStatusBarHeight(ctx), 0, 0);
int paddingLeft = view.getPaddingLeft();
int paddingTop = view.getPaddingTop();
int paddingRight = view.getPaddingRight();
int paddingBottom = view.getPaddingBottom();
view.setPadding(paddingLeft, paddingTop + getStatusBarHeight(ctx), paddingRight, paddingBottom);
}
}

View file

@ -1,41 +1,29 @@
package net.osmand.plus.mapcontextmenu.other;
import android.annotation.SuppressLint;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.IconsCache;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.other.MapMultiSelectionMenu.MenuObject;
import net.osmand.plus.widgets.TextViewEx;
import java.util.LinkedList;
import java.util.List;
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
public class MapMultiSelectionMenuFragment extends Fragment implements AdapterView.OnItemClickListener {
public class MapMultiSelectionMenuFragment extends Fragment implements MultiSelectionArrayAdapter.OnClickListener {
public static final String TAG = "MapMultiSelectionMenuFragment";
private View view;
private ArrayAdapter<MenuObject> listAdapter;
private MultiSelectionArrayAdapter listAdapter;
private MapMultiSelectionMenu menu;
private boolean dismissing = false;
private boolean wasDrawerDisabled;
@ -58,15 +46,25 @@ public class MapMultiSelectionMenuFragment extends Fragment implements AdapterVi
ListView listView = (ListView) view.findViewById(R.id.list);
if (menu.isLandscapeLayout() && Build.VERSION.SDK_INT >= 21) {
AndroidUtils.addStatusBarPadding21v(getActivity(), listView);
listView.setClipToPadding(false);
}
View headerView = inflater.inflate(R.layout.menu_obj_selection_header, listView, false);
if (!menu.isLight()) {
((TextViewEx) headerView.findViewById(R.id.header_title)).setTextColor(getResources().getColor(R.color.ctx_menu_info_text_dark));
}
headerView.setOnClickListener(null);
listView.addHeaderView(headerView);
listAdapter = createAdapter();
listAdapter.setListener(this);
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(this);
if (!oldAndroid()) {
runLayoutListener();
}
runLayoutListener();
view.findViewById(R.id.cancel_row).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
dismissMenu();
}
});
return view;
}
@ -141,8 +139,25 @@ public class MapMultiSelectionMenuFragment extends Fragment implements AdapterVi
@Override
public void onGlobalLayout() {
int maxHeight = (int) (getScreenHeight() * menu.getHalfScreenMaxHeightKoef());
int height = view.findViewById(R.id.main_view).getHeight();
if (!menu.isLandscapeLayout() && listAdapter.getCount() > 3) {
View contentView = view.findViewById(R.id.content);
float headerHeight = contentView.getResources().getDimension(R.dimen.multi_selection_header_height);
float cancelRowHeight = contentView.getResources().getDimension(R.dimen.bottom_sheet_cancel_button_height);
int maxHeight = (int) (headerHeight + cancelRowHeight);
for (int i = 0; i < 3; i++) {
View childView = listAdapter.getView(0, null, (ListView) contentView.findViewById(R.id.list));
childView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
maxHeight += childView.getMeasuredHeight();
}
int height = contentView.getHeight();
if (height > maxHeight) {
ViewGroup.LayoutParams lp = contentView.getLayoutParams();
lp.height = maxHeight;
contentView.setLayoutParams(lp);
contentView.requestLayout();
}
}
ViewTreeObserver obs = view.getViewTreeObserver();
@ -151,72 +166,21 @@ public class MapMultiSelectionMenuFragment extends Fragment implements AdapterVi
} else {
obs.removeGlobalOnLayoutListener(this);
}
if (!menu.isLandscapeLayout() && height > maxHeight) {
ViewGroup.LayoutParams lp = view.getLayoutParams();
lp.height = maxHeight;
view.setLayoutParams(lp);
view.requestLayout();
}
}
});
}
private ArrayAdapter<MenuObject> createAdapter() {
private MultiSelectionArrayAdapter createAdapter() {
final List<MenuObject> items = new LinkedList<>(menu.getObjects());
return new ArrayAdapter<MenuObject>(menu.getMapActivity(), R.layout.menu_obj_list_item, items) {
@SuppressLint("InflateParams")
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
v = menu.getMapActivity().getLayoutInflater().inflate(R.layout.menu_obj_list_item, null);
}
final MenuObject item = getItem(position);
buildHeader(v, item, menu.getMapActivity());
return v;
}
};
}
private void buildHeader(View view, MenuObject item, MapActivity mapActivity) {
AndroidUtils.setBackground(mapActivity, view, !menu.isLight(), R.drawable.expandable_list_item_background_light, R.drawable.expandable_list_item_background_dark);
IconsCache iconsCache = mapActivity.getMyApplication().getIconsCache();
final View iconLayout = view.findViewById(R.id.context_menu_icon_layout);
final ImageView iconView = (ImageView) view.findViewById(R.id.context_menu_icon_view);
Drawable icon = item.getLeftIcon();
int iconId = item.getLeftIconId();
if (icon != null) {
iconView.setImageDrawable(icon);
iconLayout.setVisibility(View.VISIBLE);
} else if (iconId != 0) {
iconView.setImageDrawable(iconsCache.getIcon(iconId,
menu.isLight() ? R.color.osmand_orange : R.color.osmand_orange_dark));
iconLayout.setVisibility(View.VISIBLE);
} else {
iconLayout.setVisibility(View.GONE);
}
// Text line 1
TextView line1 = (TextView) view.findViewById(R.id.context_menu_line1);
((TextView) view.findViewById(R.id.context_menu_line1)).setTextColor(ContextCompat.getColor(getContext(),
!menu.isLight() ? R.color.ctx_menu_title_color_dark : R.color.ctx_menu_title_color_light));
line1.setText(item.getTitleStr());
// Text line 2
TextView line2 = (TextView) view.findViewById(R.id.context_menu_line2);
((TextView) line2).setTextColor(ContextCompat.getColor(getContext(), R.color.ctx_menu_subtitle_color));
line2.setText(item.getTypeStr());
Drawable slIcon = item.getTypeIcon();
line2.setCompoundDrawablesWithIntrinsicBounds(slIcon, null, null, null);
line2.setCompoundDrawablePadding(dpToPx(5f));
return new MultiSelectionArrayAdapter(menu, R.layout.menu_obj_list_item, items);
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
menu.openContextMenu(listAdapter.getItem(position));
public void onClick(int position) {
MenuObject menuObject = listAdapter.getItem(position);
if (menuObject != null) {
menu.openContextMenu(menuObject);
}
}
public void dismissMenu() {
@ -227,23 +191,4 @@ public class MapMultiSelectionMenuFragment extends Fragment implements AdapterVi
menu.getMapActivity().getSupportFragmentManager().popBackStack();
}
}
private int dpToPx(float dp) {
Resources r = getActivity().getResources();
return (int) TypedValue.applyDimension(
COMPLEX_UNIT_DIP,
dp,
r.getDisplayMetrics()
);
}
private int getScreenHeight() {
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.heightPixels;
}
private boolean oldAndroid() {
return (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH);
}
}

View file

@ -0,0 +1,93 @@
package net.osmand.plus.mapcontextmenu.other;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.plus.IconsCache;
import net.osmand.plus.R;
import java.util.List;
public class MultiSelectionArrayAdapter extends ArrayAdapter<MapMultiSelectionMenu.MenuObject> {
private MapMultiSelectionMenu menu;
private OnClickListener listener;
MultiSelectionArrayAdapter(@NonNull MapMultiSelectionMenu menu, int resource, @NonNull List<MapMultiSelectionMenu.MenuObject> objects) {
super(menu.getMapActivity(), resource, objects);
this.menu = menu;
}
public void setListener(OnClickListener listener) {
this.listener = listener;
}
@NonNull
@Override
public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {
View v = convertView;
if (v == null) {
v = menu.getMapActivity().getLayoutInflater().inflate(R.layout.menu_obj_list_item, parent, false);
}
final MapMultiSelectionMenu.MenuObject item = getItem(position);
if (item != null) {
View contentView = v.findViewById(R.id.content);
AndroidUtils.setBackground(menu.getMapActivity(), contentView, !menu.isLight(), R.drawable.expandable_list_item_background_light, R.drawable.expandable_list_item_background_dark);
v.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null) {
listener.onClick(position);
}
}
});
IconsCache iconsCache = menu.getMapActivity().getMyApplication().getIconsCache();
final View iconLayout = v.findViewById(R.id.context_menu_icon_layout);
final ImageView iconView = (ImageView) v.findViewById(R.id.context_menu_icon_view);
Drawable icon = item.getLeftIcon();
int iconId = item.getLeftIconId();
if (icon != null) {
iconView.setImageDrawable(icon);
iconLayout.setVisibility(View.VISIBLE);
} else if (iconId != 0) {
iconView.setImageDrawable(iconsCache.getIcon(iconId,
menu.isLight() ? R.color.osmand_orange : R.color.osmand_orange_dark));
iconLayout.setVisibility(View.VISIBLE);
} else {
iconLayout.setVisibility(View.GONE);
}
// Text line 1
TextView line1 = (TextView) v.findViewById(R.id.context_menu_line1);
((TextView) v.findViewById(R.id.context_menu_line1)).setTextColor(ContextCompat.getColor(getContext(),
!menu.isLight() ? R.color.ctx_menu_title_color_dark : R.color.ctx_menu_title_color_light));
line1.setText(item.getTitleStr());
// Text line 2
TextView line2 = (TextView) v.findViewById(R.id.context_menu_line2);
((TextView) line2).setTextColor(ContextCompat.getColor(getContext(), R.color.ctx_menu_subtitle_color));
line2.setText(item.getTypeStr());
Drawable slIcon = item.getTypeIcon();
line2.setCompoundDrawablesWithIntrinsicBounds(slIcon, null, null, null);
line2.setCompoundDrawablePadding(AndroidUtils.dpToPx(menu.getMapActivity(), 5f));
// Divider
View divider = v.findViewById(R.id.divider);
divider.setVisibility(position != getCount() - 1 ? View.VISIBLE : View.GONE);
}
return v;
}
public interface OnClickListener {
void onClick(int position);
}
}