編輯:關於Android編程
本篇文章的主要內容是說圖片的內存緩存和從網絡異步獲取圖片的過程
工程效果圖如下:
vcq9o6zU2rG+tdjDu9PQu7q05qOs0rLDu9PQttTNvMasvfjQ0NG5y/W7r6OouvPG2tTZ1/bV4tCpstnX96OpoaM8L3A+DQo8cD7K18/Iv7S0+sLro6xNYWluQWN0aXZpdHm1xLK8vtbOxLz+IGFjdGl2aXR5X21haW4ueG1sIMjnz8I8L3A+DQo8cHJlIGNsYXNzPQ=="brush:java;">
代碼中部分不常見的屬性解釋如下(百度也可以找到的)
android:numColumns="auto_fit" 意思是圖片牆分成幾列 :auto_fit自適應 android:stretchMode="columnWidth" 圖片牆右邊多出來或者少的區域適配方式:在列寬上進行加減來適配
同時給GridView適配的adapter的View的布局文件 view_photo.xml如下
布局文件很簡單,接下來就是解決圖片源的問題,我這裡使用的是本地的tomcat服務器,將圖片保存在本地的tomcat服務器上,自己定義好鏈接來進行訪問:
tomcat上的文件如圖:
圖片的鏈接類如下:
package com.jishihuitong.photowalldemo; /** * Created by hss on 2016/7/27. */ public class Images { public static final String[] IMAGE = new String[]{ "http://10.0.2.2:8080/images/01.png", "http://10.0.2.2:8080/images/02.png", "http://10.0.2.2:8080/images/03.png", "http://10.0.2.2:8080/images/04.png", "http://10.0.2.2:8080/images/05.png", "http://10.0.2.2:8080/images/06.png", "http://10.0.2.2:8080/images/07.png", "http://10.0.2.2:8080/images/08.png", "http://10.0.2.2:8080/images/09.png", "http://10.0.2.2:8080/images/10.png", "http://10.0.2.2:8080/images/11.png", "http://10.0.2.2:8080/images/12.png", "http://10.0.2.2:8080/images/13.png", "http://10.0.2.2:8080/images/14.png", "http://10.0.2.2:8080/images/15.png", "http://10.0.2.2:8080/images/16.png", "http://10.0.2.2:8080/images/17.png", "http://10.0.2.2:8080/images/18.png", "http://10.0.2.2:8080/images/19.png", "http://10.0.2.2:8080/images/20.png", "http://10.0.2.2:8080/images/21.png", "http://10.0.2.2:8080/images/22.png", "http://10.0.2.2:8080/images/23.png", "http://10.0.2.2:8080/images/24.png", "http://10.0.2.2:8080/images/25.png", "http://10.0.2.2:8080/images/26.png", "http://10.0.2.2:8080/images/27.png", "http://10.0.2.2:8080/images/28.png", "http://10.0.2.2:8080/images/29.png", "http://10.0.2.2:8080/images/30.png", "http://10.0.2.2:8080/images/31.png", "http://10.0.2.2:8080/images/32.png", "http://10.0.2.2:8080/images/33.png", "http://10.0.2.2:8080/images/34.png", "http://10.0.2.2:8080/images/35.png", "http://10.0.2.2:8080/images/36.png", "http://10.0.2.2:8080/images/37.png", "http://10.0.2.2:8080/images/38.png", "http://10.0.2.2:8080/images/39.png", "http://10.0.2.2:8080/images/40.png", "http://10.0.2.2:8080/images/41.png", "http://10.0.2.2:8080/images/42.png", "http://10.0.2.2:8080/images/43.png", "http://10.0.2.2:8080/images/44.png", "http://10.0.2.2:8080/images/45.png", "http://10.0.2.2:8080/images/46.png", "http://10.0.2.2:8080/images/47.png", "http://10.0.2.2:8080/images/48.png", "http://10.0.2.2:8080/images/49.png", "http://10.0.2.2:8080/images/50.png", "http://10.0.2.2:8080/images/51.png", "http://10.0.2.2:8080/images/52.png", "http://10.0.2.2:8080/images/53.png", "http://10.0.2.2:8080/images/54.png", "http://10.0.2.2:8080/images/55.png", "http://10.0.2.2:8080/images/56.png", "http://10.0.2.2:8080/images/67.png", "http://10.0.2.2:8080/images/58.png", "http://10.0.2.2:8080/images/59.png", "http://10.0.2.2:8080/images/60.png", "http://10.0.2.2:8080/images/61.png", "http://10.0.2.2:8080/images/62.png", "http://10.0.2.2:8080/images/63.png", "http://10.0.2.2:8080/images/64.png", "http://10.0.2.2:8080/images/65.png", "http://10.0.2.2:8080/images/66.png", "http://10.0.2.2:8080/images/67.png", "http://10.0.2.2:8080/images/68.png", "http://10.0.2.2:8080/images/69.png", "http://10.0.2.2:8080/images/70.png", "http://10.0.2.2:8080/images/71.png", "http://10.0.2.2:8080/images/72.png", "http://10.0.2.2:8080/images/73.png", "http://10.0.2.2:8080/images/74.png", "http://10.0.2.2:8080/images/75.png", "http://10.0.2.2:8080/images/76.png", "http://10.0.2.2:8080/images/77.png", "http://10.0.2.2:8080/images/78.png" }; }
再來看MainActivity裡面的代碼:
package com.jishihuitong.photowalldemo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.GridView; public class MainActivity extends AppCompatActivity { /** * 圖片牆GridView的適配器Adapter */ private PhotoWallAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GridView photowall = (GridView) findViewById(R.id.gv_photowall); adapter = new PhotoWallAdapter(getApplicationContext(),0, Images.IMAGE,photowall); photowall.setAdapter(adapter); } @Override protected void onDestroy() { super.onDestroy(); //activity退出的時候取消所有正在下載的圖片任務 adapter.cancelAllTasks(); } }
主要的思路是photoWallAdapter繼承ArrayAdapter重寫裡面的getView方法,將View加載進去,
1、在構造方法中把GridView對象傳進來,便於引用
2、首先在Adapter的構造方法裡面實例化Lrucache對象,
3、實例化任務集合,實例化任務BitmapWorkerTask參數是String類型的,返回值是Bitmap類型的
4、給GridView設置滾動監聽,當第一次進入app的時候,把屏幕上出現的所有的圖片都加載出來,當不是第一次進入的時候,判斷是滾動狀態還是停止狀態,只有在停止狀態的時候才去加載圖片,滾動狀態下取消所有的下載圖片任務
5、下載完圖片之後給保存到內存中
具體過程見代碼:
MainActivity裡面沒有多少代碼,最主要的 看這個PhotoWallAdapter
package com.jishihuitong.photowalldemo; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.LruCache; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ArrayAdapter; import android.widget.GridView; import android.widget.ImageView; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashSet; /** * Created by hss on 2016/7/27. */ public class PhotoWallAdapter extends ArrayAdapter{ /** * GridView實例 */ private GridView mGridView; /** * 圖片內存緩存類 */ private LruCache mLruCache; /** * 任務管理集合 */ private HashSet mTaskCollection; private View view; /** * 第一個可以看見的條目下標 */ private int mFirstVisibleItem; /** * 可以看見的條目總數 */ private int mVisibleItemCount; /** * 是否是第一次進入 */ private boolean isFirstEnter = true; /** * 全局tag標記 */ private static final String TAG = "PhotoWallAdapter"; public PhotoWallAdapter(Context context, int resource, String[] objects, GridView gridView) { super(context, resource, objects); this.mGridView = gridView; //獲取到當前系統的最大內存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); //我們使用最大內存的1/8作為本應用緩存圖片的空間大小 int cacheMemory = maxMemory / 8; //創建內存緩存對象,參數為定義好的緩存大小, mLruCache = new LruCache (cacheMemory) { //重寫sizeOf()方法,默認返回圖片的數量 @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; //實例化任務集合 mTaskCollection = new HashSet (); //給gridView設置滾動監聽 mGridView.setOnScrollListener(new AbsListView.OnScrollListener() { //開始滾動的時候,取消下載任務, @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { //成員變量隨著滾動而變化 mFirstVisibleItem = firstVisibleItem; mVisibleItemCount = visibleItemCount; //如果第一次進來的時候,滑動狀態下可以加載圖片, if(isFirstEnter && visibleItemCount>0){ //加載可見范圍內全部的圖片 loadBitmaps(firstVisibleItem,visibleItemCount); isFirstEnter = false; } } //處於不滾動狀態的時候,再開始任務 @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if(scrollState== AbsListView.OnScrollListener.SCROLL_STATE_IDLE){ LogUtil.d(TAG,"mFirstVisibleItem = "+mFirstVisibleItem+" mVisibleItemCount = "+mVisibleItemCount); loadBitmaps(mFirstVisibleItem, mVisibleItemCount); }else{ //取消所有的下載圖片的任務 cancelAllTasks(); } } }); } /** * 取消所有下載圖片的任務 */ public void cancelAllTasks() { if(mTaskCollection!=null){ for (BitmapWorkerTask task: mTaskCollection) { task.cancel(false); } } } /** * 定義任務,執行任務,選擇方法從本地和網絡上加載圖片 * @param firstVisibleItem gridView中可以看見的第一個角標 * @param visibleItemCount gridView中可以看見的所有圖片的總數 */ private void loadBitmaps(int firstVisibleItem, int visibleItemCount) { try{ for (int i = firstVisibleItem; i { private String imageUrl; //需要在後台進程中干的事情 @Override protected Bitmap doInBackground(String... params) { //從參數中獲取到傳進來的圖片URL imageUrl = params[0]; //從網絡上下載圖片 Bitmap bitmap = downLoadBitmap(params[0]); //如果下載到的圖片不為空,把圖片保存進內存中 if(bitmap!=null){ addBitmapToCacheMemory(params[0],bitmap); } return bitmap; } //該方法在上面的方法,DoInBackground之後運行,方法裡面的參數就是上面的方法的返回值 @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); ImageView photo = (ImageView) mGridView.findViewWithTag(imageUrl); if(bitmap!=null&&photo!=null){ photo.setImageBitmap(bitmap); } //完了記得把任務清除掉 mTaskCollection.remove(this); } /** * 從網絡上下載圖片,在後台進程中運行 * @param imageUrl * @return */ private Bitmap downLoadBitmap(String imageUrl) { Bitmap bitmap = null; HttpURLConnection conn = null; try{ URL url = new URL(imageUrl); conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5*1000); conn.setReadTimeout(10 * 1000); conn.setDoInput(true); conn.setDoOutput(true); bitmap = BitmapFactory.decodeStream(conn.getInputStream()); }catch(Exception e){ e.printStackTrace(); }finally { if(conn!=null){ conn.disconnect(); } } return bitmap; } } }
運行的時候別忘了在清單文件中添加連接網絡的權限
下載源碼
在iis7中默認的MIME類型並不包含所有的後綴名文件,像現在比較熱門的apk,ipa文件都是需要手動添加的。那如何在IIS添加MIME類型?步驟如下:1、打開iis7,
問題:橫豎屏切換時Activity的生命周期?測試環境:華為mate7 package com.virglass.beyond.activity;import
小米電視2s定價在2999很大程度上是小米電視2s功能的刪減,其中大家最為關注的是砍掉了3D功能,3d功能可能不是每個人都需要,但是有總比沒有要好嗎?你說對
1.Introduction1.1.gradle構建系統的目標1)讓重用代碼和資源變得更加容易2)讓創建同一應用程序的不同版本變得更加容易,無論是多個apk發布版本還是同