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

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


首先看下效果:

\


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


packagecom.example.viewpagertest;
 
importjava.io.IOException;
importjava.lang.ref.SoftReference;
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
 
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.HttpStatus;
importorg.apache.http.client.ClientProtocolException;
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.methods.HttpGet;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.params.CoreConnectionPNames;
 
importandroid.annotation.SuppressLint;
importandroid.app.Activity;
importandroid.graphics.drawable.Drawable;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.os.Message;
importandroid.support.v4.view.PagerAdapter;
importandroid.support.v4.view.ViewPager;
importandroid.support.v4.view.ViewPager.OnPageChangeListener;
importandroid.view.LayoutInflater;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.ImageView;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
 
importcom.example.viewpagertest.MainActivity.AsyncImageLoader.ImageCallback;
 
 
 
/***
 *
 * 说明:ViewPager ,带小圆点导航,适配器采用PagerAdapter,基本可以满足需求
 * 也可以采用FragmentPagerAdapter,有人说,Fragment可以更好的适应平板和手机,
 * 并且可以更好的代码重用,具体这些好处大家试一下就知道了。
 *
 * @author andylaw
 *
 * 更多内容请查看博客:http://blog.csdn.net/lyc66666666666
 *
 */
 
@SuppressLint("NewApi")
publicclass MainActivity extendsActivity {
 
    privateViewPager view_pager;
     
    privateLayoutInflater inflater;
 
    // 图片的地址,这里可以从服务器获取
    String[] urls = newString[]{
             
            "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 = newArrayList<view>();
        inflater = LayoutInflater.from(this);
 
        /**
         * 创建多个item (每一条viewPager都是一个item)
         * 从服务器获取完数据(如文章标题、url地址) 后,再设置适配器
         */
        for(inti = 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 = newMyAdapter(list);
        view_pager.setAdapter(adapter);
 
        //绑定动作监听器:如翻页的动画
        view_pager.setOnPageChangeListener(newMyListener());
         
        initIndicator();
    }
 
     
     
    /**
     * 初始化引导图标
     * 动态创建多个小圆点,然后组装到线性布局里
     */
    privatevoid initIndicator(){
         
        ImageView imgView;
        View v = findViewById(R.id.indicator);// 线性水平布局,负责动态调整导航图标
         
        for(inti = 0; i < 7; i++) {
            imgView = newImageView(this);
            LinearLayout.LayoutParams params_linear = newLinearLayout.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 extendsPagerAdapter {
 
        privateList<view> mList;
 
         
        privateAsyncImageLoader asyncImageLoader;
         
        publicMyAdapter(List<view> list) {
            mList = list;
            asyncImageLoader = newAsyncImageLoader();  
        }
 
         
         
        /**
         * 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, intposition, 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],newImageCallback() {
 
                        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 implementsOnPageChangeListener{
 
        @Override
        publicvoid onPageScrollStateChanged(intstate) {
            // TODO Auto-generated method stub
            if(state == 0) {
                //new MyAdapter(null).notifyDataSetChanged();
            }
        }
 
         
        @Override
        publicvoid onPageScrolled(intarg0, floatarg1, intarg2) {
            // TODO Auto-generated method stub
             
        }
 
        @Override
        publicvoid onPageSelected(intposition) {
             
            // 改变所有导航的背景图片为:未选中
            for(inti = 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 = newHashMap<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,newSoftReference<drawable>(drawable));
                    Message message = handler.obtainMessage(0, drawable);
                    handler.sendMessage(message);
                }
            }.start();
             
            returnnull;
        }
 
         
        /**
         * 下载图片  (注意HttpClient 和httpUrlConnection的区别)
         */
        publicDrawable loadImageFromUrl(String url) {
 
            try{
                HttpClient client = newDefaultHttpClient();
                client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,1000*15);
                HttpGet get = newHttpGet(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();
            }
 
        }
 
    }
     
     
     
     
     
 
}


下面是layout主文件:

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

下面是每一条item文件:

?
1
2
3
4
5
6
7
<span style= "font-size:14px;" ><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:paddingbottom= "@dimen/activity_vertical_margin" android:paddingleft= "@dimen/activity_horizontal_margin" android:paddingright= "@dimen/activity_horizontal_margin" android:paddingtop= "@dimen/activity_vertical_margin" android:orientation= "vertical" >
 
    <textview android:id= "@+id/text_view" android:layout_width= "fill_parent" android:layout_height= "wrap_content" >
    
    <imageview android:id= "@+id/image" android:layout_width= "fill_parent" android:layout_height= "wrap_content" >
 
</imageview></textview></linearlayout></span>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值