1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 实现仿百度图片查看功能(点击缩略图放大效果)

实现仿百度图片查看功能(点击缩略图放大效果)

时间:2020-05-14 15:20:43

相关推荐

实现仿百度图片查看功能(点击缩略图放大效果)

我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在

大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现在我们看看在Android中如何实现类似的效果:

首先,我们需要有一个控件来显示缩略图,这里没有什么比GridView更加合适了。

配置文件如下:

我们知道,进入百度图片后,输入一个关键字后,首先看到的是很多缩略图,当我们点击某张缩略图时,我们就可以进入到大图显示页面,在

大图显示页面,中包含了一个图片画廊,同时当前大图为刚刚我们点击的那张图片。现在我们看看在Android中如何实现类似的效果:

首先,我们需要有一个控件来显示缩略图,这里没有什么比GridView更加合适了。

配置文件如下:

view plaincopy to clipboardprint?

01.<?xml version="1.0" encoding="utf-8"?>

02.<LinearLayout xmlns:android="/apk/res/android"

03. android:orientation="vertical"

04. android:layout_width="fill_parent"

05. android:layout_height="fill_parent"

06. >

07. <GridView

08. android:id="@+id/view_photos"

09. android:layout_width="fill_parent"

10. android:layout_height="fill_parent"

11. android:layout_marginTop="10dp"

12. android:columnWidth="100dp"

13. android:numColumns="auto_fit"

14. android:horizontalSpacing="5dp"

15. android:verticalSpacing="5dp"

16. android:listSelector="@drawable/frame_select" />

17.</LinearLayout>

对于GridView中每一项是一张缩略图,我们需要继承BaseAdapter,实现自己的一个GridImageAdapter,代码:

view plaincopy to clipboardprint?

01.package com.liner.manager;

02.import java.util.List;

03.import com.liner.manager.adapter.GridImageAdapter;

04.import android.app.Activity;

05.import android.graphics.Bitmap;

06.import android.os.Bundle;

07.import android.view.View;

08.import android.widget.AdapterView;

09.import android.widget.Gallery;

10.import android.widget.ImageButton;

11.import android.widget.AdapterView.OnItemClickListener;

12.public class GalleryActivity extends Activity{

13.

14. private ImageButton currentImage;

15. private Gallery gallery;

16.

17. private int[] thumbIds;

18. private int currentPos;

19.

20. private Bitmap currentBitmap;

21.

22. private List<Bitmap> bitmapCache;

23.

24. public void onCreate(Bundle savedInstanceState){

25. super.onCreate(savedInstanceState);

26. setContentView(R.layout.gallery);

27.

28. currentImage = (ImageButton)this.findViewById(R.id.image_current);

29. gallery = (Gallery)this.findViewById(R.id.image_gallery);

30. gallery.setOnItemClickListener(galleryItemClickListener);

31. init();

32. }

33.

34. private OnItemClickListener galleryItemClickListener = new OnItemClickListener() {

35. @Override

36. public void onItemClick(AdapterView<?> p, View v, int position,

37. long id) {

38. // 点击事件

39. showCurrentImage(position);

40. }

41. };

42.

43. private void init(){

44. thumbIds = this.getIntent().getIntArrayExtra("thumbIds");

45. currentPos = this.getIntent().getIntExtra("currentPos",0);

46. //galleryIds = this.getThumbnailIds(currentPos); //当前的gallery里的图片信息

47. bitmapCache = BitmapUtils.queryThumbnailListByIds(this, thumbIds);

48. GridImageAdapter adapter = new GridImageAdapter(this.getApplication(), bitmapCache);

49. gallery.setAdapter(adapter);

50. gallery.setSelection(currentPos);

51.

52. showCurrentImage(currentPos);

53.

54. }

55.

56. private void showCurrentImage(int position){

57.

58. if(currentBitmap != null){

59. currentBitmap.recycle();

60. }

61.

62. currentBitmap = BitmapUtils.queryImageByThumbnailId(GalleryActivity.this, thumbIds[position]);

63. if(currentBitmap != null){

64. currentImage.setImageBitmap(currentBitmap);

65. }else{

66. //什么都不做

67. }

68.

69. //releaseBitmaps();

70. }

71.

72. /**

73. * 将Gallery当前可见的显示之前的3张,后3张缓存起来,其余的释放掉,这样是为了放置内存不够用

74. * 之所以前三张后三张,是为了Gallery可以滑动的更加顺畅

75. */

76. private void releaseBitmaps(){

77. int start = gallery.getFirstVisiblePosition()-3; //缓存的起始位置

78. int end = gallery.getLastVisiblePosition()+3; //缓存的结束位置

79.

80. Bitmap delBitmap;

81. for(int i=0; i<start; i++){

82. delBitmap = bitmapCache.get(i);

83. if(delBitmap != null){

84. bitmapCache.remove(i);

85. delBitmap.recycle();

86. }

87. }

88. for(int i=end+1; i<bitmapCache.size(); i++){

89. delBitmap = bitmapCache.get(i);

90. if(delBitmap != null){

91. bitmapCache.remove(i);

92. delBitmap.recycle();

93. }

94. }

95. }

96.

97. /**

98. * 获取当前位置的前三个Id和后三个Id

99. * @param position

100. * @return

101. */

102. private Integer[] getThumbnailIds(int position){

103. Integer[] ids = new Integer[]{0,0,0,0,0,0,0};

104. int currPos = 0;

105. //关于这里的处理,比较复杂

106. for(int i=3; i>0; i--){

107. if(position - i >= 0){

108. currPos = 3-i;

109. ids[currPos] = thumbIds[position-i];

110. }

111. }

112. ids[++currPos] = thumbIds[position]; //当前Id

113. //currGallerySelection = currPos;

114. //这样右边剩下的位置数就是7-currPos-1

115. for(int i=1; i<=6-currPos;i++){

116. if(position+i < thumbIds.length){

117. ids[currPos+i] = thumbIds[position+i];

118. }

119. }

120.

121. return ids;

122. }

123.}

