Je ne suis pas un développeur professionnel, bien que j'aie étudié en tant que programmeur. Maintenant, je travaille en tant qu'administrateur système et je prévois de passer aux développeurs. J'écris pour moi-même une application qui analyse l'un des sites Web populaires liés à l'informatique et affiche des articles dans l'application Android native. Je voulais que toutes les photos de l'article s'ouvrent dans la galerie, comme dans l'application mobile habr.
Très probablement, le manuel se révélera simple, mais je veux obtenir des commentaires et, très probablement, ce manuel sera utile à quelqu'un.
J'ai essayé plusieurs plugins. Certains n'ont pas démarré, d'autres nécessitent jQuery, ce qui ralentit le chargement des pages dans l'application. Au final, j'ai choisi le plugin PhotoSwipe. le plugin ne nécessite pas jQuery, il fonctionne rapidement et ne pèse presque rien.
Vous devez d'abord penser à l'endroit où dans l'application il est préférable de placer les fichiers source du plugin. Tout d'abord, par inexpérience, j'ai placé les fichiers dans le dossier brut, mais il est préférable de les placer dans le dossier des ressources. Faites un clic droit sur l'application → nouveau → dossier → Dossier des actifs
Le balisage sera une simple WebView:
Code<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent"></WebView> </android.support.constraint.ConstraintLayout>
Ensuite, vous devez télécharger ou cloner le référentiel depuis PhotoSwipe (lien sur le site Web du plugin) et copier l'intégralité du contenu du dossier dist dans les actifs (dist peut être renommé en PhotoSwipe. Vous pouvez également créer un fichier style.css dans le dossier css afin que les images occupent toute la largeur.
img { width: 100%; height: auto; }
Pour la galerie, vous devez connecter des styles, des fichiers javascipt et un fichier de style pour l'habillage. Vous pouvez générer du HTML:
C'est là que va le HTML pour la visualisation Web public String getHTML() { String header = "<!DOCTYPE HTML><HTML><head><title>test</title>";
.
Pour que le plugin fonctionne, vous devez également insérer le conteneur de la galerie dans la source de la page. La documentation indique que ce n'est pas un simple plugin et que vous devez effectuer une partie du travail vous-même.
Il est conseillé d'insérer le code avant la balise de fermeture
Conteneur de galerie public String getPhotoSwipeHTML() { return "<!-- Root element of PhotoSwipe. Must have class pswp. -->\n" + "<div class=\"pswp\" tabindex=\"-1\" role=\"dialog\" aria-hidden=\"true\">\n" + "\n" + " <!-- Background of PhotoSwipe. \n" + " It's a separate element as animating opacity is faster than rgba(). -->\n" + " <div class=\"pswp__bg\"></div>\n" + "\n" + " <!-- Slides wrapper with overflow:hidden. -->\n" + " <div class=\"pswp__scroll-wrap\">\n" + "\n" + " <!-- Container that holds slides. \n" + " PhotoSwipe keeps only 3 of them in the DOM to save memory.\n" + " Don't modify these 3 pswp__item elements, data is added later on. -->\n" + " <div class=\"pswp__container\">\n" + " <div class=\"pswp__item\"></div>\n" + " <div class=\"pswp__item\"></div>\n" + " <div class=\"pswp__item\"></div>\n" + " </div>\n" + "\n" + " <!-- Default (PhotoSwipeUI_Default) interface on top of sliding area. Can be changed. -->\n" + " <div class=\"pswp__ui pswp__ui--hidden\">\n" + "\n" + " <div class=\"pswp__top-bar\">\n" + "\n" + " <!-- Controls are self-explanatory. Order can be changed. -->\n" + "\n" + " <div class=\"pswp__counter\"></div>\n" + "\n" + " <button class=\"pswp__button pswp__button--close\" title=\"Close (Esc)\"></button>\n" + "\n" + " <button class=\"pswp__button pswp__button--share\" title=\"Share\"></button>\n" + "\n" + " <button class=\"pswp__button pswp__button--fs\" title=\"Toggle fullscreen\"></button>\n" + "\n" + " <button class=\"pswp__button pswp__button--zoom\" title=\"Zoom in/out\"></button>\n" + "\n" + " <!-- Preloader demo https://codepen.io/dimsemenov/pen/yyBWoR -->\n" + " <!-- element will get class pswp__preloader--active when preloader is running -->\n" + " <div class=\"pswp__preloader\">\n" + " <div class=\"pswp__preloader__icn\">\n" + " <div class=\"pswp__preloader__cut\">\n" + " <div class=\"pswp__preloader__donut\"></div>\n" + " </div>\n" + " </div>\n" + " </div>\n" + " </div>\n" + "\n" + " <div class=\"pswp__share-modal pswp__share-modal--hidden pswp__single-tap\">\n" + " <div class=\"pswp__share-tooltip\"></div> \n" + " </div>\n" + "\n" + " <button class=\"pswp__button pswp__button--arrow--left\" title=\"Previous (arrow left)\">\n" + " </button>\n" + "\n" + " <button class=\"pswp__button pswp__button--arrow--right\" title=\"Next (arrow right)\">\n" + " </button>\n" + "\n" + " <div class=\"pswp__caption\">\n" + " <div class=\"pswp__caption__center\"></div>\n" + " </div>\n" + "\n" + " </div>\n" + "\n" + " </div>\n" + "\n" + "</div>"; }
La documentation fournit un exemple de la façon d'activer le plugin en cliquant sur l'image, mais il est à noter que PhotoSwipe ne se soucie pas de la façon exacte dont il démarre. En conséquence, j'ai écrit mon script. Je montre un article du site de quelqu'un d'autre dans l'application, donc je reçois du HTML prêt à l'emploi. Afin de ne pas travailler dynamiquement avec la mise en page, dans mon script, je change la classe pour toutes les images (car il n'y a certainement aucun excès dans l'article), attribue un gestionnaire d'événements (lorsque vous cliquez dessus, l'URL est transmise - elle sert d'identifiant pour la galerie et le plug-in démarre).
Le plugin doit connaître la taille de l'image. Étant donné que la galerie est connectée lorsque la page entière est chargée, il est facile de connaître les tailles finales des images grâce aux propriétés naturalWidth et naturalHeight de l'image.
Code de script. Tout d'abord, lorsque la page se charge, la fonction init () démarre; Ensuite, lorsque vous cliquez sur l'image openGallery ().
Ensuite, vous devez configurer WebView et charger la page.
webView = findViewById(R.id.webView); webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient()); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setDomStorageEnabled(true);
À ce stade, la page se charge, le plugin démarre lorsque vous cliquez sur l'image, mais lorsque vous appuyez sur le bouton de retour avec la galerie ouverte, l'application entière se ferme, pas le plugin.
Pour résoudre ce problème, j'ai créé un pont Javascipt.
Vous devez d'abord créer un singleton avec l'état de la galerie.
Code package me.denko.photoswipe; class GalleryState { private static final GalleryState ourInstance = new GalleryState(); static GalleryState getInstance() { return ourInstance; } private GalleryState() { } private boolean isGallery = false; public boolean isGallery() { return isGallery; } public void setGallery(boolean gallery) { isGallery = gallery; } }
Interface supplémentaire pour appeler depuis WebView
Code package me.denko.photoswipe; import android.webkit.JavascriptInterface; public class JavascriptFromWebView { @JavascriptInterface public static void setGallery(boolean bool) { GalleryState.getInstance().setGallery(bool); } }
Vous devez connecter cette interface à WebView
webView.addJavascriptInterface(new JavascriptFromWebView(), "callAndroid");
Dans le script d'ouverture de la galerie, vous devez ajouter
callAndroid.setGallery(true);
Le script de fermeture de la galerie dans le fichier photoswipe.js
Code close: function() { if(!_isOpen) { return; } callAndroid.setGallery(false);
Maintenant, lorsque vous ouvrez la galerie, l'état est défini sur true, lorsqu'il est fermé, false. Il ne reste plus qu'à ajouter le gestionnaire de bouton de retour pour WebView.
Code webView.setOnKeyListener(new View.OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() != KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) { if (GalleryState.getInstance().isGallery()) { webView.reload(); GalleryState.getInstance().setGallery(false); } else onBackPressed(); } return true; } });
Maintenant, la galerie peut être ouverte puis fermée avec le bouton de retour.
Code d'application
github complet.
La critique du code est la bienvenue. Si j'ai fait quelque chose de mal, veuillez en parler dans les commentaires.