Android 开发之下拉刷新+ViewPager的banner滚动

暂时不逼逼,先来两张鲜果图:


在这个项目里,核心部分就是怎么在下拉刷新的类里面,加入ViewPage,这么先说设计界面需要新建的xml。

第一步:在资源文件resource 的layout 新建activity_main.xml;

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_style"
    android:orientation="vertical" >
    
      <LinearLayout
          android:layout_width="match_parent"
          android:layout_height="60dp"
          android:background="@drawable/item_bg"
          android:gravity="center"
          android:orientation="vertical" >

        <TextView
            android:id="@+id/staff_head_text"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:gravity="center_horizontal|center"
            android:text="@string/app_name"
            android:textColor="@color/black"
            android:textSize="14sp"
            android:textStyle="bold" />

    </LinearLayout>
    
 <com.refresh.PullToRefreshLayout
    android:id="@+id/refresh_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >         
      <include layout="@layout/refresh_head"/>
      <include layout="@layout/view_cycle_header" /> 
       <com.refresh.PullableListView
        android:id="@+id/content_view"
        android:layout_marginTop="140dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/white"
        android:divider="@color/gray"
        android:dividerHeight="1dp"/>
   
</com.refresh.PullToRefreshLayout>  
</LinearLayout>

第二步:继续在资源文件resource 的layout 新建refresh_head.xml;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/head_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:paddingBottom="20dp"
        android:paddingTop="20dp" >

            <ImageView
                android:id="@+id/refreshing_icon"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_centerVertical="true"
                android:background="@drawable/refreshing"
                android:layout_toLeftOf="@+id/state_tv_layout"
                android:visibility="gone" />
            
            <LinearLayout
                android:id="@+id/state_tv_layout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true">

            <TextView
                android:id="@+id/state_tv"
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:text="@string/pull_to_refresh"
                android:textColor="@color/white"
                android:gravity="center"
                android:textSize="14sp" />
            </LinearLayout>

            <ImageView
                android:id="@+id/state_iv"
                android:layout_width="16dp"
                android:layout_height="16dp"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@id/state_tv_layout"
                android:visibility="gone" />

            <ImageView
                android:id="@+id/pull_icon"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@+id/state_tv_layout"
                android:background="@drawable/pull_icon_big" />

    </RelativeLayout>

</RelativeLayout>
第二步:资源文件resource 的layout 新建view_cycle_header.xml;

.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="140dip"
    android:background="#f1f1f1" >
    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@color/white" >

        <android.support.v4.view.ViewPager
            android:id="@+id/vp"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="35dip"
            android:layout_gravity="bottom"
            android:background="#33000000"
            android:gravity="center"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="XXXX"
                android:textColor="#ffffff" />

            <LinearLayout
                android:id="@+id/v_dot_list"
                android:layout_width="fill_parent"
                android:layout_height="15dp"
                android:layout_gravity="center_horizontal|center"
                android:layout_marginTop="3dip"
                android:gravity="center"
                android:orientation="horizontal"
                android:paddingRight="20dp" >

               <!--  <View
                    style="@style/dot_style"
                    android:background="@drawable/dot_focused" />
                  <View  style="@style/dot_style" /> 
                  <View     style="@style/dot_style" /> 
                  <View    style="@style/dot_style" /> 
                  <View  style="@style/dot_style" /> -->
              
            </LinearLayout>
        </LinearLayout>
    </FrameLayout>
    </RelativeLayout>

第三步:就是我们在设计中涉及到的样式xml,在drawable 文档中新建bg_style.xml样式 ,shape用于设定形状,这么是圆角边框:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
     <!-- 边框-->
    <stroke    
        android:width="0.01dip"            
        android:color="#BDC7D8" />  
    <solid android:color="#ffffff"/>
      <!-- 设置圆角
	注意:	bottomRightRadius是左下角而不是右下角  bottomLeftRadius右下角
	<corners android:topLeftRadius="5dp"
	    android:topRightRadius="5dp"
	    android:bottomLeftRadius="5dp"
	    android:bottomRightRadius="5dp"/>	-->
</shape>

第四步:设计中涉及到的样式   item_bg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 底部圆角 白色背景 灰色边框 长方体 -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#FFFFFF" />         
            <stroke android:width="1dp" android:color="#c8c7cc" />
        </shape>
    </item>
    <item  android:bottom="1dp"  android:right="1dp">
        <shape>
            <solid android:color="#FFFFFF" />           
            <stroke   android:width="0.01dip" android:color="#ffffffff" />
        </shape>
    </item>
</layer-list>

样式 dot_focused.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#aaFFFFFF" />

    <corners android:radius="3dip" />

</shape>

dot_normal.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval" >

    <solid android:color="#33000000" />

    <corners android:radius="3dip" />

</shape>

项目目录:

接下就是MainActivity.java

package com.imagelistrefresh;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;





import com.refresh.PullToRefreshLayout;
import com.refresh.PullToRefreshLayout.OnRefreshListener;
import com.refresh.PullableListView;
import com.refresh.PullableListView.OnLoadListener;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;