然后,我们就可以在Activity中通过查询MediaStore的多媒体图片库来查询所有的图片的缩略图,缩略图所在的位置是:

MediaStore.Images.Thumbnails。Activity代码如下:

view plaincopy to clipboardprint?

01.package com.liner.manager;

02.import java.util.ArrayList;

03.import java.util.List;

04.import com.liner.manager.adapter.GridImageAdapter;

05.import android.app.Activity;

06.import android.content.Intent;

07.import android.database.Cursor;

08.import android.graphics.Bitmap;

09.import android.graphics.BitmapFactory;

10.import .Uri;

11.import android.os.Bundle;

12.import android.provider.MediaStore;

13.import android.view.View;

14.import android.widget.Adapter;

15.import android.widget.AdapterView;

16.import android.widget.GridView;

17.import android.widget.Toast;

18.public class MainActivity extends Activity {

19. private GridView photoView;

20. private GridImageAdapter imageAdapter;

21.

22. private Cursor cursor;

23. private int[] thumbIds;

24.

25. @Override

26. public void onCreate(Bundle savedInstanceState) {

27. super.onCreate(savedInstanceState);

28. setContentView(R.layout.main);

29.

30. photoView = (GridView)this.findViewById(R.id.view_photos);

31. photoView.setOnItemClickListener(photoClickListener);

32.

33. //showImages();

34. showThumbnails();

35. }

36.

37.

38. private void showThumbnails(){

39.

40. cursor = BitmapUtils.queryThumbnails(this);

41. if(cursor.moveToFirst()){

42. List<Bitmap> bitmaps = new ArrayList<Bitmap>();

43. thumbIds = new int[cursor.getCount()];

44. for(int i=0; i<cursor.getCount();i++){

45. cursor.moveToPosition(i);

46. String currPath = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));

47. thumbIds[i] = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails._ID));

48. Bitmap b = BitmapUtils.decodeBitmap(currPath,100,100);

49. bitmaps.add(b);

50. }

51. imageAdapter = new GridImageAdapter(this.getApplication(), bitmaps);

52. photoView.setAdapter(imageAdapter);

53. }

54. }

55.

