Add view pager for images

This commit is contained in:
Vitaliy 2020-04-22 23:11:18 +03:00
parent c06960a4be
commit cf84c56243
5 changed files with 102 additions and 75 deletions

View file

@ -13,18 +13,10 @@
android:orientation="vertical" android:orientation="vertical"
android:paddingBottom="@dimen/list_header_settings_top_margin"> android:paddingBottom="@dimen/list_header_settings_top_margin">
<HorizontalScrollView <net.osmand.plus.LockableViewPager
android:id="@+id/images_pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="132dp" />
<LinearLayout
android:id="@+id/images_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxHeight="132dp"
android:orientation="horizontal" />
</HorizontalScrollView>
<net.osmand.plus.widgets.TextViewEx <net.osmand.plus.widgets.TextViewEx
android:id="@+id/description" android:id="@+id/description"

View file

@ -11,6 +11,7 @@
Thx - Hardy Thx - Hardy
--> -->
<string name="download_unsupported_action">Unsupported action %1$s</string>
<string name="extra_maps_menu_group">Extra maps</string> <string name="extra_maps_menu_group">Extra maps</string>
<string name="custom_color">Custom color</string> <string name="custom_color">Custom color</string>
<string name="lang_lmo">Lombard</string> <string name="lang_lmo">Lombard</string>

View file

@ -9,7 +9,7 @@ import net.osmand.map.WorldRegion;
import net.osmand.plus.download.CustomIndexItem; import net.osmand.plus.download.CustomIndexItem;
import net.osmand.plus.download.DownloadActivityType; import net.osmand.plus.download.DownloadActivityType;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.ui.DescriptionInfo; import net.osmand.plus.download.ui.DownloadDescriptionInfo;
import net.osmand.util.Algorithms; import net.osmand.util.Algorithms;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -36,7 +36,7 @@ public class CustomRegion extends WorldRegion {
private JSONArray downloadItemsJson; private JSONArray downloadItemsJson;
private DescriptionInfo descriptionInfo; private DownloadDescriptionInfo descriptionInfo;
private Map<String, String> names = new HashMap<>(); private Map<String, String> names = new HashMap<>();
private Map<String, String> icons = new HashMap<>(); private Map<String, String> icons = new HashMap<>();
@ -70,7 +70,7 @@ public class CustomRegion extends WorldRegion {
} }
@Nullable @Nullable
public DescriptionInfo getDescriptionInfo() { public DownloadDescriptionInfo getDescriptionInfo() {
return descriptionInfo; return descriptionInfo;
} }
@ -106,7 +106,7 @@ public class CustomRegion extends WorldRegion {
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
region.headerColor = 0; region.headerColor = 0;
} }
region.descriptionInfo = DescriptionInfo.fromJson(object.optJSONObject("description")); region.descriptionInfo = DownloadDescriptionInfo.fromJson(object.optJSONObject("description"));
return region; return region;
} }

View file