import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
 * 
 * @author StephenYang
 *
 */
public class MainActivity extends Activity implements OnLoadListener
{

	public List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
	
	public List<Map<String, Object>> list_banner = new ArrayList<Map<String, Object>>();
	
	
	public int images[] = {R.drawable.g_1,R.drawable.g_2,R.drawable.g_3,R.drawable.g_4,R.drawable.g_5};
    


	
	private PullableListView listView;
	//private newsList adapter;
	private MyListAdapter adapter;

	private ViewPager viewPager; // android-support-v4中的滑动组件


	private String[] titles; // 图片标题

	private List<View> dots; // 图片标题正文的那些点


	
	
	private TextView tv_title;
	private int currentItem = 0; // 当前图片的索引号
	


	// An ExecutorService that can schedule commands to run after a given delay,
	// or to execute periodically.
	private ScheduledExecutorService scheduledExecutorService;
	private PullToRefreshLayout pulltorefresh;
	private LinearLayout v_dot_list;
	View olderSelectView = null;
	
	private int totalpage; //总页数
	private List<ImageView> imageViews=new ArrayList<ImageView>(); // 滑动的图片集合

	// 切换当前显示的图片
	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			if(msg.what==20001){
				viewPager.setCurrentItem(currentItem);// 切换当前显示的图片
			}
			
		};
	};

	@SuppressLint("HandlerLeak")
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);	
		setContentView(R.layout.activity_main);	
	 
	    dots = new ArrayList<View>(); 
	    pulltorefresh=(PullToRefreshLayout) findViewById(R.id.refresh_view);
	    pulltorefresh.setOnRefreshListener(new OnRefreshListener() {					
					@Override
					public void onRefresh(final PullToRefreshLayout pullToRefreshLayout) {
						// TODO Auto-generated method stub
						// 下拉刷新操作
						new Handler()
						{
							@Override
							public void handleMessage(Message msg)
							{
								list.clear();
								initListView();				
								pullToRefreshLayout.refreshFinish(PullToRefreshLayout.SUCCEED);						
											
								listView.setOnLoadListener(MainActivity.this);
												
						        adapter.notifyDataSetChanged();
						       // 千万别忘了告诉控件刷新完毕了哦!
								if (totalpage > 10) {								
									listView.setHasMoreData(false);
									return;
								}
							}
						}.sendEmptyMessageDelayed(0, 3000);
					}
				});
		
	
		listView = (PullableListView)findViewById(R.id.content_view);
		v_dot_list=(LinearLayout)pulltorefresh.findViewById(R.id.v_dot_list);
		initListView();	
		listView.setOnLoadListener(this);
		listView.setHasMoreData(false);
		
	
		getFocusImageList();
	}	



	/**
	 * ListView初始化方法
	 */
	private void initListView()
	{
		   for(int i=0;i<10;i++){
			   HashMap<String, Object> map = new HashMap<String, Object>();	
				map.put("news_title","VVVVVVVVVVV");
				map.put("news_subtitle","vvvvvvvvvvvvvv");
				map.put("news_logo","");
				list.add(map);   
		   }

		adapter = new MyListAdapter(listView,MainActivity.this,list);	
		listView.setAdapter(adapter);		
	    adapter.notifyDataSetChanged();		
		listView.setOnItemClickListener(new OnItemClickListener()
		{

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id)
			{
				// Toast.makeText(MainActivity.this, newsid.getText().toString(), Toast.LENGTH_SHORT).show(); 
			}
		});
		
		
	}

	

	/**
	 * 获取焦点图列表
	 */
   @SuppressLint("NewApi")