56. private AdapterView.OnItemClickListener photoClickListener = new AdapterView.OnItemClickListener() {

57. @Override

58. public void onItemClick(AdapterView<?> p, View v, int position,

59. long id) {

60. //点击某张缩略图时,转到图片显示界面

61. Intent intent = new Intent();

62. intent.setClass(MainActivity.this, GalleryActivity.class);

63. intent.putExtra("thumbIds", thumbIds);

64. intent.putExtra("currentPos", position);

65. startActivity(intent);

66. }

67. };

68.

69.}

注意到,我们记录了,所有缩略图对应的id号,和当前的用户选择的位置,然后通过Intent传递到第二个展示界面。第二个界面的布局文件如下:我们用了一个Gallery和一个ImageButton来实现

view plaincopy to clipboardprint?

01.<?xml version="1.0" encoding="utf-8"?>

02.<LinearLayout

03. xmlns:android="/apk/res/android"

04. android:layout_width="fill_parent"

05. android:layout_height="fill_parent"

06. android:orientation="vertical">

07. <Gallery

08. android:id="@+id/image_gallery"

09. android:layout_width="fill_parent"

10. android:layout_height="100dp"

11. />

12. <ImageButton

13. android:id="@+id/image_current"

14. android:layout_width="fill_parent"

15. android:layout_height="fill_parent"

16. android:padding="10dp"

17. android:layout_marginTop="10dp"

18. />

19.</LinearLayout>

然后,对应的Activity如下:

view plaincopy to clipboardprint?

01.package com.liner.manager;

02.import java.util.List;

03.import com.liner.manager.adapter.GridImageAdapter;

04.import android.app.Activity;

05.import android.graphics.Bitmap;

06.import android.os.Bundle;

07.import android.view.View;

08.import android.widget.AdapterView;

09.import android.widget.Gallery;

10.import android.widget.ImageButton;

11.import android.widget.AdapterView.OnItemClickListener;

12.public class GalleryActivity extends Activity{

13.

14. private ImageButton currentImage;

15. private Gallery gallery;

16.

17. private int[] thumbIds;

18. private int currentPos;

19.

20. private Bitmap currentBitmap;

21.

22. private List<Bitmap> bitmapCache;

23.

24. public void onCreate(Bundle savedInstanceState){

25. super.onCreate(savedInstanceState);

26. setContentView(R.layout.gallery);

27.

28. currentImage = (ImageButton)this.findViewById(R.id.image_current);

29. gallery = (Gallery)this.findViewById(R.id.image_gallery);

30. gallery.setOnItemClickListener(galleryItemClickListener);

31. init();

32. }

33.

34. private OnItemClickListener galleryItemClickListener = new OnItemClickListener() {

35. @Override

36. public void onItemClick(AdapterView<?> p, View v, int position,

37. long id) {

38. // 点击事件

39. showCurrentImage(position);

40. }

41. };

42.

43. private void init(){

44. thumbIds = this.getIntent().getIntArrayExtra("thumbIds");

45. currentPos = this.getIntent().getIntExtra("currentPos",0);

46. //galleryIds = this.getThumbnailIds(currentPos); //当前的gallery里的图片信息

47. bitmapCache = BitmapUtils.queryThumbnailListByIds(this, thumbIds);

48. GridImageAdapter adapter = new GridImageAdapter(this.getApplication(), bitmapCache);

49. gallery.setAdapter(adapter);

50. gallery.setSelection(currentPos);

51.

52. showCurrentImage(currentPos);

53.

54. }

55.

56. private void showCurrentImage(int position){

57.

58. if(currentBitmap != null){

59. currentBitmap.recycle();

60. }

61.

62. currentBitmap = BitmapUtils.queryImageByThumbnailId(GalleryActivity.this, thumbIds[position]);

63. if(currentBitmap != null){

64. currentImage.setImageBitmap(currentBitmap);

65. }else{

66. //什么都不做

67. }

68.

69. //releaseBitmaps();

70. }

71.

72.}

可以看到,当用户点击Gallery中某一项时,触发onItemClick事件,在其中,我们通过根据该缩略图对应的Image_ID来从MediaStore.Images.Media中查询该缩略图对应的大图。并在ImageButton中显示。

