From 50e2f4e967bb4f7b9b41ea28575e070a638ba26b Mon Sep 17 00:00:00 2001 From: Alexey Kulish Date: Thu, 1 Oct 2015 21:42:13 +0300 Subject: [PATCH] Downloads in progress --- OsmAnd/res/layout/download_index_fragment.xml | 13 +- OsmAnd/src/net/osmand/plus/WorldRegion.java | 15 +- .../plus/download/DownloadActivity.java | 8 +- .../plus/download/DownloadIndexesThread.java | 6 +- .../net/osmand/plus/download/IndexItem.java | 9 + .../plus/download/items/ItemViewHolder.java | 88 ++++++ .../plus/download/items/ItemsListBuilder.java | 212 ++++++------- .../download/items/LocalDialogFragment.java | 93 ++++++ .../download/items/LocalItemsFragment.java | 281 ++++++++++++++++++ ...sFragment.java => WorldItemsFragment.java} | 97 +++--- 10 files changed, 661 insertions(+), 161 deletions(-) create mode 100644 OsmAnd/src/net/osmand/plus/download/items/ItemViewHolder.java create mode 100644 OsmAnd/src/net/osmand/plus/download/items/LocalDialogFragment.java create mode 100644 OsmAnd/src/net/osmand/plus/download/items/LocalItemsFragment.java rename OsmAnd/src/net/osmand/plus/download/items/{DownloadItemsFragment.java => WorldItemsFragment.java} (69%) diff --git a/OsmAnd/res/layout/download_index_fragment.xml b/OsmAnd/res/layout/download_index_fragment.xml index 673114158f..83fdecf566 100644 --- a/OsmAnd/res/layout/download_index_fragment.xml +++ b/OsmAnd/res/layout/download_index_fragment.xml @@ -14,13 +14,14 @@ android:orientation="vertical"> + android:textSize="@dimen/default_desc_text_size"/> + android:text="World Maps" + android:textSize="@dimen/default_desc_text_size"/> + android:textSize="@dimen/default_desc_text_size"/> ref : fragSet) { Fragment f = ref.get(); - if (f instanceof DownloadItemsFragment) { + if (f instanceof WorldItemsFragment) { if (f.isAdded()) { - ((DownloadItemsFragment) f).onCategorizationFinished(); + ((WorldItemsFragment) f).onCategorizationFinished(); } } } diff --git a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java index 8eb4f09fc4..8233685c83 100644 --- a/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java +++ b/OsmAnd/src/net/osmand/plus/download/DownloadIndexesThread.java @@ -413,16 +413,14 @@ public class DownloadIndexesThread { @Override protected IndexFileList doInBackground(Void... params) { IndexFileList indexFileList = DownloadOsmandIndexesHelper.getIndexesList(ctx); - indexFiles = indexFileList; if (indexFileList != null) { - ItemsListBuilder builder = new ItemsListBuilder(app, app.getWorldRegion()); - builder.invalidate(); - builder.build(); + ItemsListBuilder.prepareData(app, indexFileList.getIndexFiles()); } return indexFileList; } protected void onPostExecute(IndexFileList result) { + indexFiles = result; if (indexFiles != null && uiActivity != null) { prepareFilesToUpdate(); boolean basemapExists = uiActivity.getMyApplication().getResourceManager().containsBasemap(); diff --git a/OsmAnd/src/net/osmand/plus/download/IndexItem.java b/OsmAnd/src/net/osmand/plus/download/IndexItem.java index 32cd89b083..ce54f4166c 100644 --- a/OsmAnd/src/net/osmand/plus/download/IndexItem.java +++ b/OsmAnd/src/net/osmand/plus/download/IndexItem.java @@ -25,6 +25,7 @@ public class IndexItem implements Comparable, HasName, Parcelable { String description; String fileName; + String simplifiedFileName; String size; long timestamp; long contentSize; @@ -37,6 +38,7 @@ public class IndexItem implements Comparable, HasName, Parcelable { public IndexItem(String fileName, String description, long timestamp, String size, long contentSize, long containerSize, DownloadActivityType tp) { this.fileName = fileName; + this.simplifiedFileName = fileName.toLowerCase().replace("_2.", "."); this.description = description; this.timestamp = timestamp; this.size = size; @@ -53,6 +55,10 @@ public class IndexItem implements Comparable, HasName, Parcelable { return fileName; } + public String getSimplifiedFileName() { + return simplifiedFileName; + } + public String getDescription() { return description; } @@ -160,6 +166,7 @@ public class IndexItem implements Comparable, HasName, Parcelable { return "IndexItem{" + "description='" + description + '\'' + ", fileName='" + fileName + '\'' + + ", simplifiedFileName='" + simplifiedFileName + '\'' + ", size='" + size + '\'' + ", timestamp=" + timestamp + ", contentSize=" + contentSize + @@ -185,6 +192,7 @@ public class IndexItem implements Comparable, HasName, Parcelable { dest.writeParcelable(this.type, flags); dest.writeByte(extra ? (byte) 1 : (byte) 0); dest.writeString(this.initializedName); + dest.writeString(this.simplifiedFileName); } protected IndexItem(Parcel in) { @@ -197,6 +205,7 @@ public class IndexItem implements Comparable, HasName, Parcelable { this.type = in.readParcelable(DownloadActivityType.class.getClassLoader()); this.extra = in.readByte() != 0; this.initializedName = in.readString(); + this.simplifiedFileName = in.readString(); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { diff --git a/OsmAnd/src/net/osmand/plus/download/items/ItemViewHolder.java b/OsmAnd/src/net/osmand/plus/download/items/ItemViewHolder.java new file mode 100644 index 0000000000..3a8dc62ce4 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/download/items/ItemViewHolder.java @@ -0,0 +1,88 @@ +package net.osmand.plus.download.items; + +import android.graphics.drawable.Drawable; +import android.view.View; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import net.osmand.plus.R; +import net.osmand.plus.WorldRegion; +import net.osmand.plus.download.BaseDownloadActivity; +import net.osmand.plus.download.DownloadActivity; +import net.osmand.plus.download.DownloadActivityType; +import net.osmand.plus.download.IndexItem; + +public class ItemViewHolder { + private final TextView nameTextView; + private final TextView descrTextView; + private final ImageView leftImageView; + private final ImageView rightImageButton; + private final ProgressBar progressBar; + + public ItemViewHolder(View convertView) { + nameTextView = (TextView) convertView.findViewById(R.id.name); + descrTextView = (TextView) convertView.findViewById(R.id.description); + leftImageView = (ImageView) convertView.findViewById(R.id.leftImageView); + rightImageButton = (ImageView) convertView.findViewById(R.id.rightImageButton); + progressBar = (ProgressBar) convertView.findViewById(R.id.progressBar); + } + + public void bindIndexItem(final IndexItem indexItem, final DownloadActivity context, boolean showTypeInTitle, boolean showTypeInDesc) { + if (indexItem.getType() == DownloadActivityType.VOICE_FILE) { + nameTextView.setText(indexItem.getVisibleName(context, + context.getMyApplication().getRegions())); + } else { + if (showTypeInTitle) { + nameTextView.setText(indexItem.getType().getString(context)); + } else { + nameTextView.setText(indexItem.getVisibleName(context, context.getMyApplication().getRegions())); + } + } + if (showTypeInDesc) { + descrTextView.setText(indexItem.getType().getString(context) + " • " + indexItem.getSizeDescription(context)); + } else { + descrTextView.setText(indexItem.getSizeDescription(context)); + } + leftImageView.setImageDrawable(getContextIcon(context, + indexItem.getType().getIconResource())); + rightImageButton.setVisibility(View.VISIBLE); + rightImageButton.setImageDrawable(getContextIcon(context, + R.drawable.ic_action_import)); + rightImageButton.setTag(R.id.index_item, indexItem); + rightImageButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ((BaseDownloadActivity) v.getContext()) + .startDownload((IndexItem) v.getTag(R.id.index_item)); + progressBar.setVisibility(View.VISIBLE); + rightImageButton.setImageDrawable(getContextIcon(context, + R.drawable.ic_action_remove_dark)); + } + }); + progressBar.setVisibility(View.GONE); + } + + public void bindRegion(WorldRegion region, DownloadActivity context) { + nameTextView.setText(region.getName()); + if (region.getResourceTypes().size() > 0) { + StringBuilder stringBuilder = new StringBuilder(); + for (DownloadActivityType activityType : region.getResourceTypes()) { + if (stringBuilder.length() > 0) { + stringBuilder.append(", "); + } + stringBuilder.append(activityType.getString(context)); + } + descrTextView.setText(stringBuilder.toString()); + } else { + descrTextView.setText(R.string.shared_string_others); + } + leftImageView.setImageDrawable(getContextIcon(context, R.drawable.ic_map)); + rightImageButton.setVisibility(View.GONE); + progressBar.setVisibility(View.GONE); + } + + private Drawable getContextIcon(DownloadActivity context, int resourceId) { + return context.getMyApplication().getIconsCache().getContentIcon(resourceId); + } +} diff --git a/OsmAnd/src/net/osmand/plus/download/items/ItemsListBuilder.java b/OsmAnd/src/net/osmand/plus/download/items/ItemsListBuilder.java index fb3d0dabf6..50a7a4d272 100644 --- a/OsmAnd/src/net/osmand/plus/download/items/ItemsListBuilder.java +++ b/OsmAnd/src/net/osmand/plus/download/items/ItemsListBuilder.java @@ -9,6 +9,7 @@ import net.osmand.plus.WorldRegion; import net.osmand.plus.download.DownloadActivity; import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.IndexItem; +import net.osmand.plus.mapcontextmenu.editors.PointEditor; import net.osmand.util.Algorithms; import java.util.Collections; @@ -17,6 +18,8 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; public class ItemsListBuilder { @@ -92,16 +95,16 @@ public class ItemsListBuilder { String str2; if (obj1 instanceof WorldRegion) { - str1 = ((WorldRegion)obj1).getName(); + str1 = ((WorldRegion) obj1).getName(); } else { - ResourceItem item = (ResourceItem)obj1; + ResourceItem item = (ResourceItem) obj1; str1 = item.title + item.getIndexItem().getType().getTag(); } if (obj2 instanceof WorldRegion) { - str2 = ((WorldRegion)obj2).getName(); + str2 = ((WorldRegion) obj2).getName(); } else { - ResourceItem item = (ResourceItem)obj2; + ResourceItem item = (ResourceItem) obj2; str2 = item.title + item.getIndexItem().getType().getTag(); } @@ -114,6 +117,8 @@ public class ItemsListBuilder { private static Map> resourcesByRegions = new HashMap<>(); private static List searchableWorldwideRegionItems = new LinkedList<>(); + private static final Lock lock = new ReentrantLock(); + private List regionMapItems; private List allResourceItems; @@ -122,7 +127,6 @@ public class ItemsListBuilder { private OsmandApplication app; private WorldRegion region; - private boolean invalidated; private boolean srtmDisabled; private boolean hasSrtm; @@ -138,7 +142,7 @@ public class ItemsListBuilder { List list = new LinkedList<>(); for (Object obj : allResourceItems) { if (obj instanceof WorldRegion) { - list.add((WorldRegion)obj); + list.add((WorldRegion) obj); } } return list; @@ -157,18 +161,20 @@ public class ItemsListBuilder { } public boolean build() { - return obtainDataAndItems(); + if (lock.tryLock()) { + try { + return obtainDataAndItems(); + } finally { + lock.unlock(); + } + } else { + return false; + } } private boolean obtainDataAndItems() { - if (invalidated) { - resourcesByRegions.clear(); - } - - if (resourcesByRegions.isEmpty()) { - if (!prepareData()) { - return false; - } + if (resourcesByRegions.isEmpty() || region == null) { + return false; } collectSubregionsDataAndItems(); @@ -182,97 +188,99 @@ public class ItemsListBuilder { LOG.warn("getAllResourceItems >>>"); for (Object obj : getAllResourceItems()) { if (obj instanceof WorldRegion) { - WorldRegion item = (WorldRegion)obj; + WorldRegion item = (WorldRegion) obj; LOG.warn("W resId=" + item.getRegionId() + " title=" + item.getName()); } else if (obj instanceof ResourceItem) { - ResourceItem resourceItem = (ResourceItem)obj; + ResourceItem resourceItem = (ResourceItem) obj; LOG.warn("R resId=" + resourceItem.getIndexItem().getFileName() + " title=" + resourceItem.getTitle()); } } - invalidated = false; - return true; } - public void invalidate() { - invalidated = true; - } + public static boolean prepareData(OsmandApplication app, List resources) { + lock.lock(); + try { + List resourcesInRepository; + if (resources != null) { + resourcesInRepository = resources; + } else { + resourcesInRepository = DownloadActivity.downloadListIndexThread.getCachedIndexFiles(); + } + if (resourcesInRepository == null) { + return false; + } - private boolean prepareData() { - List resourcesInRepository = DownloadActivity.downloadListIndexThread.getCachedIndexFiles(); - if (resourcesInRepository == null) { - return false; - } + boolean doInit = resourcesByRegions.isEmpty(); + boolean initSearchableRegions = searchableWorldwideRegionItems.isEmpty() || doInit; - boolean doInit = resourcesByRegions.isEmpty(); - boolean initSearchableRegions = searchableWorldwideRegionItems.isEmpty() || doInit; - - if (initSearchableRegions) { - searchableWorldwideRegionItems.clear(); - } - - List mergedRegions = app.getWorldRegion().getFlattenedSubregions(); - mergedRegions.add(app.getWorldRegion()); - for(WorldRegion region : mergedRegions) - { if (initSearchableRegions) { - searchableWorldwideRegionItems.add(region); + searchableWorldwideRegionItems.clear(); } - String downloadsIdPrefix = region.getDownloadsIdPrefix().toLowerCase(); - - Map regionResources = new HashMap<>(); - - if (!doInit) - { - regionResources.putAll(resourcesByRegions.get(region)); - } - - if (doInit) - { - List typesArray = new LinkedList<>(); - boolean hasSrtm = false; - for (IndexItem resource : resourcesInRepository) - { - if (!resource.getFileName().startsWith(downloadsIdPrefix)) - continue; - - if (resource.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) { - hasSrtm = true; - } - - typesArray.add(resource.getType()); - - regionResources.put(resource.getFileName(), resource); + List mergedRegions = app.getWorldRegion().getFlattenedSubregions(); + mergedRegions.add(app.getWorldRegion()); + for (WorldRegion region : mergedRegions) { + if (initSearchableRegions) { + searchableWorldwideRegionItems.add(region); } - if (region.getSuperregion() != null && hasSrtm && region.getSuperregion().getSuperregion() != app.getWorldRegion()) - { - if (!region.getSuperregion().getResourceTypes().contains(DownloadActivityType.SRTM_COUNTRY_FILE)) - { - region.getSuperregion().getResourceTypes().add(DownloadActivityType.SRTM_COUNTRY_FILE); - Collections.sort(region.getSuperregion().getResourceTypes(), new Comparator() { - @Override - public int compare(DownloadActivityType dat1, DownloadActivityType dat2) { - return dat1.getTag().compareTo(dat2.getTag()); - } - }); - } + String downloadsIdPrefix = region.getDownloadsIdPrefix(); + + Map regionResources = new HashMap<>(); + + if (!doInit) { + regionResources.putAll(resourcesByRegions.get(region)); } - Collections.sort(typesArray, new Comparator() { - @Override - public int compare(DownloadActivityType dat1, DownloadActivityType dat2) { - return dat1.getTag().compareTo(dat2.getTag()); - } - }); - region.setResourceTypes(typesArray); - } + if (doInit) { + List typesArray = new LinkedList<>(); + boolean hasSrtm = false; - resourcesByRegions.put(region, regionResources); + for (IndexItem resource : resourcesInRepository) { + + if (!resource.getSimplifiedFileName().startsWith(downloadsIdPrefix)) { + continue; + } + + if (resource.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) { + hasSrtm = true; + } + + typesArray.add(resource.getType()); + + regionResources.put(resource.getSimplifiedFileName(), resource); + } + + if (region.getSuperregion() != null && hasSrtm && region.getSuperregion().getSuperregion() != app.getWorldRegion()) { + if (!region.getSuperregion().getResourceTypes().contains(DownloadActivityType.SRTM_COUNTRY_FILE)) { + region.getSuperregion().getResourceTypes().add(DownloadActivityType.SRTM_COUNTRY_FILE); + Collections.sort(region.getSuperregion().getResourceTypes(), new Comparator() { + @Override + public int compare(DownloadActivityType dat1, DownloadActivityType dat2) { + return dat1.getTag().compareTo(dat2.getTag()); + } + }); + } + } + + Collections.sort(typesArray, new Comparator() { + @Override + public int compare(DownloadActivityType dat1, DownloadActivityType dat2) { + return dat1.getTag().compareTo(dat2.getTag()); + } + }); + region.setResourceTypes(typesArray); + } + + resourcesByRegions.put(region, regionResources); + } + return true; + + } finally { + lock.unlock(); } - return true; } private void collectSubregionsDataAndItems() { @@ -286,10 +294,8 @@ public class ItemsListBuilder { allSubregionItems.clear(); regionMapItems.clear(); - for (WorldRegion subregion : region.getFlattenedSubregions()) - { - if (subregion.getSuperregion() == region) - { + for (WorldRegion subregion : region.getFlattenedSubregions()) { + if (subregion.getSuperregion() == region) { if (subregion.getFlattenedSubregions().size() > 0) { allSubregionItems.add(subregion); } else { @@ -316,27 +322,25 @@ public class ItemsListBuilder { } ResourceItem resItem = new ResourceItem(indexItem, region); - resItem.setResourceId(indexItem.getFileName()); + resItem.setResourceId(indexItem.getSimplifiedFileName()); resItem.setTitle(name); resItem.setContentSize(indexItem.getContentSize()); resItem.setContainerSize(indexItem.getSize()); - if (region != this.region && srtmDisabled) - { - if (hasSrtm && indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) - continue; + if (region != this.region && srtmDisabled) { + if (hasSrtm && indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) + continue; - if (indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) - { - resItem.setTitle("srtm_disabled"); // todo: constant - resItem.setContentSize(0); - resItem.setContainerSize(0); - } - - if (!hasSrtm && indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) - hasSrtm = true; + if (indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) { + resItem.setTitle("srtm_disabled"); // todo: constant + resItem.setContentSize(0); + resItem.setContainerSize(0); } + if (!hasSrtm && indexItem.getType() == DownloadActivityType.SRTM_COUNTRY_FILE) + hasSrtm = true; + } + if (region == this.region) { regionMapArray.add(resItem); diff --git a/OsmAnd/src/net/osmand/plus/download/items/LocalDialogFragment.java b/OsmAnd/src/net/osmand/plus/download/items/LocalDialogFragment.java new file mode 100644 index 0000000000..da599cc54d --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/download/items/LocalDialogFragment.java @@ -0,0 +1,93 @@ +package net.osmand.plus.download.items; + +import android.os.Bundle; +import android.support.v4.app.DialogFragment; +import android.support.v7.widget.Toolbar; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.OsmandSettings; +import net.osmand.plus.R; +import net.osmand.plus.WorldRegion; + +import org.apache.commons.logging.Log; + +public class LocalDialogFragment extends DialogFragment { + private static final Log LOG = PlatformUtil.getLog(LocalDialogFragment.class); + public static final String TAG = "LocalDialogFragment"; + private static final String REGION_DLG_KEY = "world_region_dialog_key"; + private WorldRegion region; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + boolean isLightTheme = ((OsmandApplication) getActivity().getApplication()) + .getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME; + int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme; + setStyle(STYLE_NO_FRAME, themeId); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View view = inflater.inflate(R.layout.maps_in_category_fragment, container, false); + + WorldRegion region = null; + if (savedInstanceState != null) { + Object regionObj = savedInstanceState.getSerializable(REGION_DLG_KEY); + if (regionObj != null) { + region = (WorldRegion)regionObj; + } + } + if (region == null) { + Object regionObj = getArguments().getSerializable(REGION_DLG_KEY); + if (regionObj != null) { + region = (WorldRegion)regionObj; + } + } + + this.region = region; + + Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar); + toolbar.setNavigationIcon(getMyApplication().getIconsCache().getIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha)); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + if (this.region != null) { + getChildFragmentManager().beginTransaction().add(R.id.fragmentContainer, + LocalItemsFragment.createInstance(region)).commit(); + toolbar.setTitle(this.region.getName()); + } + + return view; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putSerializable(REGION_DLG_KEY, region); + super.onSaveInstanceState(outState); + } + + private OsmandApplication getMyApplication() { + return (OsmandApplication) getActivity().getApplication(); + } + + public void onRegionSelected(WorldRegion region) { + createInstance(region).show(getChildFragmentManager(), TAG); + } + + public static LocalDialogFragment createInstance(WorldRegion region) { + Bundle bundle = new Bundle(); + bundle.putSerializable(REGION_DLG_KEY, region); + LocalDialogFragment fragment = new LocalDialogFragment(); + fragment.setArguments(bundle); + return fragment; + } +} diff --git a/OsmAnd/src/net/osmand/plus/download/items/LocalItemsFragment.java b/OsmAnd/src/net/osmand/plus/download/items/LocalItemsFragment.java new file mode 100644 index 0000000000..1e78149e72 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/download/items/LocalItemsFragment.java @@ -0,0 +1,281 @@ +package net.osmand.plus.download.items; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ImageView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.ProgressBar; +import android.widget.TextView; + +import net.osmand.PlatformUtil; +import net.osmand.plus.OsmandApplication; +import net.osmand.plus.R; +import net.osmand.plus.WorldRegion; +import net.osmand.plus.download.BaseDownloadActivity; +import net.osmand.plus.download.DownloadActivity; +import net.osmand.plus.download.DownloadActivityType; +import net.osmand.plus.download.IndexItem; + +import org.apache.commons.logging.Log; + +import java.text.MessageFormat; +import java.util.Locale; + +public class LocalItemsFragment extends Fragment { + public static final String TAG = "LocalItemsFragment"; + private static final Log LOG = PlatformUtil.getLog(LocalItemsFragment.class); + private static final MessageFormat formatGb = new MessageFormat("{0, number,#.##} GB", Locale.US); + + private ItemsListBuilder builder; + private RegionsAdapter regionsAdapter; + private MapsAdapter mapsAdapter; + private VoicePromtsAdapter voicePromtsAdapter; + + private TextView mapsTextView; + private ListView mapsListView; + private TextView regionsTextView; + private ListView regionsListView; + private TextView voicePromtsTextView; + private ListView voicePromtsListView; + + private static final String REGION_KEY = "world_region_key"; + private WorldRegion region; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + WorldRegion region = null; + if (savedInstanceState != null) { + Object regionObj = savedInstanceState.getSerializable(REGION_KEY); + if (regionObj != null) { + region = (WorldRegion)regionObj; + } + } + if (region == null) { + Object regionObj = getArguments().getSerializable(REGION_KEY); + if (regionObj != null) { + region = (WorldRegion)regionObj; + } + } + + this.region = region; + + View view = inflater.inflate(R.layout.download_index_fragment, container, false); + + builder = new ItemsListBuilder(getMyApplication(), this.region); + + mapsTextView = (TextView) view.findViewById(R.id.list_world_regions_title); + mapsTextView.setText("Region maps".toUpperCase()); + mapsListView = (ListView) view.findViewById(R.id.list_world_regions); + mapsAdapter = new MapsAdapter(getActivity()); + mapsListView.setAdapter(mapsAdapter); + + regionsTextView = (TextView) view.findViewById(R.id.list_world_maps_title); + regionsTextView.setText("Additional maps".toUpperCase()); + regionsListView = (ListView) view.findViewById(R.id.list_world_maps); + regionsAdapter = new RegionsAdapter(getActivity()); + regionsListView.setAdapter(regionsAdapter); + regionsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + Object obj = regionsAdapter.getItem(position); + if (obj instanceof WorldRegion) { + WorldRegion region = (WorldRegion) obj; + ((LocalDialogFragment) getParentFragment()) + .onRegionSelected(region); + } + } + }); + + voicePromtsTextView = (TextView) view.findViewById(R.id.list_voice_promts_title); + voicePromtsTextView.setText("Voice promts".toUpperCase()); + voicePromtsListView = (ListView) view.findViewById(R.id.list_voice_promts); + voicePromtsAdapter = new VoicePromtsAdapter(getActivity(), getMyApplication()); + voicePromtsListView.setAdapter(voicePromtsAdapter); + + if (builder.build()) { + fillMapsAdapter(); + fillRegionsAdapter(); + fillVoicePromtsAdapter(); + } + + return view; + } + + public static void setListViewHeightBasedOnChildren(ListView listView) { + ListAdapter listAdapter = listView.getAdapter(); + if (listAdapter == null) { + // pre-condition + return; + } + + int totalHeight = 0; + for (int i = 0; i < listAdapter.getCount(); i++) { + View listItem = listAdapter.getView(i, null, listView); + listItem.measure(0, 0); + totalHeight += listItem.getMeasuredHeight(); + } + + ViewGroup.LayoutParams params = listView.getLayoutParams(); + params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); + listView.setLayoutParams(params); + listView.requestLayout(); + } + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putSerializable(REGION_KEY, region); + super.onSaveInstanceState(outState); + } + + public OsmandApplication getMyApplication() { + return (OsmandApplication)getActivity().getApplication(); + } + + private void fillRegionsAdapter() { + if (regionsAdapter != null) { + regionsAdapter.clear(); + regionsAdapter.addAll(builder.getAllResourceItems()); + updateVisibility(regionsAdapter, regionsTextView, regionsListView); + } + } + + private void fillMapsAdapter() { + if (mapsAdapter != null) { + mapsAdapter.clear(); + mapsAdapter.addAll(builder.getRegionMapItems()); + updateVisibility(mapsAdapter, mapsTextView, mapsListView); + } + } + + private void fillVoicePromtsAdapter() { + if (voicePromtsAdapter != null) { + voicePromtsAdapter.clear(); + //voicePromtsAdapter.addAll(cats); + updateVisibility(voicePromtsAdapter, voicePromtsTextView, voicePromtsListView); + } + } + + private void updateVisibility(ArrayAdapter adapter, TextView textView, ListView listView) { + if (adapter.isEmpty()) { + textView.setVisibility(View.GONE); + listView.setVisibility(View.GONE); + } else { + textView.setVisibility(View.VISIBLE); + listView.setVisibility(View.VISIBLE); + setListViewHeightBasedOnChildren(listView); + } + } + + private DownloadActivity getDownloadActivity() { + return (DownloadActivity) getActivity(); + } + + public static LocalItemsFragment createInstance(WorldRegion region) { + Bundle bundle = new Bundle(); + bundle.putSerializable(REGION_KEY, region); + LocalItemsFragment fragment = new LocalItemsFragment(); + fragment.setArguments(bundle); + return fragment; + } + + private static class MapsAdapter extends ArrayAdapter { + + public MapsAdapter(Context context) { + super(context, R.layout.simple_list_menu_item); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder viewHolder; + if (convertView == null) { + convertView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.two_line_with_images_list_item, parent, false); + viewHolder = new ItemViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (ItemViewHolder) convertView.getTag(); + } + ItemsListBuilder.ResourceItem item = getItem(position); + viewHolder.bindIndexItem(item.getIndexItem(), (DownloadActivity) getContext(), true, false); + return convertView; + } + } + + private static class RegionsAdapter extends ArrayAdapter { + + public RegionsAdapter(Context context) { + super(context, R.layout.two_line_with_images_list_item); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ItemViewHolder viewHolder; + if (convertView == null) { + convertView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.two_line_with_images_list_item, parent, false); + viewHolder = new ItemViewHolder(convertView); + convertView.setTag(viewHolder); + } else { + viewHolder = (ItemViewHolder) convertView.getTag(); + } + Object item = getItem(position); + if (item instanceof WorldRegion) { + viewHolder.bindRegion((WorldRegion) item, (DownloadActivity) getContext()); + } else if (item instanceof ItemsListBuilder.ResourceItem) { + viewHolder.bindIndexItem(((ItemsListBuilder.ResourceItem) item).getIndexItem(), + (DownloadActivity) getContext(), false, true); + } else { + throw new IllegalArgumentException("Item must be of type WorldRegion or " + + "IndexItem but is of type:" + item.getClass()); + } + return convertView; + } + } + + private static class VoicePromtsAdapter extends ArrayAdapter { + private final OsmandApplication osmandApplication; + + public VoicePromtsAdapter(Context context, OsmandApplication osmandApplication) { + super(context, R.layout.simple_list_menu_item); + this.osmandApplication = osmandApplication; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + RegionItemViewHolder viewHolder; + if (convertView == null) { + convertView = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.simple_list_menu_item, parent, false); + viewHolder = new RegionItemViewHolder(); + viewHolder.textView = (TextView) convertView.findViewById(R.id.title); + convertView.setTag(viewHolder); + } else { + viewHolder = (RegionItemViewHolder) convertView.getTag(); + } + Drawable iconLeft = osmandApplication.getIconsCache() + .getContentIcon(R.drawable.ic_world_globe_dark); + viewHolder.textView.setCompoundDrawablesWithIntrinsicBounds(iconLeft, null, null, null); + viewHolder.textView.setText(getItem(position).toString()); + return convertView; + } + } + + private static class RegionItemViewHolder { + TextView textView; + } +} diff --git a/OsmAnd/src/net/osmand/plus/download/items/DownloadItemsFragment.java b/OsmAnd/src/net/osmand/plus/download/items/WorldItemsFragment.java similarity index 69% rename from OsmAnd/src/net/osmand/plus/download/items/DownloadItemsFragment.java rename to OsmAnd/src/net/osmand/plus/download/items/WorldItemsFragment.java index 04a5f61ed3..db6cc0d5f4 100644 --- a/OsmAnd/src/net/osmand/plus/download/items/DownloadItemsFragment.java +++ b/OsmAnd/src/net/osmand/plus/download/items/WorldItemsFragment.java @@ -4,6 +4,7 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentTransaction; import android.support.v4.view.MenuItemCompat; import android.view.LayoutInflater; import android.view.Menu; @@ -11,6 +12,7 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; +import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListAdapter; import android.widget.ListView; @@ -21,25 +23,30 @@ import net.osmand.plus.OsmandApplication; import net.osmand.plus.R; import net.osmand.plus.WorldRegion; import net.osmand.plus.download.DownloadActivity; +import net.osmand.plus.download.newimplementation.MapsInCategoryFragment; import org.apache.commons.logging.Log; import java.text.MessageFormat; import java.util.Locale; -public class DownloadItemsFragment extends Fragment { - private static final Log LOG = PlatformUtil.getLog(DownloadItemsFragment.class); +public class WorldItemsFragment extends Fragment { + public static final String TAG = "WorldItemsFragment"; + private static final Log LOG = PlatformUtil.getLog(WorldItemsFragment.class); private static final MessageFormat formatGb = new MessageFormat("{0, number,#.##} GB", Locale.US); public static final int RELOAD_ID = 0; private ItemsListBuilder builder; private WorldRegionsAdapter worldRegionsAdapter; - private WorldMapAdapter worldMapAdapter; + private WorldMapsAdapter worldMapsAdapter; private VoicePromtsAdapter voicePromtsAdapter; + private TextView worldRegionsTextView; private ListView worldRegionsListView; - private ListView worldMapListView; + private TextView worldMapsTextView; + private ListView worldMapsListView; + private TextView voicePromtsTextView; private ListView voicePromtsListView; @Override @@ -53,28 +60,37 @@ public class DownloadItemsFragment extends Fragment { View view = inflater.inflate(R.layout.download_index_fragment, container, false); builder = new ItemsListBuilder(getMyApplication(), getMyApplication().getWorldRegion()); - boolean hasBuilt = builder.build(); + worldRegionsTextView = (TextView) view.findViewById(R.id.list_world_regions_title); + worldRegionsTextView.setText("World regions".toUpperCase()); worldRegionsListView = (ListView) view.findViewById(R.id.list_world_regions); worldRegionsAdapter = new WorldRegionsAdapter(getActivity(), getMyApplication()); worldRegionsListView.setAdapter(worldRegionsAdapter); - if (hasBuilt) { - fillWorldRegionsAdapter(); - } + worldRegionsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { + @Override + public void onItemClick(AdapterView parent, View view, int position, long id) { + WorldRegion region = worldRegionsAdapter.getItem(position); - worldMapListView = (ListView) view.findViewById(R.id.list_world_map); - worldMapAdapter = new WorldMapAdapter(getActivity(), getMyApplication()); - worldMapListView.setAdapter(worldMapAdapter); - if (hasBuilt) { - fillWorldMapAdapter(); - } + FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction(); + fragmentTransaction.addToBackStack(null); + LocalDialogFragment.createInstance(region) + .show(fragmentTransaction, MapsInCategoryFragment.TAG); + } + }); + worldMapsTextView = (TextView) view.findViewById(R.id.list_world_maps_title); + worldMapsTextView.setText("World maps".toUpperCase()); + worldMapsListView = (ListView) view.findViewById(R.id.list_world_maps); + worldMapsAdapter = new WorldMapsAdapter(getActivity()); + worldMapsListView.setAdapter(worldMapsAdapter); + + voicePromtsTextView = (TextView) view.findViewById(R.id.list_voice_promts_title); + voicePromtsTextView.setText("Voice promts".toUpperCase()); voicePromtsListView = (ListView) view.findViewById(R.id.list_voice_promts); voicePromtsAdapter = new VoicePromtsAdapter(getActivity(), getMyApplication()); voicePromtsListView.setAdapter(voicePromtsAdapter); - if (hasBuilt) { - fillVoicePromtsAdapter(); - } + + onCategorizationFinished(); return view; } @@ -107,15 +123,15 @@ public class DownloadItemsFragment extends Fragment { if (worldRegionsAdapter != null) { worldRegionsAdapter.clear(); worldRegionsAdapter.addAll(builder.getRegionsFromAllItems()); - setListViewHeightBasedOnChildren(worldRegionsListView); + updateVisibility(worldRegionsAdapter, worldRegionsTextView, worldRegionsListView); } } - private void fillWorldMapAdapter() { - if (worldMapAdapter != null) { - worldMapAdapter.clear(); - worldMapAdapter.addAll(builder.getRegionMapItems()); - setListViewHeightBasedOnChildren(worldMapListView); + private void fillWorldMapsAdapter() { + if (worldMapsAdapter != null) { + worldMapsAdapter.clear(); + worldMapsAdapter.addAll(builder.getRegionMapItems()); + updateVisibility(worldMapsAdapter, worldMapsTextView, worldMapsListView); } } @@ -123,6 +139,18 @@ public class DownloadItemsFragment extends Fragment { if (voicePromtsAdapter != null) { voicePromtsAdapter.clear(); //voicePromtsAdapter.addAll(cats); + updateVisibility(voicePromtsAdapter, voicePromtsTextView, voicePromtsListView); + } + } + + private void updateVisibility(ArrayAdapter adapter, TextView textView, ListView listView) { + if (adapter.isEmpty()) { + textView.setVisibility(View.GONE); + listView.setVisibility(View.GONE); + } else { + textView.setVisibility(View.VISIBLE); + listView.setVisibility(View.VISIBLE); + setListViewHeightBasedOnChildren(listView); } } @@ -150,7 +178,7 @@ public class DownloadItemsFragment extends Fragment { public void onCategorizationFinished() { if (builder.build()) { fillWorldRegionsAdapter(); - fillWorldMapAdapter(); + fillWorldMapsAdapter(); fillVoicePromtsAdapter(); } } @@ -187,30 +215,25 @@ public class DownloadItemsFragment extends Fragment { } } - private static class WorldMapAdapter extends ArrayAdapter { - private final OsmandApplication osmandApplication; + private static class WorldMapsAdapter extends ArrayAdapter { - public WorldMapAdapter(Context context, OsmandApplication osmandApplication) { + public WorldMapsAdapter(Context context) { super(context, R.layout.simple_list_menu_item); - this.osmandApplication = osmandApplication; } @Override public View getView(int position, View convertView, ViewGroup parent) { - ViewHolder viewHolder; + ItemViewHolder viewHolder; if (convertView == null) { convertView = LayoutInflater.from(parent.getContext()) - .inflate(R.layout.simple_list_menu_item, parent, false); - viewHolder = new ViewHolder(); - viewHolder.textView = (TextView) convertView.findViewById(R.id.title); + .inflate(R.layout.two_line_with_images_list_item, parent, false); + viewHolder = new ItemViewHolder(convertView); convertView.setTag(viewHolder); } else { - viewHolder = (ViewHolder) convertView.getTag(); + viewHolder = (ItemViewHolder) convertView.getTag(); } - Drawable iconLeft = osmandApplication.getIconsCache() - .getContentIcon(R.drawable.ic_world_globe_dark); - viewHolder.textView.setCompoundDrawablesWithIntrinsicBounds(iconLeft, null, null, null); - viewHolder.textView.setText(getItem(position).getTitle()); + ItemsListBuilder.ResourceItem item = getItem(position); + viewHolder.bindIndexItem(item.getIndexItem(), (DownloadActivity) getContext(), false, false); return convertView; }