public  void getFocusImageList(){
   

		// 将最后一个ImageView添加进来
		
		if(images.length>0){
			titles = new String[images.length];
			//imageViews.add(ViewFactory.getImageView(this, infos.get(infos.size() - 1).getUrl()));
			for (int i = 0; i <images.length; i++) {
				AbsListView.LayoutParams param=new AbsListView.LayoutParams(6, 6);
			
			
				ImageView img =new ImageView(this);
				View img_v=new View(this);
				img_v.setBackgroundColor(R.style.dot_style);
				img_v.setLayoutParams(param);
			    int x_x=i+5;
		
				img.setImageResource(images[i]);
				imageViews.add(img);
				titles[i] ="xxxxxxxxxxx";
				if(i==0){
					img_v.setBackgroundResource(R.drawable.dot_focused);
					//dots.add(findViewById(R.id.v_dot0));				
				}else{
					img_v.setBackgroundResource(R.drawable.dot_normal);				
				}
				
				img_v.setX(x_x);
				img_v.invalidate();
				dots.add(img_v);			
				v_dot_list.addView(img_v,i);
			}
			v_dot_list.invalidate();
			// 将第一个ImageView添加进来
			//imageViews.add(ViewFactory.getImageView(this, infos.get(0).getUrl()));
		}
	

	
		tv_title = (TextView)pulltorefresh.findViewById(R.id.tv_title);
		tv_title.setText(titles[0]);//		
		viewPager = (ViewPager)pulltorefresh.findViewById(R.id.vp);
		viewPager.setAdapter(new MyAdapter());// 设置填充ViewPager页面的适配器
		// 设置一个监听器,当ViewPager中的页面改变时调用
		viewPager.setOnPageChangeListener(new MyPageChangeListener());		
	
				
	
}
	// 切换
	public void pushAnimUp() {
		overridePendingTransition(R.anim.push_up_in, R.anim.push_up_out);
	}

	
	@SuppressLint("HandlerLeak")
	@Override
	public void onLoad(final PullableListView pullableListView)
	{
		new Handler()
		{
			@Override
			public void handleMessage(Message msg)
			{
					
				initListView();					
				listView.setOnLoadListener(MainActivity.this);
				listView.setHasMoreData(true);
		        pullableListView.finishLoading();
		        adapter.notifyDataSetChanged();
			}
		}.sendEmptyMessageDelayed(0, 2000);
	}
	
	

	
	@Override
	protected void onStart() {
		scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
		// 当Activity显示出来后,每两秒钟切换一次图片显示
		scheduledExecutorService.scheduleAtFixedRate(new ScrollTask(), 1, 2, TimeUnit.SECONDS);
		super.onStart();
	}

	@Override
	protected void onStop() {
		// 当Activity不可见的时候停止切换
		scheduledExecutorService.shutdown();
		super.onStop();
	}

	/**
	 * 换行切换任务
	 * 
	 * @author Administrator
	 * 
	 */
	private class ScrollTask implements Runnable {

		@Override
		public void run() {
			synchronized (viewPager) {
				System.out.println("currentItem: " + currentItem);
				System.out.println("currentItem-size: " +images.length);
				currentItem = (currentItem + 1) % images.length;
				//handler.obtainMessage().sendToTarget(); // 通过Handler切换图片
				android.os.Message m=handler.obtainMessage(); 
			    m.what=20001; 
				m.sendToTarget(); 
				
			}
		}

	}

	/**
	 * 当ViewPager中页面的状态发生改变时调用
	 * 
	 * @author Administrator
	 * 
	 */
	private class MyPageChangeListener implements OnPageChangeListener {
		private int oldPosition = 0;

		/**
		 * This method will be invoked when a new page becomes selected.
		 * position: Position index of the new selected page.
		 */
		@Override
		public void onPageSelected(int position) {
			currentItem = position;
			
			   Log.e("position", String.valueOf(position));
			tv_title.setText(titles[position]);
			dots.get(oldPosition).setBackgroundResource(R.drawable.dot_normal);
			dots.get(position).setBackgroundResource(R.drawable.dot_focused);
			oldPosition = position;
		}

		@Override
		public void onPageScrollStateChanged(int arg0) {

		}

		@Override
		public void onPageScrolled(int arg0, float arg1, int arg2) {

		}
	}

	/**
	 * 填充ViewPager页面的适配器
	 * 
	 * @author Administrator
	 * 
	 */
	private class MyAdapter extends PagerAdapter {

		@Override
		public int getCount() {
			return imageViews.size();
		}

		@Override
		public Object instantiateItem(View arg0, int arg1) {
			
			((ViewPager) arg0).addView(imageViews.get(arg1));
			return imageViews.get(arg1);
		}

		@Override
		public void destroyItem(View arg0, int arg1, Object arg2) {
			((ViewPager) arg0).removeView((View) arg2);
		}

		@Override
		public boolean isViewFromObject(View arg0, Object arg1) {
			return arg0 == arg1;
		}

		@Override
		public void restoreState(Parcelable arg0, ClassLoader arg1) {

		}

		@Override
		public Parcelable saveState() {
			return null;
		}

		@Override
		public void startUpdate(View arg0) {

		}

		@Override
		public void finishUpdate(View arg0) {

		}
	}


}

数据适配器 MyListAdapter.java

package com.imagelistrefresh;

  
import java.util.ArrayList;
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  

import com.imagelistrefresh.AsyncImageTask.ImageCallback;



import android.content.Context;  

import android.graphics.drawable.Drawable;  
import android.util.Log;  
import android.view.LayoutInflater;  
import android.view.View;  
import android.view.ViewGroup;  
import android.widget.AbsListView;  
 
import android.widget.ImageView;  
import android.widget.ListView;  
import android.widget.SimpleAdapter;  
import android.widget.TextView;

  

  
/** 
 * 自定义List内容控件 
 * @author Hai Jiang 
 * @Email 672335219@qq.ciom 
 * @Data 2014-2-26 
 */  
public class MyListAdapter extends SimpleAdapter{ 