这里当图片很多时,可能会出现内存溢出,为了避免这种情况,可以更加Gallery的特点,使用缓存。保存当前可见的缩略图的前三个到后三个。其余的全部recycle。当用户点击Gallery的时候,在判断当前的位置,如果大于或小于某个值时,则重新更新缓存。这样保证内存中的缩略图的个数总是6+Gallery.getLastVisiblePosition-Gallery.getFirstVisiblePosition个。其实这就是浮动缓存窗口,一个固定大小窗口在整个坐标(全部缩略图)上游动。这里没有实现,以后待续。

同时,你可能已经注意到,程序中使用到了一个BitmapUtils类,这个类是封装了一系列对查询图片,并将其解析为Bitmap的类。

代码如下:

view plaincopy to clipboardprint?

01.package com.liner.manager;

02.import java.util.ArrayList;

03.import java.util.List;

04.import android.app.Activity;

05.import android.database.Cursor;

06.import android.graphics.Bitmap;

07.import android.graphics.BitmapFactory;

08.import android.provider.MediaStore;

09.import android.util.Log;

10.public final class BitmapUtils {

11.

12.

13.

14. public static Bitmap decodeBitmap(String path, int displayWidth, int displayHeight){

15. BitmapFactory.Options op = new BitmapFactory.Options();

16. op.inJustDecodeBounds = true;

17. Bitmap bmp = BitmapFactory.decodeFile(path, op); //获取尺寸信息

18. //获取比例大小

19. int wRatio = (int)Math.ceil(op.outWidth/(float)displayWidth);

20. int hRatio = (int)Math.ceil(op.outHeight/(float)displayHeight);

21. //如果超出指定大小,则缩小相应的比例

22. if(wRatio > 1 && hRatio > 1){

23. if(wRatio > hRatio){

24. op.inSampleSize = wRatio;

25. }else{

26. op.inSampleSize = hRatio;

27. }

28. }

29. op.inJustDecodeBounds = false;

30. bmp = BitmapFactory.decodeFile(path, op);

31. return Bitmap.createScaledBitmap(bmp, displayWidth, displayHeight, true);

32. }

33.

34. /**

35. * 采用复杂计算来决定缩放

36. * @param path

37. * @param maxImageSize

38. * @return

39. */

40. public static Bitmap decodeBitmap(String path, int maxImageSize){

41. BitmapFactory.Options op = new BitmapFactory.Options();

42. op.inJustDecodeBounds = true;

43. Bitmap bmp = BitmapFactory.decodeFile(path, op); //获取尺寸信息

44. int scale = 1;

45. if(op.outWidth > maxImageSize || op.outHeight > maxImageSize){

46. scale = (int)Math.pow(2, (int)Math.round(Math.log(maxImageSize/(double)Math.max(op.outWidth, op.outHeight))/Math.log(0.5)));

47. }

48. op.inJustDecodeBounds = false;

49. op.inSampleSize = scale;

50. bmp = BitmapFactory.decodeFile(path, op);

51. return bmp;

52. }

53.

54.

55. public static Cursor queryThumbnails(Activity context){

56. String[] columns = new String[]{

57. MediaStore.Images.Thumbnails.DATA,

58. MediaStore.Images.Thumbnails._ID,

59. MediaStore.Images.Thumbnails.IMAGE_ID

60. };

61. return context.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.Images.Thumbnails.DEFAULT_SORT_ORDER);

62. }

63.

64. public static Cursor queryThumbnails(Activity context, String selection, String[] selectionArgs){

65. String[] columns = new String[]{

66. MediaStore.Images.Thumbnails.DATA,

67. MediaStore.Images.Thumbnails._ID,

68. MediaStore.Images.Thumbnails.IMAGE_ID

69. };

70. return context.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, columns, selection, selectionArgs, MediaStore.Images.Thumbnails.DEFAULT_SORT_ORDER);

71. }

72.

