Android:ViewPager扩展详解——带有导航的ViewPagerIndicator(附带图片缓存,异步加载图片)

大家都用过viewpager了, github上有对viewpager进行扩展,导航风格更加丰富,这个开源项目是ViewPagerIndicator,很好用,但是例子比较简单,实际用起来要进行很多扩展,比如在fragment里进行图片缓存和图片异步加载。


下面是ViewPagerIndicator源码运行后的效果,大家也都看过了,我多此一举截几张图;



下载源码请点击这里






===========================================华丽的分割线========================================


下面是我改装过的,可异步加载图片,可图片缓存:



看到美女你心动了没有呢?



package com.example.viewpagerindicatortest;

import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.TabPageIndicator;


/**
 * 基于Fragment的Tab样式的viewpager;
 * 
 * @author andy
 * 
 * 更多详情请访问博客:http://blog.csdn.net/lyc66666666666
 */
public class SampleTabsDefault extends FragmentActivity {
	
	//tab标题
    private static final String[] CONTENT = new String[] { "Recent", "Artists", "Albums", "Songs", "Playlists", "Genres" ,"test"};

	private List<SubFragment> list = new ArrayList<SubFragment>();


	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"

	};
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.simple_tabs);
        
        /*
         * 初始化:组装多个fragment
         * 第一次创建subfragment不会执行onCreateView方法
         */
        for (int i = 0; i < 7; i++) {
        	
        	SubFragment fragment =new SubFragment(urls[i]);
			list.add(fragment);
		}
        
        
        
        
        ViewPager pager = (ViewPager)findViewById(R.id.pager);
        pager.setAdapter(new MyAdapter(getSupportFragmentManager(),list));//设置适配器

        TabPageIndicator indicator = (TabPageIndicator)findViewById(R.id.indicator);
        indicator.setViewPager(pager);//
        
        
        
    }

    
    /**
     * FragmentPagerAdapter用来适配Fragment
     */
    class MyAdapter extends FragmentPagerAdapter {
    	
    	List<SubFragment> mList;
    	
		public MyAdapter(FragmentManager fm,List<SubFragment> list) {
			super(fm);
			mList = list;
		}

		
		/**
		 * FragmentPagerAdapter初始化item的时候会调用一次getItem,
		 * 而第二次返回item则不调用getItem方法,而是执行SubFragment的onCreateView方法;
		 * 也就是说只有在与fragment关联的时候会调用一次getItem,以后则不调用;
		 */
		@Override
		public Fragment getItem(int position) {
			
			return mList.get(position);

		}


		/*
		 * 返回title
		 */
        @Override
        public CharSequence getPageTitle(int position) {
            return CONTENT[position % CONTENT.length].toUpperCase();
        }

        /*
         * 返回总页数
         */
        @Override
        public int getCount() {
          return mList.size();
        }
        
        
    }
    
    
    
}



package com.example.viewpagerindicatortest;

import java.io.IOException;
import java.lang.ref.SoftReference;

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.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;


/**
 * 基于Fragment的Tab样式的viewpager;
 * 
 * @author andy
 * 
 * 更多详情请访问博客:http://blog.csdn.net/lyc66666666666
 */
@SuppressLint("ValidFragment")
public  class SubFragment extends Fragment {
	
	
    private static final String KEY_CONTENT = "TestFragment:Content";

    private String mContent = "???";
    
    private String url;
 
    public SubFragment(String url) {
    	
    	this.url = url;
    	System.out.println("url:"+url);
    	
	}
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
            mContent = savedInstanceState.getString(KEY_CONTENT);
        }
    }
    
    
    View v ;
    
    /**
     * 每次翻页都会调用onCreateView创建一次组件
     */
	@Override
	public View onCreateView(LayoutInflater inflater,
			final ViewGroup container, Bundle savedInstanceState) {

		v = inflater.inflate(R.layout.test, null);


		new AsyncImageLoader().loadDrawable(url, new ImageCallback() {

			@SuppressLint("NewApi")
			public void imageLoaded(Drawable imageDrawable, String imageUrl) {
				System.out.println("图片获取完成");

				ImageView image = (ImageView) v.findViewById(R.id.img);
				image.setBackground(imageDrawable);
				
			}
		});

		return v;
	}

    
	

    /**
	 * 定义回调接口
	 */
	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable, String imageUrl);
	}
    
    /**
	 * 异步加载图片
	 */
	static class AsyncImageLoader {
		

	    Global global;

		public AsyncImageLoader() {
			global = Global.getInstance();
		}


		/**
		 * 创建子线程加载图片
		 * 子线程加载完图片交给handler处理(子线程不能更新ui,而handler处在主线程,可以更新ui)
		 * handler又交给imageCallback,imageCallback须要自己来实现,在这里可以对回调参数进行处理
		 *
		 * @param imageUrl :须要加载的图片url
		 * @param imageCallback:
		 * @return
		 */
		public Drawable loadDrawable(final String imageUrl,
				final ImageCallback imageCallback) {
			
			//如果缓存中存在图片  ,则首先使用缓存
			if (global.getCache(imageUrl)!=null) {
				System.out.println("存在缓存~~~~~~~~~~~~~~~~~");
				SoftReference<Drawable> softReference = global.getCache(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);
					// 下载完的图片放到缓存里
					global.setCache(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;
		}

		

	}
	
	
	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString(KEY_CONTENT, mContent);
	}
	
}