    public List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    private LayoutInflater inflater;  
    /**异步加载图片实例*/  
    private AsyncImageTask imageTask;  
    /**被绑定对象*/  
    private ListView listView;  
    /**Item对象集*/  
    HashMap<String, Object> itemMap =  new HashMap<String, Object>();  
    private Context _content;  
    public MyListAdapter(final ListView listView,Context context,  
    		List<Map<String, Object>> list) {  
        super(context, list, 0, null, null);  
        this.list = list;  
        this.listView = listView;    
        inflater = LayoutInflater.from(context);    
        imageTask = new AsyncImageTask();  
        /**注册监听事件*/  
        listView.setOnScrollListener(onScrollListener);  
         this._content= context;
    }  
    /** 
     * 在创建View资源对象的时候提供效率的缓存策略 
     */  
    class ViewHold{  
    	 
        public ImageView cover_user_photo;  
    
        public TextView news_title,news_subtitle;  
    }  
    ViewHold hold =null;  
    @Override  
    public View getView(int position, View convertView, ViewGroup parent) {  
      
    
        //判断是否第一次执行convertView,如果是第一次就进行布局资源的创建操作  
          
        if (convertView == null){  
            hold = new ViewHold();  
            //填充加载布局资源  
            convertView = inflater.inflate(R.layout.activity_listview_item, null);  
        	hold.cover_user_photo = (ImageView) convertView
					.findViewById(R.id.news_logo);

			hold.news_title = (TextView) convertView
					.findViewById(R.id.news_title);
			
			String imageUrl =list.get(position).get("news_logo").toString();
		    hold.cover_user_photo.setImageDrawable(imageTask.loadImage(position,imageUrl,imageCallback));
			
		
		
           
            
            //保存标记  
            convertView.setTag(hold);  
        } else {  
            hold = (ViewHold) convertView.getTag();  
        }  
        // 标记图片视图,注意不能放在上面    
        hold.cover_user_photo.setTag(position);
		hold.cover_user_photo.setImageResource(R.drawable.image);
		
        /**获取数据,进行数据填充*/  
		
		hold.news_subtitle = (TextView) convertView
				.findViewById(R.id.news_subtitle);

		hold.news_title.setText(list.get(position).get("news_title")
				.toString());	
		hold.news_subtitle.setText(list.get(position).get("news_subtitle")
				.toString());
       
        
        itemMap.put(position+"", hold);  
        return convertView;  
    } 
    
	
    /** 
     * 屏幕停止滚动监听器 
     */  
      
    AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {    
             
         @Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {    
             if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {  
                 Log.i("--", "--");  
                 int start_index = listView.getFirstVisiblePosition();  
                 int end_index = listView.getLastVisiblePosition();  
                   
                 pageImgLoad(start_index,end_index);  
             }    
                 
         }    
             
         @Override
		public void onScroll(AbsListView view, int firstVisibleItem,    
                 int visibleItemCount, int totalItemCount) {    
             // TODO Auto-generated method stub    
                 
         }    
    };  
       
    /** 
      * 加载当前屏的图片 
      */  
    private void pageImgLoad(int start_index, int end_index) {    
        for (; start_index < end_index; start_index++) {  
            list.get(start_index).get(start_index+"");  
            imageTask.loadImage(start_index,list.get(start_index).get("news_logo").toString(),imageCallback);  
        }    
    }  
      
    /**回调函数*/  
    AsyncImageTask.ImageCallback imageCallback = new ImageCallback(){  
        @Override
		public void imageLoaded(Drawable image, int position) {  
            if (image != null) {    
                //获取刚才标识的组件,并更新     
               ImageView imageView = (ImageView) listView    
                       .findViewWithTag(position);    
               if (imageView != null) {  
                   imageView.setImageDrawable(image);    
               }    
           }  
        }  
    };  
      
    @Override    
    public int getCount() {    
        return list.size();    
    }    
    
    @Override    
    public Object getItem(int position) {  
        return itemMap.get(position+"");    
    }    
    
    @Override    
    public long getItemId(int position) {    
        return position;    
    }  
}  

图片的异步加载 AsyncImageTask.java


package com.imagelistrefresh;

import java.io.IOException;  
import java.io.InputStream;  
import java.lang.ref.SoftReference;  
import java.net.URL;  
import java.util.HashMap;  
import java.util.Map;  
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
  
import android.graphics.drawable.Drawable;  
import android.os.Handler;  
import android.os.Message;  
  
/** 
 * 异步加截图片类 
 * @author Hai Jiang 
 * @Email 672335219@qq.ciom 
 * @Data 2014-2-26 
 */  
public class AsyncImageTask {  
    //开线程池  
    ExecutorService executorService =  Executors.newCachedThreadPool();  
    //缓存图片 把图片的软引用放到map中  
    private Map<String, SoftReference<Drawable>> imageMap;  
    //构造器  
    public AsyncImageTask() {    
            super();    
            this.imageMap = new HashMap<String, SoftReference<Drawable>>();    
        }   
      
