zoukankan      html  css  js  c++  java
  • Android:ViewPager详细解释(异步网络负载图片,有图片缓存,)并与导航点

    android 应用。准则欢迎页面。 和图像旋转木马特征, 或者没有很多其他的内容显示在一个页面。以被划分成多个页面,在这一刻viewpager这是非常容易使用。


    首先看下效果:



    以下是一个样例。带异步网络载入图片,并带导航小圆点


    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 extends Activity {
    
    	private ViewPager view_pager;
    	
    	private LayoutInflater inflater;
    
    	// 图片的地址,这里能够从server获取
    	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"
    	
    	};
    		
    	private ImageView image;
    	private View item ;
    	private MyAdapter adapter ;
    	private ImageView[] indicator_imgs = new ImageView[7];//存放引到图片数组
    	
    	
    	
    	@Override
    	protected void 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)
    		 * 从server获取完数据(如文章标题、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(new MyListener());
    		
    		initIndicator();
    	}
    
    	
    	
    	/**
    	 * 初始化引导图标
    	 * 动态创建多个小圆点,然后组装到线性布局里
    	 */
    	private void 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]);
    		}
    		
    	}
    	
    	
    	
    	
    	/**
    	 * 适配器。负责装配 、销毁  数据  和  组件 。
    	 */
    	private class MyAdapter extends PagerAdapter {
    
    		private List<View> mList;
    
    		
    		private AsyncImageLoader asyncImageLoader;
    		
    		public MyAdapter(List<View> list) {
    			mList = list;
    			asyncImageLoader = new AsyncImageLoader();  
    		}
    
    		
    		
    		/**
    		 * Return the number of views available.
    		 */
    		@Override
    		public int getCount() {
    			// TODO Auto-generated method stub
    			return mList.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 public void destroyItem(ViewGroup container, int position, Object object) { // TODO Auto-generated method stub container.removeView(mList.get(position)); } @Override public boolean isViewFromObject(View arg0, Object arg1) { // TODO Auto-generated method stub return arg0==arg1; } /** * Create the page for the given position. */ @Override public Object instantiateItem(final ViewGroup container, final int position) { Drawable cachedImage = asyncImageLoader.loadDrawable( urls[position], new ImageCallback() { public void 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(); return mList.get(position); } } /** * 动作监听器,可异步载入图片 * */ private class MyListener implements OnPageChangeListener{ @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub if (state == 0) { //new MyAdapter(null).notifyDataSetChanged(); } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO Auto-generated method stub } @Override public void onPageSelected(int position) { // 改变全部导航的背景图片为:未选中 for (int i = 0; i < indicator_imgs.length; i++) { indicator_imgs[i].setBackgroundResource(R.drawable.indicator); } // 改变当前背景图片为:选中 indicator_imgs[position].setBackgroundResource(R.drawable.indicator_focused); } } /** * 异步载入图片 */ static class AsyncImageLoader { // 软引用。使用内存做暂时缓存 (程序退出。或内存不够则清除软引用) private HashMap<String, SoftReference<Drawable>> imageCache; public AsyncImageLoader() { imageCache = new HashMap<String, SoftReference<Drawable>>(); } /** * 定义回调接口 */ public interface ImageCallback { public void imageLoaded(Drawable imageDrawable, String imageUrl); } /** * 创建子线程载入图片 * 子线程载入完图片交给handler处理(子线程不能更新ui。而handler处在主线程,能够更新ui) * handler又交给imageCallback。imageCallback需要自己来实现,在这里能够对回调參数进行处理 * * @param imageUrl :需要载入的图片url * @param imageCallback: * @return */ public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) { //假设缓存中存在图片 ,则首先使用缓存 if (imageCache.containsKey(imageUrl)) { SoftReference<Drawable> softReference = imageCache.get(imageUrl); Drawable drawable = softReference.get(); if (drawable != null) { imageCallback.imageLoaded(drawable, imageUrl);//运行回调 return drawable; } } /** * 在主线程里运行回调,更新视图 */ final Handler handler = new Handler() { public void handleMessage(Message message) { imageCallback.imageLoaded((Drawable) message.obj, imageUrl); } }; /** * 创建子线程訪问网络并载入图片 ,把结果交给handler处理 */ new Thread() { @Override public void run() { Drawable drawable = loadImageFromUrl(imageUrl); // 下载完的图片放到缓存里 imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); Message message = handler.obtainMessage(0, drawable); handler.sendMessage(message); } }.start(); return null; } /** * 下载图片 (注意HttpClient 和httpUrlConnection的差别) */ public Drawable 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"); return d; } else { return null; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } //清除缓存 public void clearCache() { if (this.imageCache.size() > 0) { this.imageCache.clear(); } } } }




    以下是layout主文件:

    <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" >
    	
        <RelativeLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" >
    
            <android.support.v4.view.ViewPager
                android:id="@+id/view_pager"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" >
            </android.support.v4.view.ViewPager>
    
           <LinearLayout
                android:id="@+id/indicator"
                android:layout_width="fill_parent"
                android:layout_height="100px"
                android:layout_marginTop="500px"
                android:gravity="center_horizontal"
                android:orientation="horizontal" >
            </LinearLayout>
            
        </RelativeLayout>
      
    </LinearLayout>
    </span>


    以下是每一条item文件:

    <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"
            />
    
    </LinearLayout></span>



    代码地址

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    阿里P8架构师谈:阿里双11秒杀系统如何设计?
    秒杀系统设计的知识点
    秒杀系统架构优化思路
    秒杀系统解决方案
    Entity Framework Code First (七)空间数据类型 Spatial Data Types
    Entity Framework Code First (六)存储过程
    Entity Framework Code First (五)Fluent API
    Entity Framework Code First (四)Fluent API
    Entity Framework Code First (三)Data Annotations
    Entity Framework Code First (二)Custom Conventions
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4626364.html
Copyright © 2011-2022 走看看