73. public static Bitmap queryThumbnailById(Activity context, int thumbId){

74. String selection = MediaStore.Images.Thumbnails._ID + " = ?";

75. String[] selectionArgs = new String[]{

76. thumbId+""

77. };

78. Cursor cursor = BitmapUtils.queryThumbnails(context,selection,selectionArgs);

79.

80. if(cursor.moveToFirst()){

81. String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));

82. cursor.close();

83. return BitmapUtils.decodeBitmap(path, 100, 100);

84. }else{

85. cursor.close();

86. return null;

87. }

88. }

89.

90. public static Bitmap[] queryThumbnailsByIds(Activity context, Integer[] thumbIds){

91. Bitmap[] bitmaps = new Bitmap[thumbIds.length];

92. for(int i=0; i<bitmaps.length; i++){

93. bitmaps[i] = BitmapUtils.queryThumbnailById(context, thumbIds[i]);

94. }

95.

96. return bitmaps;

97. }

98.

99. /**

100. * 获取全部

101. * @param context

102. * @return

103. */

104. public static List<Bitmap> queryThumbnailList(Activity context){

105. List<Bitmap> bitmaps = new ArrayList<Bitmap>();

106. Cursor cursor = BitmapUtils.queryThumbnails(context);

107. for(int i=0; i<cursor.getCount(); i++){

108. cursor.moveToPosition(i);

109. String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.DATA));

110. Bitmap b = BitmapUtils.decodeBitmap(path, 100, 100);

111. bitmaps.add(b);

112. }

113. cursor.close();

114. return bitmaps;

115. }

116.

117. public static List<Bitmap> queryThumbnailListByIds(Activity context, int[] thumbIds){

118. List<Bitmap> bitmaps = new ArrayList<Bitmap>();

119. for(int i=0; i<thumbIds.length; i++){

120. Bitmap b = BitmapUtils.queryThumbnailById(context, thumbIds[i]);

121. bitmaps.add(b);

122. }

123.

124. return bitmaps;

125. }

126.

127. public static Cursor queryImages(Activity context){

128. String[] columns = new String[]{

129. MediaStore.Images.Media._ID,

130. MediaStore.Images.Media.DATA,

131. MediaStore.Images.Media.DISPLAY_NAME

132. };

133. return context.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, MediaStore.Images.Media.DEFAULT_SORT_ORDER);

134. }

135.

136. public static Cursor queryImages(Activity context, String selection, String[] selectionArgs){

137. String[] columns = new String[]{

138. MediaStore.Images.Media._ID,

139. MediaStore.Images.Media.DATA,

140. MediaStore.Images.Media.DISPLAY_NAME

141. };

142. return context.managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, selection, selectionArgs, MediaStore.Images.Media.DEFAULT_SORT_ORDER);

143. }

144.

145. public static Bitmap queryImageById(Activity context, int imageId){

146. String selection = MediaStore.Images.Media._ID + "=?";

147. String[] selectionArgs = new String[]{

148. imageId + ""

149. };

150. Cursor cursor = BitmapUtils.queryImages(context, selection, selectionArgs);

151. if(cursor.moveToFirst()){

152. String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));

153. cursor.close();

154. //return BitmapUtils.decodeBitmap(path, 260, 260);

155. return BitmapUtils.decodeBitmap(path, 220); //看看和上面这种方式的差别,看了,差不多

156. }else{

157. cursor.close();

158. return null;

159. }

160. }

161.

162. /**

163. * 根据缩略图的Id获取对应的大图

164. * @param context

165. * @param thumbId

166. * @return

167. */

168. public static Bitmap queryImageByThumbnailId(Activity context, Integer thumbId){

169.

170. String selection = MediaStore.Images.Thumbnails._ID + " = ?";

171. String[] selectionArgs = new String[]{

172. thumbId+""

173. };

174. Cursor cursor = BitmapUtils.queryThumbnails(context, selection, selectionArgs);

175.

176. if(cursor.moveToFirst()){

177. int imageId = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Thumbnails.IMAGE_ID));

178. cursor.close();

179. return BitmapUtils.queryImageById(context, imageId);

180. }else{

181. cursor.close();

182. return null;

183. }

184. }

185.}

本文来自CSDN博客,转载请标明出处:/chenjie19891104/archive//04/20/6336439.aspx

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。