Android:ViewPager详解(异步网络加载图片,带图片缓存,并带导航小圆点)

时间:2021-04-27 20:42:13

android 应用中,如欢迎指引页面, 和图片轮播功能, 或者更多的内容在一页显示不了,要分成多个页面,这时候viewpager是很好用的。


首先看下效果:

Android:ViewPager详解(异步网络加载图片,带图片缓存,并带导航小圆点)


下面是一个例子,带异步网络加载图片,并带导航小圆点


?
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 package com.example.viewpagertest; import java.io.IOException;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.HashMap;import java.util.List; import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.HttpStatus;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.params.CoreConnectionPNames; import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.drawable.Drawable;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.support.v4.view.ViewPager.OnPageChangeListener;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.TextView; import com.example.viewpagertest.MainActivity.AsyncImageLoader.ImageCallback;   /*** * * 说明:ViewPager ,带小圆点导航,适配器采用PagerAdapter,基本可以满足需求 * 也可以采用FragmentPagerAdapter,有人说,Fragment可以更好的适应平板和手机, * 并且可以更好的代码重用,具体这些好处大家试一下就知道了。 * * @author andylaw * * 更多内容请查看博客:http://blog.csdn.net/lyc66666666666 * */ @SuppressLint("NewApi")public class MainActivity extendsActivity {     privateViewPager view_pager;         privateLayoutInflater inflater;     // 图片的地址,这里可以从服务器获取    String[] urls =new String[]{                         "http://a.hiphotos.baidu.com/image/pic/item/3bf33a87e950352ad6465dad5143fbf2b2118b6b.jpg",            "http://a.hiphotos.baidu.com/image/pic/item/c8177f3e6709c93d002077529d3df8dcd0005440.jpg",            "http://f.hiphotos.baidu.com/image/pic/item/7aec54e736d12f2ecc3d90f84dc2d56285356869.jpg",            "http://e.hiphotos.baidu.com/image/pic/item/9c16fdfaaf51f3de308a87fc96eef01f3a297969.jpg",            "http://d.hiphotos.baidu.com/image/pic/item/f31fbe096b63f624b88f7e8e8544ebf81b4ca369.jpg",            "http://h.hiphotos.baidu.com/image/pic/item/11385343fbf2b2117c2dc3c3c88065380cd78e38.jpg",            "http://c.hiphotos.baidu.com/image/pic/item/3801213fb80e7bec5ed8456c2d2eb9389b506b38.jpg"         };             privateImageView image;    privateView item ;    privateMyAdapter adapter ;    privateImageView[] indicator_imgs = newImageView[7];//存放引到图片数组                   @Override    protectedvoid onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);         view_pager = (ViewPager) findViewById(R.id.view_pager);        List<view> list =new ArrayList<view>();        inflater = LayoutInflater.from(this);         /**         * 创建多个item (每一条viewPager都是一个item)         * 从服务器获取完数据(如文章标题、url地址) 后,再设置适配器         */        for(int i = 0; i < 7; i++) {            item = inflater.inflate(R.layout.item,null);            ((TextView) item.findViewById(R.id.text_view)).setText("第 "+ i+ " 个 viewPager");            list.add(item);        }         //创建适配器, 把组装完的组件传递进去        adapter =new MyAdapter(list);        view_pager.setAdapter(adapter);         //绑定动作监听器:如翻页的动画        view_pager.setOnPageChangeListener(newMyListener());                 initIndicator();    }               /**     * 初始化引导图标     * 动态创建多个小圆点,然后组装到线性布局里     */    privatevoid initIndicator(){                 ImageView imgView;        View v = findViewById(R.id.indicator);// 线性水平布局,负责动态调整导航图标                 for(int i = 0; i < 7; i++) {            imgView =new ImageView(this);            LinearLayout.LayoutParams params_linear =new LinearLayout.LayoutParams(10,10);            params_linear.setMargins(7,10, 7,10);            imgView.setLayoutParams(params_linear);            indicator_imgs[i] = imgView;                         if(i == 0) {// 初始化第一个为选中状态                                 indicator_imgs[i].setBackgroundResource(R.drawable.indicator_focused);            }else {                indicator_imgs[i].setBackgroundResource(R.drawable.indicator);            }            ((ViewGroup)v).addView(indicator_imgs[i]);        }             }                        /**     * 适配器,负责装配 、销毁  数据  和  组件 。     */    privateclass MyAdapter extends PagerAdapter {         privateList<view> mList;                  privateAsyncImageLoader asyncImageLoader;                 publicMyAdapter(List<view> list) {            mList = list;            asyncImageLoader =new AsyncImageLoader();         }                           /**         * Return the number of views available.         */        @Override        publicint getCount() {            // TODO Auto-generated method stub            returnmList.size();        }                  /**         * Remove a page for the given position.         * 滑动过后就销毁 ,销毁当前页的前一个的前一个的页!         * instantiateItem(View container, int position)         * This method was deprecated in API level . Use instantiateItem(ViewGroup, int)         */        @Override        publicvoid destroyItem(ViewGroup container,int position, Object object) {            // TODO Auto-generated method stub            container.removeView(mList.get(position));                     }         @Override        publicboolean isViewFromObject(View arg0, Object arg1) {            // TODO Auto-generated method stub            returnarg0==arg1;        }                  /**         * Create the page for the given position.         */        @Override        publicObject instantiateItem(finalViewGroup container, finalint position) {                          Drawable cachedImage = asyncImageLoader.loadDrawable(                    urls[position],new ImageCallback() {                         publicvoid imageLoaded(Drawable imageDrawable,                                String imageUrl) {                             View view = mList.get(position);                            image = ((ImageView) view.findViewById(R.id.image));                            image.setBackground(imageDrawable);                            container.removeView(mList.get(position));                            container.addView(mList.get(position));                            // adapter.notifyDataSetChanged();                         }                    });             View view = mList.get(position);            image = ((ImageView) view.findViewById(R.id.image));            image.setBackground(cachedImage);             container.removeView(mList.get(position));            container.addView(mList.get(position));            // adapter.notifyDataSetChanged();                              returnmList.get(position);         }                  }              /**     * 动作监听器,可异步加载图片     *     */    privateclass MyListener implements OnPageChangeListener{         @Override        publicvoid onPageScrollStateChanged(intstate) {            // TODO Auto-generated method stub            if(state == 0) {                //new MyAdapter(null).notifyDataSetChanged();            }        }                  @Override        publicvoid onPageScrolled(intarg0, float arg1, int arg2) {            // TODO Auto-generated method stub                     }         @Override        publicvoid onPageSelected(intposition) {                         // 改变所有导航的背景图片为:未选中            for(int i = 0; i < indicator_imgs.length; i++) {                                 indicator_imgs[i].setBackgroundResource(R.drawable.indicator);                             }                         // 改变当前背景图片为:选中            indicator_imgs[position].setBackgroundResource(R.drawable.indicator_focused);        }                      }               /**     * 异步加载图片     */    staticclass AsyncImageLoader {         // 软引用,使用内存做临时缓存 (程序退出,或内存不够则清除软引用)        privateHashMap<string, softreference<drawable="">> imageCache;         publicAsyncImageLoader() {            imageCache =new HashMap<string, softreference<drawable="">>();        }         /**         * 定义回调接口         */        publicinterface ImageCallback {            publicvoid imageLoaded(Drawable imageDrawable, String imageUrl);        }                  /**         * 创建子线程加载图片         * 子线程加载完图片交给handler处理(子线程不能更新ui,而handler处在主线程,可以更新ui)         * handler又交给imageCallback,imageCallback须要自己来实现,在这里可以对回调参数进行处理         *         * @param imageUrl :须要加载的图片url         * @param imageCallback:         * @return         */        publicDrawable loadDrawable(finalString imageUrl,                finalImageCallback imageCallback) {                         //如果缓存中存在图片  ,则首先使用缓存            if(imageCache.containsKey(imageUrl)) {                SoftReference<drawable> softReference = imageCache.get(imageUrl);                Drawable drawable = softReference.get();                if(drawable != null) {                    imageCallback.imageLoaded(drawable, imageUrl);//执行回调                    returndrawable;                }            }             /**             * 在主线程里执行回调,更新视图             */            finalHandler handler = newHandler() {                publicvoid handleMessage(Message message) {                    imageCallback.imageLoaded((Drawable) message.obj, imageUrl);                }            };                          /**             * 创建子线程访问网络并加载图片 ,把结果交给handler处理             */            newThread() {                @Override                publicvoid run() {                    Drawable drawable = loadImageFromUrl(imageUrl);                    // 下载完的图片放到缓存里                    imageCache.put(imageUrl,new SoftReference<drawable>(drawable));                    Message message = handler.obtainMessage(0, drawable);                    handler.sendMessage(message);                }            }.start();                         returnnull;        }                  /**         * 下载图片  (注意HttpClient 和httpUrlConnection的区别)         */        publicDrawable loadImageFromUrl(String url) {             try{                HttpClient client =new DefaultHttpClient();                client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,1000*15);                HttpGet get =new HttpGet(url);                HttpResponse response;                 response = client.execute(get);                if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {                    HttpEntity entity = response.getEntity();                     Drawable d = Drawable.createFromStream(entity.getContent(),                            "src");                     returnd;                }else {                    returnnull;                }            }catch (ClientProtocolException e) {                e.printStackTrace();            }catch (IOException e) {                e.printStackTrace();            }             returnnull;        }         //清除缓存        publicvoid clearCache() {             if(this.imageCache.size() >0) {                 this.imageCache.clear();            }         }     }                          }</drawable></drawable></string,></string,></view></view></view></view>



下面是layout主文件:

?
1234567891011121314 <span style="font-size: 14px;"><linearlayout android:paddingtop="@dimen/activity_vertical_margin"android:paddingright="@dimen/activity_horizontal_margin"android:paddingleft="@dimen/activity_horizontal_margin"android:paddingbottom="@dimen/activity_vertical_margin"android:layout_height="match_parent"android:layout_width="match_parent"xmlns:tools="http://schemas.android.com/tools"xmlns:android="http://schemas.android.com/apk/res/android">         <relativelayout android:layout_height="fill_parent"android:layout_width="fill_parent">                  </android.support.v4.view.viewpager>        <linearlayout android:id="@+id/indicator"android:layout_height="100px"android:layout_width="fill_parent"android:orientation="horizontal"android:gravity="center_horizontal"android:layout_margintop="500px">        </linearlayout>             </relativelayout>   </linearlayout></span>


下面是每一条item文件:

?
1234567 <span style="font-size: 14px;"><linearlayout android:paddingtop="@dimen/activity_vertical_margin"android:paddingright="@dimen/activity_horizontal_margin"android:paddingleft="@dimen/activity_horizontal_margin"android:paddingbottom="@dimen/activity_vertical_margin"android:layout_height="match_parent"android:layout_width="match_parent"xmlns:tools="http://schemas.android.com/tools"xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical">    <textview android:id="@+id/text_view"android:layout_height="wrap_content"android:layout_width="fill_parent">       <imageview android:id="@+id/image"android:layout_height="wrap_content"android:layout_width="fill_parent"> </imageview></textview></linearlayout></span>



原文:http://www.2cto.com/kf/201406/307322.html