    //ID为标记,标记哪条记录image . 这个ID来自于自定义adapter的getView()方法中其中一个参数position  
    public Drawable loadImage(final int id, final String imageUrl,   
            final ImageCallback callback){  
          
        //先看缓存(Map)中是否存在  
        if(imageMap.containsKey(imageUrl)){  
            SoftReference<Drawable> softReference = imageMap.get(imageUrl);  
            if( softReference != null){  
               Drawable draeable = softReference.get();  
               if(draeable!= null){  
                                callback.imageLoaded(draeable, id);  
                return draeable;  
               }  
                }  
        }  
          
        //主线程更新图片  
        final Handler handler = new Handler() {    
                    @Override
					public void handleMessage(Message message) {    
                            callback.imageLoaded((Drawable) message.obj, id);    
                    }    
            };  
        //加载图片的线程  
            executorService.submit(   
        //加载图片的线程  
        new Thread() {    
                @Override
				public void run() {    
                    //加载图片    
                    Drawable drawable = AsyncImageTask.loadImageByUrl(imageUrl);    
                    //加入缓存集合中 注意  这里就要把得到的图片变成软引用放到map中了  
                    imageMap.put(imageUrl, new SoftReference<Drawable>(drawable));    
                    //通知消息主线程更新UI  . 这里就是是否能异步刷新的留意点.  
                    Message message = handler.obtainMessage(0, drawable);    
                    handler.sendMessage(message);    
                }    
            });  
        return null;  
        //到这里就获取图片的静态方法就完了  
    }  
      
    //根据图片地址加载图片,并保存为Drawable  
    //这里不用说了吧.都是一些基本的.从API从可以看  
    public static Drawable loadImageByUrl(String imageUrl){  
        URL url = null;  
        InputStream inputStream = null;  
        try {  
            url = new URL(imageUrl);  
            inputStream = (InputStream) url.getContent();    
            Drawable drawable = Drawable.createFromStream(inputStream,"src");  
            return drawable;  
        } catch (Exception e) {  
            e.printStackTrace();  
        } finally {  
            try {  
                if(inputStream != null)  
                    inputStream.close();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
        }  
        return null;  
    }  
      
    //利用接口回调,更新图片UI    
        public interface ImageCallback {    
            public void imageLoaded(Drawable obj, int id);    
        }   
      
}  

.继承 RelativeLayout 类的PullToRefreshLayout.java

package com.refresh;

import java.util.Timer;
import java.util.TimerTask;

import com.imagelistrefresh.R;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * 更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38868463
 * 
 * @author 陈靖
 */
public class PullToRefreshLayout extends RelativeLayout {
	public static final String TAG = "PullToRefreshLayout";
	// 初始状态
	public static final int INIT = 0;
	// 释放刷新
	public static final int RELEASE_TO_REFRESH = 1;
	// 正在刷新
	public static final int REFRESHING = 2;
	// 操作完毕
	public static final int DONE = 3;
	// 当前状态
	private int state = INIT;
	// 刷新回调接口
	private OnRefreshListener mListener;
	// 刷新成功
	public static final int SUCCEED = 0;
	// 刷新失败
	public static final int FAIL = 1;
	// 按下Y坐标,上一个事件点Y坐标
	private float downY, lastY;

	// 下拉的距离。注意:pullDownY和pullUpY不可能同时不为0
	public float pullDownY = 0;

	// 释放刷新的距离
	private float refreshDist = 200;

	private MyTimer timer;
	// 回滚速度
	public float MOVE_SPEED = 8;
	// 第一次执行布局
	private boolean isLayout = false;
	// 在刷新过程中滑动操作
	private boolean isTouch = false;
	// 手指滑动距离与下拉头的滑动距离比,中间会随正切函数变化
	private float radio = 2;

	// 下拉箭头的转180°动画
	private RotateAnimation rotateAnimation;
	// 均匀旋转动画
	private RotateAnimation refreshingAnimation;

	// 下拉头
	private View refreshView;
	// 下拉的箭头
	private View pullView;
	// 正在刷新的图标
	private View refreshingView;
	// 刷新结果图标
	private View refreshStateImageView;
	// 刷新结果:成功或失败
	private TextView refreshStateTextView;

	// 实现了Pullable接口的View
	private View pullableView;
	
	
	private View cycleHeadView;
	// 过滤多点触碰
	private int mEvents;