@ -15,9 +15,9 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class DescriptionInfo { public class DownloadDescriptionInfo {
private static final Log LOG = PlatformUtil.getLog(DescriptionInfo.class); private static final Log LOG = PlatformUtil.getLog(DownloadDescriptionInfo.class);
private JSONArray buttonsJson; private JSONArray buttonsJson;
private List<String> imageUrls; private List<String> imageUrls;
@ -32,49 +32,44 @@ public class DescriptionInfo {
return description != null ? Html.fromHtml(description) : null; return description != null ? Html.fromHtml(description) : null;
} }
public List<DownloadActionButton> getDownloadActionButtons(Context ctx) { public List<ActionButton> getActionButtons(Context ctx) {
List<DownloadActionButton> downloadActionButtons = new ArrayList<>(); List<ActionButton> actionButtons = new ArrayList<>();
if (buttonsJson != null) { if (buttonsJson != null) {
try { try {
for (int i = 0; i < buttonsJson.length(); i++) { for (int i = 0; i < buttonsJson.length(); i++) {
DescriptionActionButtonType type = null;
String url = null; String url = null;
String actionType = null;
JSONObject object = buttonsJson.getJSONObject(i); JSONObject object = buttonsJson.getJSONObject(i);
if (object.has("url")) { if (object.has("url")) {
url = object.optString("url"); url = object.optString("url");
} else if (object.has("action")) { } else if (object.has("action")) {
String action = object.optString("action"); actionType = object.optString("action");
for (DescriptionActionButtonType buttonType : DescriptionActionButtonType.values()) {
if (buttonType.name().equalsIgnoreCase(action)) {
type = buttonType;
}
}
} }
Map<String, String> localizedMap = JsonUtils.getLocalizedMapFromJson(object); Map<String, String> localizedMap = JsonUtils.getLocalizedMapFromJson(object);
String name = JsonUtils.getLocalizedResFromMap(ctx, localizedMap, null); String name = JsonUtils.getLocalizedResFromMap(ctx, localizedMap, null);
DownloadActionButton actionButton = new DownloadActionButton(type, name, url); ActionButton actionButton = new ActionButton(actionType, name, url);
downloadActionButtons.add(actionButton); actionButtons.add(actionButton);
} }
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
return downloadActionButtons; return actionButtons;
} }
public static DescriptionInfo fromJson(JSONObject json) { public static DownloadDescriptionInfo fromJson(JSONObject json) {
if (json != null) { if (json != null) {
DescriptionInfo descriptionInfo = new DescriptionInfo(); DownloadDescriptionInfo downloadDescriptionInfo = new DownloadDescriptionInfo();
try { try {
descriptionInfo.texts = JsonUtils.getLocalizedMapFromJson("text", json); downloadDescriptionInfo.texts = JsonUtils.getLocalizedMapFromJson("text", json);
descriptionInfo.imageUrls = JsonUtils.jsonArrayToList("image", json); downloadDescriptionInfo.imageUrls = JsonUtils.jsonArrayToList("image", json);
descriptionInfo.buttonsJson = json.optJSONArray("button"); downloadDescriptionInfo.buttonsJson = json.optJSONArray("button");
} catch (JSONException e) { } catch (JSONException e) {
LOG.error(e); LOG.error(e);
} }
return descriptionInfo; return downloadDescriptionInfo;
} }
return null; return null;
} }
@ -90,25 +85,20 @@ public class DescriptionInfo {
return descrJson; return descrJson;
} }
public enum DescriptionActionButtonType { public static class ActionButton {
DOWNLOAD,
URL
}
public static class DownloadActionButton { private String actionType;
private DescriptionInfo.DescriptionActionButtonType type;
private String name; private String name;
private String url; private String url;
public DownloadActionButton(DescriptionInfo.DescriptionActionButtonType type, String name, String url) { public ActionButton(String actionType, String name, String url) {
this.type = type; this.actionType = actionType;
this.name = name; this.name = name;
this.url = url; this.url = url;
} }
public DescriptionInfo.DescriptionActionButtonType getType() { public String getActionType() {
return type; return actionType;
} }
public String getName() { public String getName() {

View file

@ -22,19 +22,21 @@ import android.widget.ExpandableListView.OnChildClickListener;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.view.MenuItemCompat; import androidx.core.view.MenuItemCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.viewpager.widget.PagerAdapter;
import com.squareup.picasso.Callback; import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import com.squareup.picasso.RequestCreator;
import net.osmand.AndroidNetworkUtils; import net.osmand.AndroidNetworkUtils;
import net.osmand.AndroidUtils; import net.osmand.AndroidUtils;
import net.osmand.PicassoUtils; import net.osmand.PicassoUtils;
import net.osmand.plus.CustomRegion; import net.osmand.plus.CustomRegion;
import net.osmand.plus.LockableViewPager;
import net.osmand.plus.OsmandApplication; import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R; import net.osmand.plus.R;
import net.osmand.plus.UiUtilities; import net.osmand.plus.UiUtilities;
@ -49,6 +51,7 @@ import net.osmand.plus.download.DownloadResourceGroup.DownloadResourceGroupType;
import net.osmand.plus.download.DownloadResources; import net.osmand.plus.download.DownloadResources;
import net.osmand.plus.download.DownloadValidationManager; import net.osmand.plus.download.DownloadValidationManager;
import net.osmand.plus.download.IndexItem; import net.osmand.plus.download.IndexItem;
import net.osmand.plus.download.ui.DownloadDescriptionInfo.ActionButton;
import net.osmand.plus.helpers.AndroidUiHelper; import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper; import net.osmand.plus.inapp.InAppPurchaseHelper;
import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener; import net.osmand.plus.inapp.InAppPurchaseHelper.InAppPurchaseListener;
@ -251,16 +254,16 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
if (descriptionView != null) { if (descriptionView != null) {
if (group != null && group.getRegion() instanceof CustomRegion) { if (group != null && group.getRegion() instanceof CustomRegion) {
CustomRegion customRegion = (CustomRegion) group.getRegion(); CustomRegion customRegion = (CustomRegion) group.getRegion();
net.osmand.plus.download.ui.DescriptionInfo descriptionInfo = customRegion.getDescriptionInfo(); DownloadDescriptionInfo downloadDescriptionInfo = customRegion.getDescriptionInfo();
if (descriptionInfo != null) { if (downloadDescriptionInfo != null) {
TextView description = descriptionView.findViewById(R.id.description); TextView description = descriptionView.findViewById(R.id.description);
CharSequence descr = descriptionInfo.getLocalizedDescription(activity); CharSequence descr = downloadDescriptionInfo.getLocalizedDescription(activity);
description.setText(descr); description.setText(descr);
AndroidUiHelper.updateVisibility(description, !Algorithms.isEmpty(descr)); AndroidUiHelper.updateVisibility(description, !Algorithms.isEmpty(descr));
ViewGroup buttonsContainer = descriptionView.findViewById(R.id.buttons_container); ViewGroup buttonsContainer = descriptionView.findViewById(R.id.buttons_container);
buttonsContainer.removeAllViews(); buttonsContainer.removeAllViews();
for (final DescriptionInfo.DownloadActionButton actionButton : descriptionInfo.getDownloadActionButtons(activity)) { for (final ActionButton actionButton : downloadDescriptionInfo.getActionButtons(activity)) {
String name = actionButton.getName(); String name = actionButton.getName();
if (!Algorithms.isEmpty(name)) { if (!Algorithms.isEmpty(name)) {
TextView buttonText = (TextView) activity.getLayoutInflater().inflate(R.layout.download_description_button, buttonsContainer, false); TextView buttonText = (TextView) activity.getLayoutInflater().inflate(R.layout.download_description_button, buttonsContainer, false);
@ -270,37 +273,22 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
public void onClick(View v) { public void onClick(View v) {
if (actionButton.getUrl() != null) { if (actionButton.getUrl() != null) {
WikipediaDialogFragment.showFullArticle(activity, Uri.parse(actionButton.getUrl()), nightMode); WikipediaDialogFragment.showFullArticle(activity, Uri.parse(actionButton.getUrl()), nightMode);
} else {
activity.getMyApplication().showShortToastMessage(R.string.download_unsupported_action, actionButton.getActionType());
} }
} }
}); });
buttonsContainer.addView(buttonText); buttonsContainer.addView(buttonText);
} }
} }
LockableViewPager viewPager = descriptionView.findViewById(R.id.images_pager);
ViewGroup imagesContainer = descriptionView.findViewById(R.id.images_container); if (!Algorithms.isEmpty(downloadDescriptionInfo.getImageUrls())) {
imagesContainer.removeAllViews(); ImagesPagerAdapter adapter = new ImagesPagerAdapter(downloadDescriptionInfo.getImageUrls());
viewPager.setAdapter(adapter);
final PicassoUtils picassoUtils = PicassoUtils.getPicasso(getMyApplication()); } else {
Picasso picasso = Picasso.get(); viewPager.setVisibility(View.GONE);
for (final String imageUrl : descriptionInfo.getImageUrls()) {
final ImageView image = new ImageView(getContext());
imagesContainer.addView(image);
RequestCreator rc = picasso.load(imageUrl);
rc.into(image, new Callback() {
@Override
public void onSuccess() {
image.setVisibility(View.VISIBLE);
picassoUtils.setResultLoaded(imageUrl, true);
}
@Override
public void onError(Exception e) {
image.setVisibility(View.GONE);
picassoUtils.setResultLoaded(imageUrl, false);
}
});
} }
descriptionView.findViewById(R.id.container).setVisibility(View.VISIBLE); descriptionView.findViewById(R.id.container).setVisibility(View.VISIBLE);
return; return;
} }
@ -810,4 +798,60 @@ public class DownloadResourceGroupFragment extends DialogFragment implements Dow
return true; return true;
} }
} }
private class ImagesPagerAdapter extends PagerAdapter {
private PicassoUtils picassoUtils;
private List<String> imageUrls;
public ImagesPagerAdapter(List<String> imageUrls) {
this.imageUrls = imageUrls;
picassoUtils = PicassoUtils.getPicasso(getMyApplication());
}
@Override
public int getCount() {
return imageUrls.size();
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view = createImageView(position);
container.addView(view, 0);
return view;
}
@Override
public void destroyItem(ViewGroup collection, int position, @NonNull Object view) {
collection.removeView((View) view);
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
private View createImageView(int position) {
final ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
final String imageUrl = imageUrls.get(position);
Picasso.get().load(imageUrl).into(imageView, new Callback() {
@Override
public void onSuccess() {
imageView.setVisibility(View.VISIBLE);
picassoUtils.setResultLoaded(imageUrl, true);
}
@Override
public void onError(Exception e) {
imageView.setVisibility(View.INVISIBLE);
picassoUtils.setResultLoaded(imageUrl, false);
}
});
return imageView;
}
}
} }