• 當前位置:首頁 > IT技術 > 移動平臺 > 正文

    android列表下載圖片listview緩存
    2021-09-16 11:48:36

    在使用listview下載圖片的時候,經常遇到圖片錯亂問題,快速滑動會導致圖片位置不對,這里提供一種思路

    實現效果圖:

    android列表下載圖片listview緩存_.net

    (1)activity_main.xml

    ?

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    (2)images_item.xml

    ?

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:src="@mipmap/empty_photo"
        android:scaleType="fitXY"/>

    (3)在清單文件AndroidManifest.xml里添加聯網權限

    ?

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

    (4)創建一個圖片類Images,用于放置圖片數組

    ?

    public class Images {
    
        public final static String[] imageUrls = new String[] {
                "https://img-my.csdn.net/uploads/201508/05/1438760758_3497.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760758_6667.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760757_3588.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760756_3304.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760755_6715.jpeg",
                "https://img-my.csdn.net/uploads/201508/05/1438760726_5120.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760726_8364.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760725_4031.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760724_9463.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760724_2371.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760707_4653.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760706_6864.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760706_9279.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760704_2341.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760704_5707.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760685_5091.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760685_4444.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760684_8827.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760683_3691.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760683_7315.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760663_7318.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760662_3454.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760662_5113.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760661_3305.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760661_7416.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760589_2946.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760589_1100.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760588_8297.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760587_2575.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760587_8906.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760550_2875.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760550_9517.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760549_7093.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760549_1352.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760548_2780.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760531_1776.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760531_1380.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760530_4944.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760530_5750.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760529_3289.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760500_7871.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760500_6063.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760499_6304.jpeg",
                "https://img-my.csdn.net/uploads/201508/05/1438760499_5081.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760498_7007.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760478_3128.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760478_6766.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760477_1358.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760477_3540.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760476_1240.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760446_7993.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760446_3641.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760445_3283.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760444_8623.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760444_6822.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760422_2224.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760421_2824.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760420_2660.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760420_7188.jpg",
                "https://img-my.csdn.net/uploads/201508/05/1438760419_4123.jpg",
        };
    }
    

    (5)在MainActivity里面引用適配器,設置顯示的內容

    ?

    public class MainActivity extends AppCompatActivity {
        private ListView listView;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            setContentView(R.layout.activity_main);
            listView = (ListView) findViewById(R.id.list_view);
            ImageAdapter adapter = new ImageAdapter(this, 0, Images.imageUrls);
            listView.setAdapter(adapter);
        }
    }
    

    (6)適配器ImageAdapter

    ?

    public class ImageAdapter extends ArrayAdapter<String> {
    
        private ListView mListView;
    
        private Bitmap mLoadingBitmap;
    
        /**
         * 圖片緩存技術的核心類,用于緩存所有下載好的圖片,在程序內存達到設定值時會將最少最近使用的圖片移除掉。
         */
        private LruCache<String, BitmapDrawable> mMemoryCache;
    
        public ImageAdapter(Context context, int resource, String[] objects) {
            super(context, resource, objects);
            mLoadingBitmap = BitmapFactory.decodeResource(context.getResources(),
                    R.mipmap.empty_photo);
            // 獲取應用程序最大可用內存
            int maxMemory = (int) Runtime.getRuntime().maxMemory();
            int cacheSize = maxMemory / 8;
            mMemoryCache = new LruCache<String, BitmapDrawable>(cacheSize) {
                @Override
                protected int sizeOf(String key, BitmapDrawable drawable) {
                    return drawable.getBitmap().getByteCount();
                }
            };
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (mListView == null) {
                mListView = (ListView) parent;
            }
            String url = getItem(position);
            View view;
            if (convertView == null) {
                view = LayoutInflater.from(getContext()).inflate(R.layout.images_item, null);
            } else {
                view = convertView;
            }
            ImageView image = (ImageView) view.findViewById(R.id.image);
            BitmapDrawable drawable = getBitmapFromMemoryCache(url);
            if (drawable != null) {
                image.setImageDrawable(drawable);
            } else if (cancelPotentialWork(url, image)) {
                BitmapWorkerTask task = new BitmapWorkerTask(image);
                AsyncDrawable asyncDrawable = new AsyncDrawable(getContext()
                        .getResources(), mLoadingBitmap, task);
                image.setImageDrawable(asyncDrawable);
                task.execute(url);
            }
            return view;
        }
    
        /**
         * 自定義的一個Drawable,讓這個Drawable持有BitmapWorkerTask的弱引用。
         */
        class AsyncDrawable extends BitmapDrawable {
    
            private WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;
    
            public AsyncDrawable(Resources res, Bitmap bitmap,
                                 BitmapWorkerTask bitmapWorkerTask) {
                super(res, bitmap);
                bitmapWorkerTaskReference = new WeakReference<>(
                        bitmapWorkerTask);
            }
    
            public BitmapWorkerTask getBitmapWorkerTask() {
                return bitmapWorkerTaskReference.get();
            }
    
        }
    
        /**
         * 獲取傳入的ImageView它所對應的BitmapWorkerTask。
         */
        private BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
            if (imageView != null) {
                Drawable drawable = imageView.getDrawable();
                if (drawable instanceof AsyncDrawable) {
                    AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
                    return asyncDrawable.getBitmapWorkerTask();
                }
            }
            return null;
        }
    
        /**
         * 取消掉后臺的潛在任務,當認為當前ImageView存在著一個另外圖片請求任務時
         * ,則把它取消掉并返回true,否則返回false。
         */
        public boolean cancelPotentialWork(String url, ImageView imageView) {
            BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
            if (bitmapWorkerTask != null) {
                String imageUrl = bitmapWorkerTask.imageUrl;
                if (imageUrl == null || !imageUrl.equals(url)) {
                    bitmapWorkerTask.cancel(true);
                } else {
                    return false;
                }
            }
            return true;
        }
    
        /**
         * 將一張圖片存儲到LruCache中。
         *
         * @param key
         *            LruCache的鍵,這里傳入圖片的URL地址。
         * @param drawable
         *            LruCache的值,這里傳入從網絡上下載的BitmapDrawable對象。
         */
        public void addBitmapToMemoryCache(String key, BitmapDrawable drawable) {
            if (getBitmapFromMemoryCache(key) == null) {
                mMemoryCache.put(key, drawable);
            }
        }
    
        /**
         * 從LruCache中獲取一張圖片,如果不存在就返回null。
         *
         * @param key
         *            LruCache的鍵,這里傳入圖片的URL地址。
         * @return 對應傳入鍵的BitmapDrawable對象,或者null。
         */
        public BitmapDrawable getBitmapFromMemoryCache(String key) {
            return mMemoryCache.get(key);
        }
    
        /**
         * 異步下載圖片的任務。
         *
         * @author guolin
         */
        class BitmapWorkerTask extends AsyncTask<String, Void, BitmapDrawable> {
    
            String imageUrl;
    
            private WeakReference<ImageView> imageViewReference;
    
            public BitmapWorkerTask(ImageView imageView) {
                imageViewReference = new WeakReference<>(imageView);
            }
    
            @Override
            protected BitmapDrawable doInBackground(String... params) {
                imageUrl = params[0];
                // 在后臺開始下載圖片
                Bitmap bitmap = downloadBitmap(imageUrl);
                BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), bitmap);
                addBitmapToMemoryCache(imageUrl, drawable);
                return drawable;
            }
    
            @Override
            protected void onPostExecute(BitmapDrawable drawable) {
                ImageView imageView = getAttachedImageView();
                if (imageView != null && drawable != null) {
                    imageView.setImageDrawable(drawable);
                }
            }
    
            /**
             * 獲取當前BitmapWorkerTask所關聯的ImageView。
             */
            private ImageView getAttachedImageView() {
                ImageView imageView = imageViewReference.get();
                BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);
                if (this == bitmapWorkerTask) {
                    return imageView;
                }
                return null;
            }
    
            /**
             * 建立HTTP請求,并獲取Bitmap對象。
             *
             * @param imageUrl
             *            圖片的URL地址
             * @return 解析后的Bitmap對象
             */
            private Bitmap downloadBitmap(String imageUrl) {
                Bitmap bitmap = null;
                HttpURLConnection con = null;
                try {
                    URL url = new URL(imageUrl);
                    con = (HttpURLConnection) url.openConnection();
                    con.setConnectTimeout(5 * 1000);
                    con.setReadTimeout(10 * 1000);
                    bitmap = BitmapFactory.decodeStream(con.getInputStream());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (con != null) {
                        con.disconnect();
                    }
                }
                return bitmap;
            }
    
        }
    
    }
    

    ?


    本文摘自 :https://blog.51cto.com/u

    開通會員,享受整站包年服務
    国产呦精品一区二区三区网站|久久www免费人咸|精品无码人妻一区二区|久99久热只有精品国产15|中文字幕亚洲无线码