溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ListView結合軟引用和懶加載

發布時間:2020-06-18 14:53:07 來源:網絡 閱讀:1145 作者:dongdong200514 欄目:開發技術

第一篇blog。。。希望能記住自己是怎么理解程序。。。

應該說這樣的代碼網上并不少,像我現在的代碼其實也是跟著別人的代碼寫的。

文章寫的是關于通過ListView顯示異步加載的網上圖片,并且實現緩存機制,圖片在內存足夠且已經存在緩存的情況下,直接從緩存把圖片取出來,而不用多次從網上搜索圖片。

文章涉及的知識點:

SoftReference(軟引用):JDK設置的關于對象引用的一種級別。在軟引用的情況下,只要內存足夠,垃圾回收器就不會對它進行回收,內存不足時,才會對它回收。只要沒有被回收,我們的程序就可以一直使用它。軟引用主要用于高速緩存。

AsyncTask:為了訪問UI線程的工具類,適用于簡單的異步處理。使用時需要注意Task必須在UI線程中創建,execute方法必須在UI線程中調用,不要手動調用它的4個方法,task只能被執行一次。

4個方法(根據自己的需要選擇1~4個方法的重寫):
onPreExecute();在實際后臺操作前被UI線程調用,可以顯示一個進度條

doInparams...);在上面操作后立即執行,主要負責耗時的后臺計算< /span>

onProgressUpdate(values...);顯示上面操作的進展情況,通常在進度條上顯示進度

onPostExecute(result...);doInBackground執行后被UI線程調用,后臺計算結果通過這一函數傳給UI線程


需要加載的包:jericho-html-3.1 這個包應該是用來解析html語言用的


這個程序完成的功能:從豆瓣的新書主頁把新書在listview上顯示,不過程序代碼要想同樣獲得不同網頁的list進行顯示,估計需要適當的修改,具體待會兒寫一下,所以程序本身只是提供一個思路,如何解耦估計到時可以在這個程序基礎上修改。。。因為跟著程序寫得同時也在思考程序是怎么的流程,理解并記下來免得忘了。


程序:

豆瓣的網址:http://book.douban.com/lates

查看網址的源代碼,可以知道一本書的介紹的html標簽如下設置:

<li>
    <div>
        <h3>        </h3>
        <p>        </p>
        <p>        </p>
    </div>
    <a href>    <img src=></img>    </a>
</li>

根據標簽我們可以設置Book.java

String name; String message ; String synopsis ;String path;

分別對應書的名字,基本信息,大綱,圖片地址。


下面源程序引入的包名省略(可通過ctrl+shift+o導入):

public class BookDao {
    public static List<Book> getAllBooks() throws Exception{
        List<Book> list = new ArrayList<Book>();
        URL url = new URL("http://book.douban.com/latest");
        URLConnection conn = url.openConnection();
        Source source = new Source(conn);
        List<Element>elList = source.getAllElements("li");
        for(Element e:elList){
            List<Element> childrenList = e.getChildElements();
            if(childrenList.size()==2 && "div".equals(childrenList.get(0).getName())
                    && "a".equals(childrenList.get(1).getName())){
                Book book = new Book();
                String name = childrenList.get(0).getAllElements().get(0).getTextExtractor().toString();
                String message = childrenList.get(0).getAllElements().get(1).getTextExtractor().toString();
                String synopsis = childrenList.get(0).getAllElements().get(2).getTextExtractor().toString();
                String path = childrenList.get(1).getAllElements().get(1).getAttributeValue("src");
                book.setBname(name);
                book.setBmessage(message);
                book.setBsynopsis(synopsis);
                book.setBpathimg(path);
                list.add(book);
            }
        }
        return list;
    }
}

****************

BookDao的方法getAllBooks()獲得網址的所有圖書:

通過Source獲得鏈接的源,source.getAllElements("li")獲得所有li標簽包圍的內容,getChildElements()獲得其所有的子標簽,找到子標簽中如果是第一個子標簽為div,第二個子標簽為a的,獲得div子標簽下所有的子標簽,并把其下子標簽的內容取出來分別放入到book中,getAttributeValue("src")方法獲得其圖像的地址。最后將獲得的圖書加入到list中。因為不同網頁對li標簽下的設置不同,所以必須得根據需要打開的網頁進行適當的設置。

