diff --git a/OsmAnd/res/layout/list_item_header.xml b/OsmAnd/res/layout/list_item_header.xml index 7a880dc640..53d6e5cf11 100644 --- a/OsmAnd/res/layout/list_item_header.xml +++ b/OsmAnd/res/layout/list_item_header.xml @@ -4,7 +4,6 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" - android:descendantFocusability="blocksDescendants" android:orientation="vertical"> { +public class OsmEditsAdapter extends ArrayAdapter { + + public static final int TYPE_HEADER = 0; + private static final int TYPE_ITEM = 1; + private static final int TYPE_COUNT = 2; private OsmandApplication app; + private List items; private boolean selectionMode; private List selectedOsmEdits; + private boolean portrait; private OsmEditsAdapterListener listener; - public OsmEditsAdapter(OsmandApplication app, @NonNull List points) { - super(app, 0, points); + public OsmEditsAdapter(OsmandApplication app, @NonNull List items) { + super(app, 0, items); this.app = app; + this.items = items; } public boolean isSelectionMode() { @@ -46,6 +56,10 @@ public class OsmEditsAdapter extends ArrayAdapter { this.selectedOsmEdits = selectedOsmEdits; } + public void setPortrait(boolean portrait) { + this.portrait = portrait; + } + public void setAdapterListener(OsmEditsAdapterListener listener) { this.listener = listener; } @@ -53,69 +67,164 @@ public class OsmEditsAdapter extends ArrayAdapter { @NonNull @Override public View getView(int position, View convertView, @NonNull ViewGroup parent) { - View view = convertView; - if (view == null) { - view = LayoutInflater.from(getContext()).inflate(R.layout.note_list_item, parent, false); - OsmEditViewHolder holder = new OsmEditViewHolder(view); - view.setTag(holder); - } - final OsmPoint osmEdit = getItem(position); - - if (osmEdit != null) { - final OsmEditViewHolder holder = (OsmEditViewHolder) view.getTag(); - - holder.titleTextView.setText(OsmEditingPlugin.getName(osmEdit)); - holder.descriptionTextView.setText(getDescription(osmEdit)); - Drawable icon = getIcon(osmEdit); - if (icon != null) { - holder.icon.setImageDrawable(icon); + if (portrait) { + if (convertView == null) { + if (position == 0) { + convertView = LayoutInflater.from(getContext()).inflate(R.layout.list_item_header, parent, false); + HeaderViewHolder holder = new HeaderViewHolder(convertView); + convertView.setTag(holder); + } else { + convertView = LayoutInflater.from(getContext()).inflate(R.layout.note_list_item, parent, false); + OsmEditViewHolder holder = new OsmEditViewHolder(convertView); + convertView.setTag(holder); + } } - if (selectionMode) { - holder.optionsImageButton.setVisibility(View.GONE); - holder.selectCheckBox.setVisibility(View.VISIBLE); - holder.selectCheckBox.setChecked(selectedOsmEdits.contains(osmEdit)); - holder.icon.setVisibility(View.GONE); - holder.selectCheckBox.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (listener != null) { - listener.onItemSelect(osmEdit, holder.selectCheckBox.isChecked()); - } - } - }); + if (position == 0) { + bindHeaderViewHolder((HeaderViewHolder) convertView.getTag()); } else { - holder.icon.setVisibility(View.VISIBLE); - holder.optionsImageButton.setVisibility(View.VISIBLE); - holder.selectCheckBox.setVisibility(View.GONE); + final Object item = getItem(position); + if (item instanceof OsmPoint) { + final OsmEditViewHolder holder = (OsmEditViewHolder) convertView.getTag(); + bindOsmEditViewHolder(holder, (OsmPoint) item, position); + } } - holder.optionsImageButton.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_overflow_menu_white)); - holder.optionsImageButton.setOnClickListener(new View.OnClickListener() { + return convertView; + } else { + int margin = app.getResources().getDimensionPixelSize(R.dimen.content_padding); + int sideMargin = app.getResources().getDisplayMetrics().widthPixels / 10; + + FrameLayout fl = new FrameLayout(getContext()); + LinearLayout ll = new LinearLayout(getContext()); + ll.setOrientation(LinearLayout.VERTICAL); + ll.setBackgroundResource(app.getSettings().isLightContent() ? R.drawable.bg_card_light : R.drawable.bg_card_dark); + fl.addView(ll); + ((FrameLayout.LayoutParams) ll.getLayoutParams()).setMargins(sideMargin, margin, sideMargin, margin); + + HeaderViewHolder headerViewHolder = new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.list_item_header, parent, false)); + bindHeaderViewHolder(headerViewHolder); + ll.addView(headerViewHolder.mainView); + + for (int i = 0; i < items.size(); i++) { + Object item = getItem(i); + if (item instanceof OsmPoint) { + OsmEditViewHolder viewHolder = new OsmEditViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.note_list_item, parent, false)); + bindOsmEditViewHolder(viewHolder, (OsmPoint) item, i); + ll.addView(viewHolder.mainView); + } + } + + return fl; + } + } + + @Override + public int getCount() { + if (portrait) { + return super.getCount(); + } else { + return getHeadersCount(); + } + } + + @Override + public int getItemViewType(int position) { + Object item = getItem(position); + if (item instanceof OsmPoint) { + return TYPE_ITEM; + } + return (int) item; + } + + @Override + public int getViewTypeCount() { + return TYPE_COUNT; + } + + private int getHeadersCount() { + int count = 0; + for (int i = 0; i < items.size(); i++) { + Object item = items.get(i); + if (!(item instanceof OsmPoint)) { + count++; + } + } + return count; + } + + private void bindHeaderViewHolder(final HeaderViewHolder holder) { + holder.topDivider.setVisibility(portrait ? View.VISIBLE : View.GONE); + holder.title.setText(R.string.your_edits); + holder.checkBox.setChecked(isAllSelected()); + if (selectionMode) { + holder.checkBox.setVisibility(View.VISIBLE); + holder.checkBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (listener != null) { - listener.onOptionsClick(osmEdit); + listener.onHeaderCheckboxClick(holder.checkBox.isChecked()); } } }); - holder.mainView.setOnClickListener(new View.OnClickListener() { + } else { + holder.checkBox.setVisibility(View.GONE); + } + } + + private void bindOsmEditViewHolder(final OsmEditViewHolder holder, final OsmPoint osmEdit, int position) { + holder.titleTextView.setText(OsmEditingPlugin.getName(osmEdit)); + holder.descriptionTextView.setText(getDescription(osmEdit)); + Drawable icon = getIcon(osmEdit); + if (icon != null) { + holder.icon.setImageDrawable(icon); + } + if (selectionMode) { + holder.optionsImageButton.setVisibility(View.GONE); + holder.selectCheckBox.setVisibility(View.VISIBLE); + holder.selectCheckBox.setChecked(selectedOsmEdits.contains(osmEdit)); + holder.icon.setVisibility(View.GONE); + holder.selectCheckBox.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (selectionMode) { - holder.selectCheckBox.performClick(); - } else { - if (listener != null) { - listener.onItemShowMap(osmEdit); - } + if (listener != null) { + listener.onItemSelect(osmEdit, holder.selectCheckBox.isChecked()); } - } }); - boolean showDivider = getCount() > 1 && position != getCount() - 1; - holder.bottomDivider.setVisibility(showDivider ? View.VISIBLE : View.GONE); + } else { + holder.icon.setVisibility(View.VISIBLE); + holder.optionsImageButton.setVisibility(View.VISIBLE); + holder.selectCheckBox.setVisibility(View.GONE); } - return view; + holder.optionsImageButton.setImageDrawable(app.getIconsCache().getThemedIcon(R.drawable.ic_overflow_menu_white)); + holder.optionsImageButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (listener != null) { + listener.onOptionsClick(osmEdit); + } + } + }); + holder.mainView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (selectionMode) { + holder.selectCheckBox.performClick(); + } else { + if (listener != null) { + listener.onItemShowMap(osmEdit); + } + } + + } + }); + boolean showDivider = getItemsCount() > 1 && position != getItemsCount() - 1; + holder.bottomDivider.setVisibility(showDivider ? View.VISIBLE : View.GONE); + } + + private int getItemsCount() { + return items.size(); } private Drawable getIcon(OsmPoint point) { @@ -158,6 +267,18 @@ public class OsmEditsAdapter extends ArrayAdapter { return null; } + private boolean isAllSelected() { + for (int i = 0; i < items.size(); i++) { + Object item = items.get(i); + if (item instanceof OsmPoint) { + if (!selectedOsmEdits.contains(item)) { + return false; + } + } + } + return true; + } + private String getDescription(OsmPoint point) { String action = ""; if (point.getAction() == OsmPoint.Action.CREATE) { @@ -197,6 +318,20 @@ public class OsmEditsAdapter extends ArrayAdapter { return description; } + private class HeaderViewHolder { + View mainView; + View topDivider; + CheckBox checkBox; + TextView title; + + HeaderViewHolder(View view) { + mainView = view; + topDivider = view.findViewById(R.id.top_divider); + checkBox = (CheckBox) view.findViewById(R.id.check_box); + title = (TextView) view.findViewById(R.id.title_text_view); + } + } + private class OsmEditViewHolder { View mainView; ImageView icon; @@ -219,6 +354,8 @@ public class OsmEditsAdapter extends ArrayAdapter { public interface OsmEditsAdapterListener { + void onHeaderCheckboxClick(boolean checked); + void onItemSelect(OsmPoint point, boolean checked); void onItemShowMap(OsmPoint point); diff --git a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java index 789275e3a1..9a20d11c25 100644 --- a/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java +++ b/OsmAnd/src/net/osmand/plus/osmedit/OsmEditsFragment.java @@ -21,7 +21,6 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewStub; import android.widget.ArrayAdapter; -import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; @@ -64,7 +63,6 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo private OsmEditingPlugin plugin; private View footerView; - private View headerView; private View emptyView; private List osmEdits = new ArrayList<>(); @@ -133,6 +131,12 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo return listAdapter; } + private void recreateAdapterData() { + listAdapter.clear(); + listAdapter.addAll(createItemsList()); + listAdapter.notifyDataSetChanged(); + } + private void selectAll() { for (int i = 0; i < osmEdits.size(); i++) { OsmPoint point = osmEdits.get(i); @@ -285,7 +289,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo private void updateSelectionMode(ActionMode m) { updateSelectionTitle(m); - refreshSelectAll(); + listAdapter.notifyDataSetChanged(); } private void updateSelectionTitle(ActionMode m) { @@ -296,28 +300,9 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo } } - private void refreshSelectAll() { - View view = getView(); - if (view == null) { - return; - } - CheckBox selectAll = (CheckBox) view.findViewById(R.id.check_box); - for (int i = 0; i < osmEdits.size(); i++) { - OsmPoint point = osmEdits.get(i); - if (!osmEditsSelected.contains(point)) { - selectAll.setChecked(false); - return; - } - } - selectAll.setChecked(true); - } - private void enableSelectionMode(boolean selectionMode) { listAdapter.setSelectionMode(selectionMode); //noinspection ConstantConditions - if (headerView != null) { - headerView.findViewById(R.id.check_box).setVisibility(selectionMode ? View.VISIBLE : View.GONE); - } ((FavoritesActivity) getActivity()).setToolbarVisibility(!selectionMode && AndroidUiHelper.isOrientationPortrait(getActivity())); ((FavoritesActivity) getActivity()).updateListViewFooter(footerView); } @@ -348,6 +333,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo } private void fetchData() { + boolean portrait = AndroidUiHelper.isOrientationPortrait(getActivity()); osmEdits = new ArrayList<>(); List l1 = plugin.getDBPOI().getOpenstreetmapPoints(); List l2 = plugin.getDBBug().getOsmbugsPoints(); @@ -357,32 +343,24 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo listView.setDivider(null); listView.setEmptyView(emptyView); - if (osmEdits.size() > 0) { - if (footerView == null) { - footerView = getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, listView, false); - listView.addFooterView(footerView); - } - if (headerView == null) { - headerView = getActivity().getLayoutInflater().inflate(R.layout.list_item_header, listView, false); - listView.addHeaderView(headerView); - ((TextView) headerView.findViewById(R.id.title_text_view)).setText(R.string.your_edits); - final CheckBox selectAll = (CheckBox) headerView.findViewById(R.id.check_box); - selectAll.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (selectAll.isChecked()) { - selectAll(); - } else { - deselectAll(); - } - updateSelectionTitle(actionMode); - } - }); - } + if (osmEdits.size() > 0 && footerView == null && portrait) { + footerView = getActivity().getLayoutInflater().inflate(R.layout.list_shadow_footer, listView, false); + listView.addFooterView(footerView); } - listAdapter = new OsmEditsAdapter(getMyApplication(), osmEdits); + List items = createItemsList(); + listAdapter = new OsmEditsAdapter(getMyApplication(), items); listAdapter.setSelectedOsmEdits(osmEditsSelected); listAdapter.setAdapterListener(new OsmEditsAdapter.OsmEditsAdapterListener() { + @Override + public void onHeaderCheckboxClick(boolean checked) { + if (checked) { + selectAll(); + } else { + deselectAll(); + } + updateSelectionTitle(actionMode); + } + @Override public void onItemSelect(OsmPoint point, boolean checked) { if (checked) { @@ -403,9 +381,19 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo openPopUpMenu(note); } }); + listAdapter.setPortrait(portrait); listView.setAdapter(listAdapter); } + private List createItemsList() { + List items = new ArrayList<>(); + if (!osmEdits.isEmpty()) { + items.add(OsmEditsAdapter.TYPE_HEADER); + items.addAll(osmEdits); + } + return items; + } + private void showBugDialog(final OsmNotesPoint point) { final View view = LayoutInflater.from(getActivity()).inflate(R.layout.open_bug, null); view.findViewById(R.id.user_name_field).setVisibility(View.GONE); @@ -527,7 +515,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo osmEdits.remove(osmPoint); } } - listAdapter.notifyDataSetChanged(); + recreateAdapterData(); } }; dialog.show(getActivity().getSupportFragmentManager(), ProgressDialogFragment.TAG); @@ -546,7 +534,7 @@ public class OsmEditsFragment extends OsmAndListFragment implements SendPoiDialo private void deletePoint(OsmPoint osmPoint) { osmEdits.remove(osmPoint); - listAdapter.notifyDataSetChanged(); + recreateAdapterData(); } private void notifyDataSetChanged() {