圖片瀏覽器效果圖 :
源碼下載地址 :
-- CSDN : http://download.csdn.net/detail/han1202012/6875083
-- GitHub : https://github.com/han1202012/AndroidPictureViewer.git
一. 圖片瀏覽器顯示界面ImageView介紹
1. ImageView的上下繼承結構
下面是API中的結構:
java.lang.Object | ||
↳ | android.view.View | |
android.widget.ImageView |
![]() |
![]() |
繪制成UML圖 :
通過上面的分析 : ImageView有兩個子類 ImageButton 和 QuickContactBadge, ImageButton還有一個子類是 ZoomButton;
2. XML文件屬性
調整邊界, 保持長寬比 :android:adjustViewBounds, setAdjustViewBounds(boolean), 是否調整自己的邊界, 用來保持圖片的長寬比例, 該屬性與 android:maxHeight 和 android:maxWidth 屬性一起使用才有效果, 單獨使用沒有效果;
設置最大寬度, 高度 :android:maxWidth(android:maxHeight), setMaxWidth(int)[setMaxHeight(int)], 該屬性需要與android:adjustViewBounds屬性一起使用,單獨使用無效果;
-- 設置圖片固定大小, 同時保持長寬比 : a. 設置android:adjustViewBounds 為 true; b. 設置最大寬度, 高度; c. 設置android:layout_width 與 android:layout_height 值為 warp_content;
裁剪保留空白 :android:cropToPadding, setCropToPadding(boolean), 是否裁剪, 用來保留ImageView的padding, 該屬性與android:scrollY 屬性一起使用的時候才有用, 單獨使用沒有效果; 即 在滾動的時候, 滾動到邊界, 邊界的padding空白是否顯示;
填充方式 :android:scaleType, setScaleType(ImageView.ScaleType), 設置圖片縮放類型以適配ImageView大小, 即填充方式;
可能的取值 : matrix, fitXY, fitStart, fitCenter, fitEnd, center, centerCrop, centerInside;
-- matrix : 方法中的常量值為 ImageView.ScaleType.MATRIX, 使用矩陣來進行繪圖;
-- fitXY : 方法中的常量值為 ImageView.ScaleType.FIT_XY, 在x y 兩個方向上縮放, 使圖片完全填充整個ImageView 不按照長寬比例縮放;
-- fitStart : 方法中的常量值為 ImageView.ScaleType.FIT_START, 保持長寬比縮放, 直到該圖片完全顯示在ImageView中, 縮放完成之后該圖片在左上角;
-- fitCenter : 方法中的常量值為 ImageView.ScaleType.FIT_CENTER, 保持長寬比縮放, 直到該圖片完全顯示在ImageView中, 縮放完成之后該圖片位於中央;
-- fitEnd : 方法中的常量值為 ImageView.ScaleType.FIT_END, 保持長寬比縮放, 直到該圖片完全顯示在ImageView中, 縮放完成之后該圖片位於右下角;
-- center : 方法中的常量值為 ImageView.ScaleType.CENTER, 將圖片放在ImageView的中央, 不進行縮放;
-- centerCrop : 方法中的常量值為 ImageView.ScaleType.CENTER_CROP, 保持長寬比縮放, 使圖片完全覆蓋ImageView;
-- centerInside : 方法中的常量值為 ImageView.ScaleType.CENTER_INSIDE, 保持長寬比縮放, 是的ImageView完全顯示圖片;
實例 :
XML文件 :
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
- <ImageView
- android:id="@+id/im"
- android:background="#00FF00"
- android:layout_height="300dp"
- android:layout_width="300dp"
- android:src="@drawable/pic"
- <strong>android:scaleType</strong>="matrix"/>
- </LinearLayout>
修改其中的 android:scaleType屬性值, 查看其中的差異 :
原圖 :
android:scaleType 默認情況下 :
android:scaleType = "matrix" : 由下圖可以看出, ImageView中的圖片寬度與原圖一樣, 該屬性不進行任何縮放,直接將圖片放在左上角;
android:scaleType = "fixXY" : 長寬不按比例拉伸, 圖片明顯變形 :
android:scaleType = "fitStart" , 圖片按比例縮放, 寬先達到邊界, 圖片位於上邊; 如果高先達到邊界, 圖片位於左邊;
android:scaleType = "fieCenter" ,長寬按照比例縮放, 寬度先達到邊界, 上下有空白; 如果高度先達到邊界, 那么左右有空白;
android:scaleType = "fitEnd" , 長寬等比例縮放, 寬度先達到邊界, 位於下邊; 如果高度先達到邊界, 位於右邊;
android:scaleType = "center" ,長寬不進行縮放, 圖片的中心 與 ImageView 的中心重合;
android:scaleType = "centerCrop" ,長寬等比例縮放, 使圖片完全覆蓋ImageView, 圖片中心與ImageView中心重合, 使圖片最短的邊能覆蓋ImageView邊界;
android:scaleType = "centerInside" ,長寬等比例縮放, 如果圖片寬高小於等於ImageView寬高, 那么就按照原圖大小顯示; 如果圖片大於ImageView, 那么按照等比例縮小直到能完全顯示為止;
3. ImageView常用方法
設置圖片 :
-- 設置位圖 : setImageBitmap(bitmap), 為ImageView設置Bitmap位圖顯示;
-- 設置Drawable : setImageDrawable(drawable), 為ImageView設置Drawable顯示;
-- 設置資源 : setImageResource(int), 為ImageView設置資源圖片;
-- 設置路徑 : setImageUri(uri), 為ImageView設置圖片路徑, 顯示該路徑的圖片;
二. 圖片瀏覽器操作介紹
1. 實現左右循環切換圖片
圖片數組 : 將圖片放在數組中, ImageView顯示數組中的圖片;
當前顯示圖片下標索引 : 設置一個int值, 用來表示當前顯示圖片數組中的圖片, 這個值不是int下標, 這個值設置很大設置成Integer.MAXVALUE / 2, 該值與圖片數組的長度進行取模運算結果就是當前顯示的圖片數組下標值;
翻頁操作 : 上一頁操作就將當前顯示索引自減1, 然后模上 圖片數組大小; 下一頁就將當前索引自增1, 然后模上 圖片數組大小;
代碼示例 :
- //設置一個很大的值, 保證前后翻頁不會出現異常
- currentImage = Integer.MAX_VALUE / 2;
- //為了保證圖片能夠循環, 這里模運算是關鍵, 顯示圖片的下標始終是長度的模
- image_all.setImageResource(images[ ++currentImage % images.length ]);
- image_all.setImageResource(images[ --currentImage % images.length ]);
2. 透明度改變
設置當前透明度 : 設置一個當前透明度值, 初始值為255, 255是不透明, 0為完全透明;
透明度改變 : 當點擊透明度增加按鈕的時候, 透明度自增20, 如果結果透明度大於255, 那么改透明度強制設置為255; 當點擊透明度見效按鈕的時候, 透明度自減20, 當透明度小於0的時候, 透明度強制設置為0;
代碼示例 :
- //透明度初始值
- alpha = 255;
- //透明度增加
- alpha += 20;
- if(alpha >= 255)
- alpha = 255;
- image_all.setAlpha(alpha);
- //透明度減小
- alpha -= 20;
- if(alpha <= 0)
- alpha = 0;
- image_all.setAlpha(alpha);
3. 圖片的放大縮小
獲取View組件寬高 : 在Activity普通方法中無法獲取到view組件的准確值, 如果想要獲取view組件的寬高, 可以在 onWindowFocusChanged()方法中獲取;
計算每次自增自減的單位值 : 當按下縮放按鈕的時候, 就對ImageView的寬高值進行自增自減單位值操作;
為ImageView設置寬高 : 即設置LayoutParams, 注意是LinearLayout.LayoutParams對象;
代碼示例 :
獲取寬高 :
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- // TODO Auto-generated method stub
- super.onWindowFocusChanged(hasFocus);
- //獲取ImageView組件的寬高
- imageWidth = image_all.getWidth();
- imageHeight = image_all.getHeight();
- //計算每次自增自減的值
- addWidth = imageWidth / 5;
- addHeight = imageHeight / 5;
- }
縮放圖片操作 :
- case R.id.big: //放大圖片
- imageWidth += addWidth;
- imageHeight += addHeight;
- image_all.setLayoutParams(new LinearLayout.LayoutParams(imageWidth, imageHeight));
- break;
- case R.id.small: //縮小圖片
- imageWidth -= addWidth;
- imageHeight -= addHeight;
- if(imageWidth <= 0 || imageHeight <=0){
- imageWidth += addWidth;
- imageHeight += addHeight;
- }
- image_all.setLayoutParams(new LinearLayout.LayoutParams(imageWidth, imageHeight));
- break;
4. 旋轉圖片操作
設置Matrix對象 : 該對象用來存放圖像的旋轉角度;
設置旋轉角度 : matrix.setRotate(), 即可設置旋轉角度;
創建Bitmap : 創建一個位圖, 注意將設置了旋轉角度的 matrix 設置上去;
源碼示例 :
- matrix = new Matrix();
- //向左旋轉進行的操作
- anglel += 45;
- matrix.setRotate(anglel);
- Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(images[currentImage % images.length])).getBitmap();
- bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);
- image_all.setImageBitmap(bitmap);
- //向右旋轉進行的操作
- anglel -= 45;
- matrix.setRotate(anglel);
- Bitmap bitmap1 = ((BitmapDrawable) getResources().getDrawable(images[currentImage % images.length])).getBitmap();
- bitmap1 = Bitmap.createBitmap(bitmap1, 0, 0, bitmap1.getWidth(),bitmap1.getHeight(), matrix, true);
- image_all.setImageBitmap(bitmap1);
三. 圖片瀏覽器源碼
XML布局文件 :
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/bg_im"
- android:orientation="vertical">
- <LinearLayout
- android:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:padding="5dp"
- android:gravity="center">
- <Button
- android:id="@+id/alpha_plus"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="透明度+"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/alpha_minus"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="透明度-"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/prev_page"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="上一張"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/next_page"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="下一張"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- </LinearLayout>
- <LinearLayout
- android:orientation="horizontal"
- android:layout_height="wrap_content"
- android:layout_width="fill_parent"
- android:padding="5dp"
- android:gravity="center">
- <Button
- android:id="@+id/big"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="放大"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/small"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="縮小"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/turn_left"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="左轉"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- <Button
- android:id="@+id/turn_right"
- android:layout_height="fill_parent"
- android:layout_width="fill_parent"
- android:layout_weight="1"
- android:text="右轉"
- android:background="@drawable/bg_bt"
- android:onClick="onClick"/>
- </LinearLayout>
- <ImageView
- android:id="@+id/image_all"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:scaleType="fitCenter"
- android:src="@drawable/mary1"/>
- </LinearLayout>
Drawable資源 :
整個界面的背景 : 漸變的顏色
- <?xml version="1.0" encoding="utf-8"?>
- <shape xmlns:android="http://schemas.android.com/apk/res/android" >
- <gradient
- android:startColor="#A9F5A9"
- android:centerColor="#2EFE2E"
- android:endColor="#A9F5A9"
- android:type="linear"/>
- </shape>
按鈕的背景 : 兩個9patch圖片, 按下的時候按鈕背景會改變
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:state_pressed="true"
- android:drawable="@drawable/bt_focus"></item>
- <item android:state_pressed="false"
- android:drawable="@drawable/bt_normal"></item>
- </selector>
主Activity核心代碼 :
- package shuliang.han.imageview_test;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.Matrix;
- import android.graphics.drawable.BitmapDrawable;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- public class MainActivity extends Activity {
- private int[] images; //圖片資源id數組
- private int currentImage; //當前顯示圖片
- private int alpha; //透明度
- private Matrix matrix;
- private int anglel; //角度
- private int imageWidth;
- private int imageHeight;
- private int addWidth;
- private int addHeight;
- private ImageView image_all;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- init();
- }
- //初始化成員變量
- private void init() {
- images = new int[]{R.drawable.mary1, R.drawable.mary2};
- currentImage = Integer.MAX_VALUE / 2;
- alpha = 255;
- matrix = new Matrix();
- image_all = (ImageView) findViewById(R.id.image_all);
- image_all.setImageResource(images[currentImage % images.length]);
- }
- public void onClick(View view) {
- int id = view.getId();
- switch (id) {
- case R.id.alpha_plus: //增大透明度
- alpha += 20;
- if(alpha >= 255)
- alpha = 255;
- image_all.setAlpha(alpha);
- break;
- case R.id.alpha_minus: //減小透明度
- alpha -= 20;
- if(alpha <= 0)
- alpha = 0;
- image_all.setAlpha(alpha);
- break;
- case R.id.next_page: //顯示下一張圖片
- //為了保證圖片能夠循環, 這里模運算是關鍵, 顯示圖片的下標始終是長度的模
- image_all.setImageResource(images[ ++currentImage % images.length ]);
- break;
- case R.id.prev_page: //顯示上一張圖片
- image_all.setImageResource(images[ --currentImage % images.length ]);
- break;
- case R.id.big: //放大圖片
- imageWidth += addWidth;
- imageHeight += addHeight;
- image_all.setLayoutParams(new LinearLayout.LayoutParams(imageWidth, imageHeight));
- break;
- case R.id.small: //縮小圖片
- imageWidth -= addWidth;
- imageHeight -= addHeight;
- if(imageWidth <= 0 || imageHeight <=0){
- imageWidth += addWidth;
- imageHeight += addHeight;
- }
- image_all.setLayoutParams(new LinearLayout.LayoutParams(imageWidth, imageHeight));
- break;
- case R.id.turn_left: //向左旋轉
- anglel += 45;
- matrix.setRotate(anglel);
- Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(images[currentImage % images.length])).getBitmap();
- bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),bitmap.getHeight(), matrix, true);
- image_all.setImageBitmap(bitmap);
- break;
- case R.id.turn_right: //向右旋轉
- anglel -= 45;
- matrix.setRotate(anglel);
- Bitmap bitmap1 = ((BitmapDrawable) getResources().getDrawable(images[currentImage % images.length])).getBitmap();
- bitmap1 = Bitmap.createBitmap(bitmap1, 0, 0, bitmap1.getWidth(),bitmap1.getHeight(), matrix, true);
- image_all.setImageBitmap(bitmap1);
- break;
- default:
- break;
- }
- }
- @Override
- public void onWindowFocusChanged(boolean hasFocus) {
- // TODO Auto-generated method stub
- super.onWindowFocusChanged(hasFocus);
- //獲取ImageView組件的寬高
- imageWidth = image_all.getWidth();
- imageHeight = image_all.getHeight();
- //計算每次自增自減的值
- addWidth = imageWidth / 5;
- addHeight = imageHeight / 5;
- }
- }
四. ZoomButton 和 QuickContactBadge
示例效果圖 :
下載地址 :
GitHub : https://github.com/han1202012/ZoomButton_QuickContactBadge.git
1. ZoomButton
ZoomButton按鈕 : ZoomButton按鈕提供放大 縮小兩個按鈕, 兩個按鈕;
ZoomControls按鈕 : 該按鈕會自動生成一組兩個按鈕, 兩個按鈕分別是放大和縮小;
按鈕點擊切換背景 : 設置selector資源, 設置兩個item, 一個item的狀態為按下時, 顯示一個圖片, 另一個item的狀態為普通情況下, 顯示另一個圖片;
selector源碼 :
- <?xml version="1.0" encoding="utf-8"?>
- <selector xmlns:android="http://schemas.android.com/apk/res/android" >
- <item android:state_pressed="true"
- android:drawable="@drawable/app3"></item>
- <item android:state_pressed="false"
- android:drawable="@drawable/app4"></item>
- </selector>
XML源碼 :
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/app2"/>
- <ImageButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/bt_bg"/>
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:padding="10dp"
- android:layout_gravity="center_horizontal">
- <ZoomButton
- android:id="@+id/zoom_1"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:src="@android:drawable/btn_minus"/>
- <ZoomButton
- android:id="@+id/zoom_2"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:src="@android:drawable/btn_plus"/>
- </LinearLayout>
- <ZoomControls
- android:id="@+id/zoom_ctrl"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal"/>
- </LinearLayout>
2. QuickContactBadge
本質 : QuickContactBadge 也是圖片, 可以通過android:src 指定圖片;
功能 : QuickContactBadge 可以關聯手機通訊錄中的聯系人, 當點擊圖片的時候, 會彈出該聯系人相關的界面;
-- 關聯方法 :
--- 使用郵箱關聯 : assignContactFromEmail(String address, boolean lazyLookup), 將圖片關聯到指定email聯系人;
--- 使用號碼關聯 : assignContactFromPhone(String number, boolean lazyLookup), 將圖片關聯到指定電話聯系人;
--- 使用Uri關聯 : assignContactUri(Uri uri), 將圖片關聯到Uri對應的聯系人;
XML代碼 :
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <QuickContactBadge
- android:id="@+id/badge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:src="@drawable/app5"/>
- </LinearLayout>
Activity代碼 :
- package shuliang.han.zoombutton_quickcontactbadge;
- import android.app.Activity;
- import android.os.Bundle;
- import android.widget.QuickContactBadge;
- import shuliang.han.zoombutton_quickcontactbadge.R;
- public class QuickContactBadgeActivity extends Activity {
- private QuickContactBadge badge;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.quick_contact_badge);
- badge = (QuickContactBadge) findViewById(R.id.badge);
- badge.assignContactFromPhone("120", false);
- }
- }