package com.example.viewpagerindicatortest;

import java.lang.ref.SoftReference;
import java.util.HashMap;

import android.graphics.drawable.Drawable;

/**
 * 全局变量,以软引用方式存放图片缓存
 * 
 * @author andy
 * 
 * 更多详情请访问博客:http://blog.csdn.net/lyc66666666666
 */
public class Global {

	// 软引用,使用内存做临时缓存 (程序退出,或内存不够则清除软引用)
	private static HashMap<String, SoftReference<Drawable>> imageCache;

	private static Global global;

	public static Global getInstance() {

		if (global == null) {
			global = new Global();
		}

		if (imageCache == null) {
			imageCache = new HashMap<String, SoftReference<Drawable>>();
		}

		return global;

	}

	
	//存放缓存
	public void setCache(String url, SoftReference<Drawable> softReference) {

		imageCache.put(url, softReference);
		
	}

	//获取缓存
	public SoftReference<Drawable> getCache(String url) {
		
		return imageCache.get(url);
		
	}
	
	//清除缓存
	public void clearCache() {
		if (imageCache.size() > 0) {
			imageCache.clear();
		}
	}
	
	
}



simple_tabs.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 Jake Wharton

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <com.viewpagerindicator.TabPageIndicator
        android:id="@+id/indicator"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        />
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        />

</LinearLayout>


test.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/img"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>


AndroidMainfest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.viewpagerindicatortest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    
    <uses-permission android:name="android.permission.INTERNET"/>
    
        
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        
         <activity
            android:name=".SampleTabsDefault"
            android:label="@string/app_name"
            android:theme="@style/Theme.PageIndicatorDefaults">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>



点击下载源码

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ViewPager是一个Android中的View容器,可以让用户在多个页面之间进行滑动切换。要实现多页面滑动切换以及动画效果,可以按照以下步骤: 1. 在XML布局文件中添加ViewPager控件,并添加对应的布局文件,例如: ``` <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2. 在Java代码中为ViewPager设置Adapter,用于显示多个页面。例如: ``` ViewPager viewPager = findViewById(R.id.viewPager); MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); ``` 其中,MyPagerAdapter是自定义的PagerAdapter类,需要继承自FragmentPagerAdapter或FragmentStatePagerAdapter。 3. 在自定义的PagerAdapter类中实现getItem()方法,用于返回每个页面的Fragment实例。例如: ``` @Override public Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); case 1: return new Fragment2(); case 2: return new Fragment3(); default: return null; } } ``` 其中,Fragment1、Fragment2、Fragment3是自定义的Fragment类,用于显示对应页面的内容。 4. 如果需要添加页面切换的动画效果,可以在Java代码中为ViewPager设置PageTransformer。例如: ``` viewPager.setPageTransformer(true, new DepthPageTransformer()); ``` 其中,DepthPageTransformer是自定义的PageTransformer类,用于实现页面切换时的动画效果。可以参考以下代码示例: ``` public class DepthPageTransformer implements ViewPager.PageTransformer { private static final float MIN_SCALE = 0.75f; public void transformPage(View view, float position) { int pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) // This page is way off-screen to the left. view.setAlpha(0f); } else if (position <= 0) { // [-1,0] // Use the default slide transition when moving to the left page view.setAlpha(1f); view.setTranslationX(0f); view.setScaleX(1f); view.setScaleY(1f); } else if (position <= 1) { // (0,1] // Fade the page out. view.setAlpha(1 - position); // Counteract the default slide transition view.setTranslationX(pageWidth * -position); // Scale the page down (between MIN_SCALE and 1) float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else { // (1,+Infinity] // This page is way off-screen to the right. view.setAlpha(0f); } } } ``` 以上就是实现AndroidViewPager多页面滑动切换以及动画效果的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值