	/**
	 * 执行自动回滚的handler
	 */
	Handler updateHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			// 回弹速度随下拉距离moveDeltaY增大而增大
			MOVE_SPEED = (float) (8 + 20 * Math.tan(Math.PI / 2
					/ getMeasuredHeight() * (pullDownY)));
			if (!isTouch) {
				// 正在刷新,且没有往上推的话则悬停,显示"正在刷新..."
				if (state == REFRESHING && pullDownY <= refreshDist) {
					pullDownY = refreshDist;
					timer.cancel();
				}

			}
			if (pullDownY > 0)
				pullDownY -= MOVE_SPEED;
			if (pullDownY <= 0) {
				// 已完成回弹
				pullDownY = 0;
				pullView.clearAnimation();
				// 隐藏下拉头时有可能还在刷新,只有当前状态不是正在刷新时才改变状态
				if (state != REFRESHING)
					changeState(INIT);
				timer.cancel();
			}
			// 刷新布局,会自动调用onLayout
			requestLayout();
		}

	};

	public void setOnRefreshListener(OnRefreshListener listener) {
		mListener = listener;
	}

	public PullToRefreshLayout(Context context) {
		super(context);
		initView(context);
	}

	public PullToRefreshLayout(Context context, AttributeSet attrs) {
		super(context, attrs);
		initView(context);
	}

	public PullToRefreshLayout(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		initView(context);
	}

	private void initView(Context context) {
		timer = new MyTimer(updateHandler);
		rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
				context, R.anim.reverse_anim);
		refreshingAnimation = (RotateAnimation) AnimationUtils.loadAnimation(
				context, R.anim.rotating);
		// 添加匀速转动动画
		LinearInterpolator lir = new LinearInterpolator();
		rotateAnimation.setInterpolator(lir);
		refreshingAnimation.setInterpolator(lir);
	}

	private void hide() {
		timer.schedule(5);
	}

	/**
	 * 完成刷新操作,显示刷新结果。注意:刷新完成后一定要调用这个方法
	 */
	/**
	 * @param refreshResult
	 *            PullToRefreshLayout.SUCCEED代表成功,PullToRefreshLayout.FAIL代表失败
	 */
	public void refreshFinish(int refreshResult) {
		refreshingView.clearAnimation();
		refreshingView.setVisibility(View.GONE);
		switch (refreshResult) {
		case SUCCEED:
			// 刷新成功
			refreshStateImageView.setVisibility(View.VISIBLE);
			refreshStateTextView.setText(R.string.refresh_succeed);
			refreshStateImageView
					.setBackgroundResource(R.drawable.refresh_succeed);
			break;
		case FAIL:
		default:
			// 刷新失败
			refreshStateImageView.setVisibility(View.VISIBLE);
			refreshStateTextView.setText(R.string.refresh_fail);
			refreshStateImageView
					.setBackgroundResource(R.drawable.refresh_failed);
			break;
		}
		// 刷新结果停留1秒
		new Handler() {
			@Override
			public void handleMessage(Message msg) {
				changeState(DONE);
				if (!isTouch) {
					hide();
				}
			}
		}.sendEmptyMessageDelayed(0, 1000);
	}

	private void changeState(int to) {
		state = to;
		switch (state) {
		case INIT:
			// 下拉布局初始状态
			refreshStateImageView.setVisibility(View.GONE);
			refreshStateTextView.setText(R.string.pull_to_refresh);
			pullView.startAnimation(AnimationUtils
					.loadAnimation(getContext(), R.anim.reverse_anim2));
			pullView.setVisibility(View.VISIBLE);
			break;
		case RELEASE_TO_REFRESH:
			// 释放刷新状态
			refreshStateTextView.setText(R.string.release_to_refresh);
			pullView.startAnimation(rotateAnimation);
			break;
		case REFRESHING:
			// 正在刷新状态
			pullView.clearAnimation();
			refreshingView.setVisibility(View.VISIBLE);
			pullView.setVisibility(View.INVISIBLE);
			refreshingView.startAnimation(refreshingAnimation);
			refreshStateTextView.setText(R.string.refreshing);
			break;
		case DONE:
			// 刷新完毕,啥都不做
			break;
		}
	}

	/*
	 * (非 Javadoc)由父控件决定是否分发事件,防止事件冲突
	 * 
	 * @see android.view.ViewGroup#dispatchTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		switch (ev.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
			downY = ev.getY();
			lastY = downY;
			timer.cancel();
			mEvents = 0;
			break;
		case MotionEvent.ACTION_POINTER_DOWN:
		case MotionEvent.ACTION_POINTER_UP:
			// 过滤多点触碰
			mEvents = -1;
			break;
		case MotionEvent.ACTION_MOVE:
			if (mEvents == 0) {
				if (((Pullable) pullableView).canPullDown()) {
					// 可以下拉,正在加载时不能下拉
					// 对实际滑动距离做缩小,造成用力拉的感觉
					pullDownY = pullDownY + (ev.getY() - lastY) / radio;
					if (ev.getY() - lastY < 0) {
						pullDownY = pullDownY + (ev.getY() - lastY);
					}
					if (pullDownY < 0) {
						pullDownY = 0;
					}
					if (pullDownY > getMeasuredHeight())
						pullDownY = getMeasuredHeight();
					if (state == REFRESHING) {
						// 正在刷新的时候触摸移动
						isTouch = true;
					}
				}
			} else
				mEvents = 0;
			lastY = ev.getY();
			// 根据下拉距离改变比例
			radio = (float) (2 + 3 * Math.tan(Math.PI / 2 / getMeasuredHeight()
					* (pullDownY)));
			requestLayout();
			if (pullDownY <= refreshDist && (state == RELEASE_TO_REFRESH || state == DONE)) {
				// 如果下拉距离没达到刷新的距离且当前状态是释放刷新,改变状态为下拉刷新
				changeState(INIT);
			}
			if (pullDownY >= refreshDist && state == INIT) {
				// 如果下拉距离达到刷新的距离且当前状态是初始状态刷新,改变状态为释放刷新
				changeState(RELEASE_TO_REFRESH);
			}
			// 因为刷新和加载操作不能同时进行,所以pullDownY和pullUpY不会同时不为0,因此这里用(pullDownY +
			// Math.abs(pullUpY))就可以不对当前状态作区分了
			if ((pullDownY) > 8) {
				// 防止下拉过程中误触发长按事件和点击事件
				ev.setAction(MotionEvent.ACTION_CANCEL);
			}
			break;
		case MotionEvent.ACTION_UP:
			if (pullDownY > refreshDist)
				// 正在刷新时往下拉(正在加载时往上拉),释放后下拉头(上拉头)不隐藏
				isTouch = false;
			if (state == RELEASE_TO_REFRESH) {
				changeState(REFRESHING);
				// 刷新操作
				if (mListener != null)
					mListener.onRefresh(this);
			}
			hide();
		default:
			break;
		}
		// 事件分发交给父类
		super.dispatchTouchEvent(ev);
		return true;
	}

	private void initView() {
		// 初始化下拉布局
		pullView = refreshView.findViewById(R.id.pull_icon);
		refreshStateTextView = (TextView) refreshView
				.findViewById(R.id.state_tv);
		refreshingView = refreshView.findViewById(R.id.refreshing_icon);
		refreshStateImageView = refreshView.findViewById(R.id.state_iv);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		if (!isLayout) {
			// 这里是第一次进来的时候做一些初始化
			refreshView = getChildAt(0);
			cycleHeadView = getChildAt(1);
			// 这里是第一次进来的时候做一些初始化 1
			pullableView = getChildAt(2);
			isLayout = true;
			initView();
			refreshDist = ((ViewGroup) refreshView).getChildAt(0)
					.getMeasuredHeight();
		}
		// 改变子控件的布局,这里直接用(pullDownY + pullUpY)作为偏移量,这样就可以不对当前状态作区分
		refreshView.layout(0,(int) (pullDownY) - refreshView.getMeasuredHeight(),refreshView.getMeasuredWidth(), (int) (pullDownY));
		cycleHeadView.layout(0, (int) (pullDownY),cycleHeadView.getMeasuredWidth(), (int) (pullDownY)+ cycleHeadView.getMeasuredHeight());
		pullableView.layout(0, (int) (pullDownY+cycleHeadView.getMeasuredHeight()),pullableView.getMeasuredWidth(), (int) (pullDownY)+ pullableView.getMeasuredHeight()+cycleHeadView.getMeasuredHeight());
	}

	class MyTimer {
		private Handler handler;
		private Timer timer;
		private MyTask mTask;

		public MyTimer(Handler handler) {
			this.handler = handler;
			timer = new Timer();
		}

		public void schedule(long period) {
			if (mTask != null) {
				mTask.cancel();
				mTask = null;
			}
			mTask = new MyTask(handler);
			timer.schedule(mTask, 0, period);
		}

		public void cancel() {
			if (mTask != null) {
				mTask.cancel();
				mTask = null;
			}
		}

		class MyTask extends TimerTask {
			private Handler handler;

			public MyTask(Handler handler) {
				this.handler = handler;
			}

			@Override
			public void run() {
				handler.obtainMessage().sendToTarget();
			}

		}
	}

	/**
	 * 刷新加载回调接口
	 * 
	 * @author chenjing
	 * 
	 */
	public interface OnRefreshListener {
		/**
		 * 刷新操作
		 */
		void onRefresh(PullToRefreshLayout pullToRefreshLayout);
	}
}


Pullable.java 回调方法接口:

package com.refresh;

public interface Pullable
{
	/**
	 * 判断是否可以下拉,如果不需要下拉功能可以直接return false
	 * 
	 * @return true如果可以下拉否则返回false
	 */
	boolean canPullDown();
	boolean canPullUp();
}

PullableListView.java

package com.refresh;

import com.imagelistrefresh.R;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;



/**
 * 如果不需要下拉刷新直接在canPullDown中返回false,这里的自动加载和下拉刷新没有冲突,通过增加在尾部的footerview实现自动加载,
 * 所以在使用中不要再动footerview了
 * 更多详解见博客http://blog.csdn.net/zhongkejingwang/article/details/38963177
 * @author chenjing
 * 
 */
public class PullableListView extends ListView implements Pullable
{
	public static final int INIT = 0;
	public static final int LOADING = 1;
	public static final int NO_MORE_DATA = 2;
	private OnLoadListener mOnLoadListener;
	private View mLoadmoreView;
	private ImageView mLoadingView;
	private TextView mStateTextView;
	private int state = INIT;
	private boolean canLoad = true;
	private boolean autoLoad = true;
	private boolean hasMoreData = true;
	private AnimationDrawable mLoadAnim;

	public PullableListView(Context context)
	{
		super(context);
		init(context);
	}

	public PullableListView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
		init(context);
	}

	public PullableListView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context)
	{
		mLoadmoreView = LayoutInflater.from(context).inflate(R.layout.load_more,
				null);
		mLoadingView = (ImageView) mLoadmoreView.findViewById(R.id.loading_icon);
		mLoadingView.setBackgroundResource(R.anim.loading_anim);
		mLoadAnim = (AnimationDrawable) mLoadingView.getBackground();
		mStateTextView = (TextView) mLoadmoreView.findViewById(R.id.loadstate_tv);
		mLoadmoreView.setOnClickListener(new OnClickListener()
		{
			
			@Override
			public void onClick(View v)
			{
				//点击加载
				if(state != LOADING && hasMoreData){
					load();
				}
			}
		});
		addFooterView(mLoadmoreView, null, false);
	}
	
	/**
	 * 是否开启自动加载
	 * @param enable true启用,false禁用
	 */
	public void enableAutoLoad(boolean enable){
		autoLoad = enable;
	}
	
	/**
	 * 是否显示加载更多
	 * @param v true显示,false不显示
	 */
	public void setLoadmoreVisible(boolean v){
		if(v)
			{
			if (getFooterViewsCount() == 0) {
				addFooterView(mLoadmoreView, null, false);
			}
			}
		else {
			removeFooterView(mLoadmoreView);
		}
	}

	@Override
	public boolean onTouchEvent(MotionEvent ev)
	{
		switch (ev.getActionMasked())
		{
		case MotionEvent.ACTION_DOWN:
			// 按下的时候禁止自动加载
			canLoad = false;
			break;
		case MotionEvent.ACTION_UP:
			// 松开手判断是否自动加载
			canLoad = true;
			checkLoad();
			break;
		}
		return super.onTouchEvent(ev);
	}

	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt)
	{
		super.onScrollChanged(l, t, oldl, oldt);
		// 在滚动中判断是否满足自动加载条件
		checkLoad();
	}

	/**
	 * 判断是否满足自动加载条件
	 */
	private void checkLoad()
	{
		if (reachBottom() && mOnLoadListener != null && state != LOADING
				&& canLoad && autoLoad && hasMoreData)
			load();
	}
	
	private void load(){
		changeState(LOADING);
		mOnLoadListener.onLoad(this);
	}

	private void changeState(int state)
	{
		this.state = state;
		switch (state)
		{
		case INIT:
			mLoadAnim.stop();
			mLoadingView.setVisibility(View.INVISIBLE);
			mStateTextView.setText(R.string.more);
			break;

		case LOADING:
			mLoadingView.setVisibility(View.VISIBLE);
			mLoadAnim.start();
			mStateTextView.setText(R.string.loading);
			break;
			
		case NO_MORE_DATA:
			mLoadAnim.stop();
			mLoadingView.setVisibility(View.INVISIBLE);
			mStateTextView.setText("没有更多的数据了");
			break;
		}
	}

	/**
	 * 完成加载
	 */
	public void finishLoading()
	{
		changeState(INIT);
	}

	@Override
	public boolean canPullDown()
	{
		if (getCount() == 0)
		{
			// 没有item的时候也可以下拉刷新
			return true;
		} else if (getFirstVisiblePosition() == 0
				&& getChildAt(0).getTop() >= 0)
		{
			// 滑到ListView的顶部了
			return true;
		} else
			return false;
	}

	public void setOnLoadListener(OnLoadListener listener)
	{
		this.mOnLoadListener = listener;
	}

	/**
	 * @return footerview可见时返回true,否则返回false
	 */
	private boolean reachBottom()
	{
		if (getCount() == 0)
		{
			return true;
		} else if (getLastVisiblePosition() == (getCount() - 1))
		{
			// 滑到底部,且頂部不是第0个,也就是说item数超过一屏后才能自动加载,否则只能点击加载
			if (getChildAt(getLastVisiblePosition() - getFirstVisiblePosition()) != null
					&& getChildAt(
							getLastVisiblePosition()
									- getFirstVisiblePosition()).getTop() < getMeasuredHeight() && !canPullDown())
				return true;
		}
		return false;
	}

	public boolean isHasMoreData() {
		return hasMoreData;
	}

	public void setHasMoreData(boolean hasMoreData) {
		this.hasMoreData = hasMoreData;
		if (!hasMoreData) {
			changeState(NO_MORE_DATA);
		}else{
			changeState(INIT);
		}
	}

	public interface OnLoadListener
	{
		void onLoad(PullableListView pullableListView);
	}

	@Override
	public boolean canPullUp() {
		// TODO Auto-generated method stub
		return false;
	}
}

PullableWebView.java

package com.refresh;

import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;

public class PullableWebView extends WebView implements Pullable
{

	public PullableWebView(Context context)
	{
		super(context);
	}

	public PullableWebView(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}

	public PullableWebView(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
	}

	@Override
	public boolean canPullDown()
	{
		if (getScrollY() == 0)
			return true;
		else
			return false;
	}

	@Override
	public boolean canPullUp() {
		// TODO Auto-generated method stub
		return false;
	}
}

下载地址:http://download.csdn.net/detail/ywenboy/9647977

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

StephenYangKing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值