***************

imgCache存放緩存的圖片對象,loadImg(url)方法將傳入的url解析成InputStream,通過Drawable.createFromStream(in ,null)方法將stream流轉換成Drawable對象。

imgCache= new HashMap<String , SoftReference<Drawable>>();通過圖像地址唯一標識圖片作為Key,通過軟引用圖像。loadDraw(final String imgUrl,final ImgCallBack imgCallBack)判斷是否存在緩存圖片。如果沒有緩沖,即開啟線程去下載圖片,同時將當前的圖片放入到存放緩存圖片的HashMap中。

public class MainActivity extends Activity {
                                                                                   
    private List<Book> list;
    private ListView lv_book_list;
    private LinearLayout loading;
    private boolean isScroll = false;
    private BookListAdapter adapter;
    private boolean isloading  = false;
                                                                                   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        lv_book_list = (ListView) this.findViewById(R.id.books_list);
        loading = (LinearLayout) this.findViewById(R.id.progressll);
        list  = new ArrayList<Book>();
        adapter  = new BookListAdapter();
        /**第一次加載*/
        getData();
        /**判斷是否處于滾動狀態或是否已經滾動到最底部*/
        lv_book_list.setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                // TODO Auto-generated method stub
                if(totalItemCount <=0){
                    return ;
                }
                if(firstVisibleItem + visibleItemCount == totalItemCount){
                    if(isloading){
                        return ;
                    }
                    new AsyncTask<Void ,String ,List<Book>>(){
                        @Override
                        protected List<Book> doInVoid...  params) {
                            List<Book> listBooks = null;
                            try{
                                listBooks = BookDao.getAllBooks();
                            }catch(Exception e){
                                e.printStackTrace();
                            }
                            return listBooks;
                        }
                                                                                                       
                        protected void onPreExecute() {
                            loading.setVisibility(View.VISIBLE);
                            isloading = true;
                            super.onPreExecute();
                        }
                        protected void onPostExecute(List<Book> result) {
                            list.addAll(result);
                            loading.setVisibility(View.GONE);
                            adapter.notifyDataSetChanged();
                            isloading = false;
                            super.onPostExecute(result);
                        }
                        protected void onProgressUpdate(String... values) {
                            Toast.makeText(MainActivity.this, values[0], Toast.LENGTH_SHORT)
                            .show();
                            super.onProgressUpdate(values);
                        }
                    }.execute(null);
                }
            }
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                // TODO Auto-generated method stub
                switch(scrollState){
                case OnScrollListener.SCROLL_STATE_FLING:
                    isScroll = true;
                    break;
                case OnScrollListener.SCROLL_STATE_IDLE:
                    isScroll = false;
                    int startindex = lv_book_list.getFirstVisiblePosition();
                    int count = lv_book_list.getChildCount();
                    for(int i = 0 ; i < count ; i++){
                        int currentpostion = startindex + i;
                        final Book book = (Book) lv_book_list.getItemAtPosition(currentpostion);
                        final View viewchildren = lv_book_list.getChildAt(i);
                        ImageView icon = (ImageView) viewchildren.findViewById(R.id.icon);
                        Drawable drawable = ImgUtil.aimgLoader.loadDraw(book.getBpathimg(),
                                new ImgCallBack(){
                                    @Override
                                    public void imgLoaded(Drawable imgDrawable,
                                            String imgUrl) {
                                        ImageView ivTag = (ImageView) lv_book_list.findViewWithTag(imgUrl);
                                        if(ivTag !=null){
                                            ivTag.setImageDrawable(imgDrawable);
                                        }
                                    }
                        });
                        if(drawable != null){
                            icon.setImageDrawable(drawable);
                        }else{
                            icon.setImageResource(R.drawable.icon);
                        }
                    }
                    break;
                case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                    isScroll = true;
                    break;
                }
            }
                                                                                           
        });
    }
                                                                                   
    /**獲取第一次顯示的數據*/
    private void getData(){
        new AsyncTask<Void ,String ,List<Book>>(){
            @Override
            protected List<Book> doInVoid...  params) {
                List<Book> listBooks = null;
                try{
                    listBooks = BookDao.getAllBooks();
                }catch(Exception e){
                    publishProgress("獲取新書失??!");
                    e.printStackTrace();
                }
                return listBooks;
            }
            protected void onPreExecute() {
                loading.setVisibility(View.VISIBLE);
                isloading = true;
                super.onPreExecute();
            }
            protected void onPostExecute(List<Book> result) {
                list = result;
                loading.setVisibility(View.GONE);
                lv_book_list.setAdapter(adapter);
                isloading = false;
                super.onPostExecute(result);
            }
            protected void onProgressUpdate(String... values) {
                Toast.makeText(MainActivity.this, values[0], Toast.LENGTH_SHORT)
                .show();
                super.onProgressUpdate(values);
            }
        }.execute(null);
    }
                                                                                   
    private class BookListAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            // TODO Auto-generated method stub
            return list.size();
        }
        @Override
        public Object getItem(int position) {
            // TODO Auto-generated method stub
            return list.get(position);
        }
        @Override
        public long getItemId(int position) {
            // TODO Auto-generated method stub
            return position;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // TODO Auto-generated method stub
            View view = null;
            ViewCache viewCache = null;
            ViewHolder viewHolder = null;
            if(convertView == null){
                viewHolder  = new ViewHolder();
                view = View.inflate(MainActivity.this, R.layout.item, null);
                viewCache = new ViewCache(view);
                view.setTag(R.id.fir, viewCache);
                                                                                               
                viewHolder.name = (TextView) view.findViewById(R.id.name);
                viewHolder.message = (TextView) view.findViewById(R.id.message);
                viewHolder.synopsis = (TextView) view.findViewById(R.id.synopsis);
                view.setTag(R.id.sec, viewHolder);
            }else{
                view = convertView;
                viewCache = (ViewCache) view.getTag(R.id.fir);
                viewHolder = (ViewHolder) view.getTag(R.id.sec);
            }
            Book book = list.get(position);
            viewHolder.name.setText(book.getBname());
            viewHolder.message.setText(book.getBmessage());
            viewHolder.synopsis.setText(book.getBsynopsis());
            String imgUrl = book.getBsynopsis();
            ImageView imgBook = viewCache.getImgView();
            imgBook.setTag(imgUrl);       
                                                                                           
            if(isScroll){
                imgBook.setImageResource(R.drawable.icon);
            }else{
                /**靜止時下載網上的圖片*/
                Drawable drawable = ImgUtil.aimgLoader.loadDraw(imgUrl,
                        new ImgCallBack(){
                            public void imgLoaded(Drawable imgDrawable,
                                    String imgUrl) {
                                ImageView ivTag = (ImageView) lv_book_list.findViewWithTag(imgUrl);
                                if(ivTag != null){
                                    ivTag.setImageDrawable(imgDrawable);
                                }
                            }
                                                                                                       
                });
                if(drawable !=null){
                    imgBook.setImageDrawable(drawable);
                }else{
                    imgBook.setImageResource(R.drawable.icon);
                }
            }
            return view;
        }
                                                                                       
    }
    static class ViewHolder {
        ImageView icon;
        TextView  name;
        TextView  message;
        TextView  synopsis;
    }
}


另外涉及到的ViewCache包含view和p_w_picpathview,ImgUtil其實是AsyncImageLoader的管理器,大概這樣,因為最后的這個的源碼相關的解析在程序一開始就已經說明了,所以我再次看的時候大概應該也能知道吧。。。

程序其實還可以,不過因為有點雜亂,所以看得不爽,其實還有其他比較好的實現方法,但我認為寫這樣長一點的可以多知道其他android的知識點,再好好寫下一篇的時候再寫得清楚點吧~




向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女