We know that after entering the Baidu image and entering a keyword, we first see a lot of thumbnails. When we click a thumbnail, we can go to the big image display page.
The big picture display page contains an image gallery. The current big picture is the image we just clicked. Now let's take a look at how to achieve similar effects in Android:
First, we need a control to display the thumbnail. Nothing is better than the gridview.
The configuration file is as follows:
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> Android: Orientation = "vertical" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> <gridview <br/> Android: id = "@ + ID/view_photos" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> Android: layout_margintop = "10dp" <br/> Android: columnwidth = "100dp" <br/> Android: numcolumns = "auto_fit" <br/> Android: horizontalspacing = "5dp" <br/> Android: verticalspacing = "5dp" <br/> Android: listselector = "@ drawable/frame_select"/> <br/> </linearlayout>
For each item in the gridview is a thumbnail, We need to inherit the baseadapter to implement our own gridimageadapter. Code:
Package COM. liner. manager; <br/> Import Java. util. list; <br/> Import COM. liner. manager. adapter. gridimageadapter; <br/> Import android. app. activity; <br/> Import android. graphics. bitmap; <br/> Import android. OS. bundle; <br/> Import android. view. view; <br/> Import android. widget. adapterview; <br/> Import android. widget. gallery; <br/> Import android. widget. imagebutton; <br/> Import android. widget. adapterview. on Itemclicklistener; <br/> public class galleryactivity extends activity {</P> <p> private imagebutton currentimage; <br/> private gallery Gallery; </P> <p> private int [] thumbids; <br/> private int currentpos; </P> <p> private bitmap currentbitmap; </P> <p> private list <bitmap> bitmapcache; </P> <p> Public void oncreate (bundle savedinstancestate) {<br/> super. oncreate (savedinstancestate); <br/> setcontentview (R. layout. Gallery); </P> <p> currentimage = (imagebutton) This. findviewbyid (R. id. image_current); <br/> gallery = (Gallery) This. findviewbyid (R. id. image_gallery); <br/> Gallery. setonitemclicklistener (galleryitemclicklistener); <br/> Init (); <br/>}</P> <p> private onitemclicklistener galleryitemclicklistener = new onitemclicklistener () {<br/> @ override <br/> Public void onitemclick (adapterview <?> P, view V, int position, <br/> long ID) {<br/> // click event <br/> showcurrentimage (position ); <br/>}< br/>}; </P> <p> private void Init () {<br/> thumbids = This. getintent (). getintarrayextra ("thumbids"); <br/> currentpos = This. getintent (). getintextra ("currentpos", 0); <br/> // galleryids = This. getthumbnailids (currentpos); // The image information in the current gallery <br/> bitmapcache = bitmaputils. querythumbnaillistbyids (this, thumbids ); <Br/> gridimageadapter adapter = new gridimageadapter (this. getapplication (), bitmapcache); <br/> Gallery. setadapter (adapter); <br/> Gallery. setselection (currentpos); </P> <p> showcurrentimage (currentpos); </P> <p >}</P> <p> private void showcurrentimage (INT position) {</P> <p> If (currentbitmap! = NULL) {<br/> currentbitmap. recycle (); <br/>}</P> <p> currentbitmap = bitmaputils. queryimagebythumbnailid (galleryactivity. this, thumbids [position]); <br/> If (currentbitmap! = NULL) {<br/> currentimage. setimagebitmap (currentbitmap); <br/>}else {<br/> // do nothing <br/>}</P> <p> // releasebitmaps (); <br/>}</P> <p>/** <br/> * cache the three images before the current display of gallery, the rest are released to make the memory insufficient <br/> * The reason why the first three and the last three, it is for gallery to slide more smoothly <br/> */<br/> private void releasebitmaps () {<br/> int start = Gallery. getfirstvisibleposition ()-3; // the starting position of the cache <br/> int end = Gallery. getlastvisibleposition () + 3; // The cache end position </P> <P> bitmap delbitmap; <br/> for (INT I = 0; I <start; I ++) {<br/> delbitmap = bitmapcache. get (I); <br/> If (delbitmap! = NULL) {<br/> bitmapcache. remove (I); <br/> delbitmap. recycle (); <br/>}< br/> for (INT I = end + 1; I <bitmapcache. size (); I ++) {<br/> delbitmap = bitmapcache. get (I); <br/> If (delbitmap! = NULL) {<br/> bitmapcache. remove (I); <br/> delbitmap. recycle (); <br/>}</P> <p>/** <br/> * obtain the first three IDs and three IDs <br/> * @ Param position <br/> * @ return <br/> */<br/> private integer [] getthumbnailids (INT position) {<br/> integer [] IDs = new integer [] {0, 0, 0, 0}; <br/> int currpos = 0; <br/> // The processing here is more complicated <br/> for (INT I = 3; I> 0; I --) {<br/> If (position-I> = 0) {<br/> currpos = 3-I; <br/> IDs [currpos] = thumbids [position-I]; <br/>}< br/> IDs [++ currpos] = thumbids [position]; // current ID <br/> // currgalleryselection = currpos; <br/> // The number of locations left on the right is 7-currpos-1 <br/> for (INT I = 1; I <= 6-currpos; I ++) {<br/> If (Position + I <thumbids. length) {<br/> IDs [currpos + I] = thumbids [Position + I]; <br/>}</P> <p> return IDs; <br/>}< br/>
Then, we can query the mediastore Multimedia Image Library in the activity to query the thumbnails of all images. The thumbnail is located:
Mediastore. Images. thumbnails. The activity code is as follows:
Package COM. liner. manager; <br/> Import Java. util. arraylist; <br/> Import Java. util. list; <br/> Import COM. liner. manager. adapter. gridimageadapter; <br/> Import android. app. activity; <br/> Import android. content. intent; <br/> Import android. database. cursor; <br/> Import android. graphics. bitmap; <br/> Import android. graphics. bitmapfactory; <br/> Import android.net. uri; <br/> Import android. OS. bundle; <br/> impo RT android. provider. mediastore; <br/> Import android. view. view; <br/> Import android. widget. adapter; <br/> Import android. widget. adapterview; <br/> Import android. widget. gridview; <br/> Import android. widget. toast; <br/> public class mainactivity extends activity {<br/> private gridview photoview; <br/> private gridimageadapter imageadapter; </P> <p> private cursor; <br/> private int [] thumbids; </P> <p> @ Override <br/> Public void oncreate (bundle savedinstancestate) {<br/> super. oncreate (savedinstancestate); <br/> setcontentview (R. layout. main); </P> <p> photoview = (gridview) This. findviewbyid (R. id. view_photos); <br/> photoview. setonitemclicklistener (photoclicklistener); </P> <p> // showimages (); <br/> showthumbnails (); <br/>}</P> <p> private void showthumbnails () {</P> <p> cursor = bitmaputils. queryt Humbnails (this); <br/> If (cursor. movetofirst () {<br/> List <bitmap> bitmaps = new arraylist <bitmap> (); <br/> thumbids = new int [cursor. getcount ()]; <br/> for (INT I = 0; I <cursor. getcount (); I ++) {<br/> cursor. movetoposition (I); <br/> string currpath = cursor. getstring (cursor. getcolumnindexorthrow (mediastore. images. thumbnails. data); <br/> thumbids [I] = cursor. getint (cursor. getcolumnindexorthrow (Media Store. images. thumbnails. _ id); <br/> bitmap B = bitmaputils. decodebitmap (currpath, 100,100); <br/> bitmaps. add (B); <br/>}< br/> imageadapter = new gridimageadapter (this. getapplication (), bitmaps); <br/> photoview. setadapter (imageadapter); <br/>}</P> <p> private adapterview. onitemclicklistener photoclicklistener = new adapterview. onitemclicklistener () {<br/> @ override <br/> Public void onite Mclick (adapterview <?> P, view V, int position, <br/> long ID) {<br/> // when you click a thumbnail, go to the image display page <br/> intent = new intent (); <br/> intent. setclass (mainactivity. this, galleryactivity. class); <br/> intent. putextra ("thumbids", thumbids); <br/> intent. putextra ("currentpos", position); <br/> startactivity (intent); <br/>}< br/>}; </P> <p>}
Note that we have recorded the ID numbers of all thumbnails and the locations selected by the current user, and then passed them to the second display interface through intent. The layout file of the second interface is as follows: we use a gallery and an imagebutton to implement
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <linearlayout <br/> xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> Android: Orientation = "vertical"> <br/> <gallery <br/> Android: id = "@ + ID/image_gallery" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "100dp" <br/> <imagebutton <br/> Android: Id = "@ + ID/image_current" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> Android: padding = "10dp" <br/> Android: layout_margintop = "10dp" <br/> </linearlayout>
Then, the corresponding activity is as follows:
Package COM. liner. manager; <br/> Import Java. util. list; <br/> Import COM. liner. manager. adapter. gridimageadapter; <br/> Import android. app. activity; <br/> Import android. graphics. bitmap; <br/> Import android. OS. bundle; <br/> Import android. view. view; <br/> Import android. widget. adapterview; <br/> Import android. widget. gallery; <br/> Import android. widget. imagebutton; <br/> Import android. widget. adapterview. on Itemclicklistener; <br/> public class galleryactivity extends activity {</P> <p> private imagebutton currentimage; <br/> private gallery Gallery; </P> <p> private int [] thumbids; <br/> private int currentpos; </P> <p> private bitmap currentbitmap; </P> <p> private list <bitmap> bitmapcache; </P> <p> Public void oncreate (bundle savedinstancestate) {<br/> super. oncreate (savedinstancestate); <br/> setcontentview (R. layout. Gallery); </P> <p> currentimage = (imagebutton) This. findviewbyid (R. id. image_current); <br/> gallery = (Gallery) This. findviewbyid (R. id. image_gallery); <br/> Gallery. setonitemclicklistener (galleryitemclicklistener); <br/> Init (); <br/>}</P> <p> private onitemclicklistener galleryitemclicklistener = new onitemclicklistener () {<br/> @ override <br/> Public void onitemclick (adapterview <?> P, view V, int position, <br/> long ID) {<br/> // click event <br/> showcurrentimage (position ); <br/>}< br/>}; </P> <p> private void Init () {<br/> thumbids = This. getintent (). getintarrayextra ("thumbids"); <br/> currentpos = This. getintent (). getintextra ("currentpos", 0); <br/> // galleryids = This. getthumbnailids (currentpos); // The image information in the current gallery <br/> bitmapcache = bitmaputils. querythumbnaillistbyids (this, thumbids ); <Br/> gridimageadapter adapter = new gridimageadapter (this. getapplication (), bitmapcache); <br/> Gallery. setadapter (adapter); <br/> Gallery. setselection (currentpos); </P> <p> showcurrentimage (currentpos); </P> <p >}</P> <p> private void showcurrentimage (INT position) {</P> <p> If (currentbitmap! = NULL) {<br/> currentbitmap. recycle (); <br/>}</P> <p> currentbitmap = bitmaputils. queryimagebythumbnailid (galleryactivity. this, thumbids [position]); <br/> If (currentbitmap! = NULL) {<br/> currentimage. setimagebitmap (currentbitmap); <br/>}else {<br/> // do nothing <br/>}</P> <p> // releasebitmaps (); <br/>}</P> <p >}< br/>
As you can see, when a user clicks a certain item in gallery, the onitemclick event is triggered. In this event, we use the image_id corresponding to the thumbnail to extract data from mediastore. images. query the large image corresponding to the thumbnail in media. And displayed in imagebutton.
Here, when there are many images, memory overflow may occur. To avoid this situation, you can use the cache for better gallery features. Save the first three to the last three visible thumbnails. All other recycle instances. When you click gallery, you can determine the current position. If the value is greater than or less than a certain value, the cache is updated again. This ensures that the number of thumbnails in the memory is always 6 + gallery. getLastVisiblePosition-Gallery.getFirstVisiblePosition. In fact, this is the floating cache window, a fixed size window swimming on the whole coordinate (all thumbnails. It is not implemented here and will be continued in the future.
At the same time, you may have noticed that a bitmaputils class is used in the program. This class encapsulates a series of classes for querying images and parsing them into bitmap.
The Code is as follows:
Package COM. liner. manager; <br/> Import Java. util. arraylist; <br/> Import Java. util. list; <br/> Import android. app. activity; <br/> Import android. database. cursor; <br/> Import android. graphics. bitmap; <br/> Import android. graphics. bitmapfactory; <br/> Import android. provider. mediastore; <br/> Import android. util. log; <br/> Public final class bitmaputils {</P> <p> Public static bitmap decodebitmap (string path, Int displaywidth, int displayheight) {<br/> bitmapfactory. options op = new bitmapfactory. options (); <br/> op. injustdecodebounds = true; <br/> bitmap BMP = bitmapfactory. decodefile (path, OP); // obtain the size information <br/> // obtain the proportional size <br/> int wratio = (INT) math. ceil (op. outwidth/(float) displaywidth); <br/> int hratio = (INT) math. ceil (op. outheight/(float) displayheight); <br/> // if the specified size is exceeded, the ratio is reduced. <br/> If (wratio> 1 & hrati O> 1) {<br/> If (wratio> hratio) {<br/> op. insamplesize = wratio; <br/>} else {<br/> op. insamplesize = hratio; <br/>}< br/> op. injustdecodebounds = false; <br/> BMP = bitmapfactory. decodefile (path, OP); <br/> return bitmap. createscaledbitmap (BMP, displaywidth, displayheight, true ); <br/>}</P> <p>/** <br/> * use complex computing to determine scaling <br/> * @ Param path <br/> *@ param maximagesize <br/> * @ return <br/> */<br/> P Ublic static bitmap decodebitmap (string path, int maximagesize) {<br/> bitmapfactory. options op = new bitmapfactory. options (); <br/> op. injustdecodebounds = true; <br/> bitmap BMP = bitmapfactory. decodefile (path, OP); // obtain the size information <br/> int scale = 1; <br/> If (op. outwidth> maximagesize | op. outheight> maximagesize) {<br/> scale = (INT) math. pow (2, (INT) math. round (math. log (maximagesize/(double) math. max (op. Outwidth, op. outheight)/math. log (0.5); <br/>}< br/> op. injustdecodebounds = false; <br/> op. insamplesize = scale; <br/> BMP = bitmapfactory. decodefile (path, OP); <br/> return BMP; <br/>}</P> <p> Public static cursor querythumbnails (activity context) {<br/> string [] Columns = new string [] {<br/> mediastore. images. thumbnails. data, <br/> mediastore. images. thumbnails. _ id, <br/> mediastore. images. thumbnail S. image_id <br/>}; <br/> return context. managedquery (mediastore. images. thumbnails. external_content_uri, columns, null, null, mediastore. images. thumbnails. default_sort_order); <br/>}</P> <p> Public static cursor querythumbnails (activity context, string selection, string [] selectionargs) {<br/> string [] Columns = new string [] {<br/> mediastore. images. thumbnails. data, <br/> mediastore. images. thumbnails. _ Id, <br/> mediastore. images. thumbnails. image_id <br/>}; <br/> return context. managedquery (mediastore. images. thumbnails. external_content_uri, columns, selection, selectionargs, mediastore. images. thumbnails. default_sort_order); <br/>}</P> <p> Public static bitmap querythumbnailbyid (activity context, int thumbid) {<br/> string selection = mediastore. images. thumbnails. _ ID + "=? "; <Br/> string [] selectionargs = new string [] {<br/> thumbid +" "<br/>}; <br/> cursor = bitmaputils. querythumbnails (context, selection, selectionargs); </P> <p> If (cursor. movetofirst () {<br/> string Path = cursor. getstring (cursor. getcolumnindexorthrow (mediastore. images. thumbnails. data); <br/> cursor. close (); <br/> return bitmaputils. decodebitmap (path, 100,100); <br/>} else {<br/> cursor. close (); <br/> r Eturn NULL; <br/>}</P> <p> Public static bitmap [] querythumbnailsbyids (activity context, integer [] thumbids) {<br/> bitmap [] bitmaps = new bitmap [thumbids. length]; <br/> for (INT I = 0; I <bitmaps. length; I ++) {<br/> bitmaps [I] = bitmaputils. querythumbnailbyid (context, thumbids [I]); <br/>}</P> <p> return bitmaps; <br/>}</P> <p>/** <br/> * obtain all <br/> * @ Param context <br/> * @ return <br/> */<br/> Public Static list <bitmap> querythumbnaillist (activity context) {<br/> List <bitmap> bitmaps = new arraylist <bitmap> (); <br/> cursor = bitmaputils. querythumbnails (context); <br/> for (INT I = 0; I <cursor. getcount (); I ++) {<br/> cursor. movetoposition (I); <br/> string Path = cursor. getstring (cursor. getcolumnindexorthrow (mediastore. images. thumbnails. data); <br/> bitmap B = bitmaputils. decodebitmap (paths, 100, 100); <br/> bitmaps. add (B); <br/>}< br/> cursor. close (); <br/> return bitmaps; <br/>}</P> <p> Public static list <bitmap> querythumbnaillistbyids (activity context, int [] thumbids) {<br/> List <bitmap> bitmaps = new arraylist <bitmap> (); <br/> for (INT I = 0; I <thumbids. length; I ++) {<br/> bitmap B = bitmaputils. querythumbnailbyid (context, thumbids [I]); <br/> bitmaps. add (B); <br/>}</P> <p> return bitmaps; <br/>}</ P> <p> Public static cursor queryimages (activity context) {<br/> string [] Columns = new string [] {<br/> mediastore. images. media. _ id, <br/> mediastore. images. media. data, <br/> mediastore. images. media. display_name <br/>}; <br/> return context. managedquery (mediastore. images. media. external_content_uri, columns, null, null, mediastore. images. media. default_sort_order); <br/>}</P> <p> Public static cursor queryim Ages (activity context, string selection, string [] selectionargs) {<br/> string [] Columns = new string [] {<br/> mediastore. images. media. _ id, <br/> mediastore. images. media. data, <br/> mediastore. images. media. display_name <br/>}; <br/> return context. managedquery (mediastore. images. media. external_content_uri, columns, selection, selectionargs, mediastore. images. media. default_sort_order); <br/>}</P> <p> publi C static bitmap queryimagebyid (activity context, int imageid) {<br/> string selection = mediastore. Images. Media. _ ID + "=? "; <Br/> string [] selectionargs = new string [] {<br/> imageid +" "<br/>}; <br/> cursor = bitmaputils. queryimages (context, selection, selectionargs); <br/> If (cursor. movetofirst () {<br/> string Path = cursor. getstring (cursor. getcolumnindexorthrow (mediastore. images. media. data); <br/> cursor. close (); <br/> // return bitmaputils. decodebitmap (path, 260,260); <br/> return bitmaputils. decodebitmap (path, 220); // see the difference from the above method. After reading it, it is almost <br/>}else {<br/> cursor. close (); <br/> return NULL; <br/>}</P> <p>/** <br/> * obtain a large image based on the thumbnail ID. <br/> * @ Param context <br/> * @ Param thumbid <br/> * @ return <br/> */<br/> Public static bitmap queryimagebythumbnailid (activity context, integer thumbid) {</P> <p> string selection = mediastore. images. thumbnails. _ ID + "=? "; <Br/> string [] selectionargs = new string [] {<br/> thumbid +" "<br/>}; <br/> cursor = bitmaputils. querythumbnails (context, selection, selectionargs); </P> <p> If (cursor. movetofirst () {<br/> int imageid = cursor. getint (cursor. getcolumnindexorthrow (mediastore. images. thumbnails. image_id); <br/> cursor. close (); <br/> return bitmaputils. queryimagebyid (context, imageid); <br/>} else {<br/> cursor. close (); <br/> return NULL; <br/>}< br/>
This is achieved, similar to the effect of Baidu Image Browsing. As follows: