开源地址: https://github.com/chrisbanes/Android-PullToRefresh
简介:PullToRefresh是一款支持ListView,GridView,ViewPager,ScrollView,WebView等一切可以拖动,并实现上下左右拖动刷新数据的框架,废话不多说,上代码;
[基本的android依赖项目存放在library中,支持fragment列表,ViewPager列表的存放在extras包中]
[依赖项目导入如左图]
1.支持ListView的实现:
1)XML实现
<RelativeLayout 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" > <com.handmark.pulltorefresh.library.PullToRefreshListView android:id="@+id/my_ptr_lv" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#0000" android:divider="#0FF" android:dividerHeight="1dp" android:smoothScrollbar="true" android:fastScrollEnabled="false" android:footerDividersEnabled="false" android:headerDividersEnabled="false" /> </RelativeLayout>
2)JAVA代码
public class PullListSampleActivity extends Activity { private PullToRefreshListView mPullToRefreshLv; private ArrayAdapter<String> mAdapter; private LinkedList<String> mListItems; private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", "Allgauer Emmentaler", "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", "Allgauer Emmentaler" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pull_list_sample); //填充数据 mPullToRefreshLv=(PullToRefreshListView) findViewById(R.id.my_ptr_lv); mListItems=new LinkedList<String>(Arrays.asList(mStrings)); mAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,android.R.id.text1,mListItems); mPullToRefreshLv.setAdapter(mAdapter); //下拉刷新的声音支持 SoundPullEventListener<ListView> soundPullEventListener=new SoundPullEventListener<ListView>(this); soundPullEventListener.addSoundEvent(State.PULL_TO_REFRESH, R.raw.pull_event); soundPullEventListener.addSoundEvent(State.REFRESHING, R.raw.refreshing_sound); soundPullEventListener.addSoundEvent(State.RESET, R.raw.reset_sound); mPullToRefreshLv.setOnPullEventListener(soundPullEventListener); //刷新时调用的监听器 mPullToRefreshLv.setOnRefreshListener(new OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> refreshView) { String label=DateUtils.formatDateTime(PullListSampleActivity.this, System.currentTimeMillis(), DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_ABBREV_ALL); //设置头部Label mPullToRefreshLv.getLoadingLayoutProxy().setLastUpdatedLabel(label); new GetListDataTask().execute(); } }); mPullToRefreshLv.setOnLastItemVisibleListener(new OnLastItemVisibleListener() { @Override public void onLastItemVisible() { Toast.makeText(PullListSampleActivity.this,"all data loaded !", 800).show(); } }); } class GetListDataTask extends AsyncTask<Void, Void, String[]>{ @Override protected String[] doInBackground(Void... params) { //mock get datas try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } return mStrings; } @Override protected void onPostExecute(String[] result) { mListItems.addAll(Arrays.asList(result)); mAdapter.notifyDataSetChanged(); //手动关闭头部 mPullToRefreshLv.onRefreshComplete(); super.onPostExecute(result); } } }
1)XML实现
ptr:ptrMode="both"表示上下/左右都可以刷新
ptr:ptrDrawable表示刷新时显示的图标
<RelativeLayout 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" > <com.handmark.pulltorefresh.library.PullToRefreshGridView xmlns:ptr="http://schemas.android.com/apk/res-auto" android:id="@+id/my_ptr_gv" android:layout_width="match_parent" android:layout_height="match_parent" android:cacheColorHint="#0000" android:divider="#0FF" android:dividerHeight="1dp" android:smoothScrollbar="true" android:fastScrollEnabled="false" android:footerDividersEnabled="false" android:headerDividersEnabled="false" android:numColumns="auto_fit" ptr:ptrMode="both" ptr:ptrDrawable="@drawable/default_ptr_rotate" /> </RelativeLayout>
public class PullGridSampleActivity extends Activity { private PullToRefreshGridView mPullToRefreshGridView; private ArrayAdapter<String> mAdapter; private LinkedList<String> mListItems; private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", "Allgauer Emmentaler" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pull_grid_sample); mPullToRefreshGridView=(PullToRefreshGridView) findViewById(R.id.my_ptr_gv); mListItems=new LinkedList<String>(); mAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, android.R.id.text1,mListItems); mPullToRefreshGridView.setAdapter(mAdapter); //支持当没有数据的时候替代的View 具体代码根据自己的业务 TextView textView=new TextView(this); LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); params.gravity=Gravity.CENTER; textView.setLayoutParams(params); textView.setText("The data is empty !"); mPullToRefreshGridView.setEmptyView(textView); SoundPullEventListener<GridView> pullEventListener=new SoundPullEventListener<GridView>(this); pullEventListener.addSoundEvent(State.PULL_TO_REFRESH,R.raw.pull_event); pullEventListener.addSoundEvent(State.RESET,R.raw.reset_sound); pullEventListener.addSoundEvent(State.REFRESHING,R.raw.refreshing_sound); mPullToRefreshGridView.setOnPullEventListener(pullEventListener); mPullToRefreshGridView.setOnRefreshListener(new OnRefreshListener2<GridView>() { @Override public void onPullDownToRefresh( PullToRefreshBase<GridView> refreshView) { String label=DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),DateUtils.FORMAT_24HOUR); refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label); new GetDataTask().execute(); } @Override public void onPullUpToRefresh( PullToRefreshBase<GridView> refreshView) { String label=DateUtils.formatDateTime(getApplicationContext(), System.currentTimeMillis(),DateUtils.FORMAT_24HOUR); refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(label); new GetDataTask().execute(); } }); } class GetDataTask extends AsyncTask<Void, Void, String[]>{ @Override protected String[] doInBackground(Void... params) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return mStrings; } @Override protected void onPostExecute(String[] result) { mListItems.addAll(Arrays.asList(result)); mAdapter.notifyDataSetChanged(); mPullToRefreshGridView.onRefreshComplete(); } } }
3.对ViewPager的实现
1)XML
<RelativeLayout 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" > <com.handmark.pulltorefresh.extras.viewpager.PullToRefreshViewPager xmlns:ptr="http://schemas.android.com/apk/res-auto" android:id="@+id/my_ptr_viewpager" android:layout_width="match_parent" android:layout_height="match_parent" ptr:ptrAnimationStyle="flip" ptr:ptrMode="both" ptr:ptrHeaderBackground="#FFFF" /> </RelativeLayout>
public class PullViewPagerSample extends Activity implements OnRefreshListener<ViewPager>{ private PullToRefreshViewPager mPullToRefreshViewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_pull_viewpager_sample); mPullToRefreshViewPager=(PullToRefreshViewPager) findViewById(R.id.my_ptr_viewpager); mPullToRefreshViewPager.getRefreshableView().setAdapter(new MyPagerAdapter()); mPullToRefreshViewPager.setOnRefreshListener(this); } class MyPagerAdapter extends PagerAdapter{ private final int[] sDrawables = { R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper, R.drawable.wallpaper }; @Override public int getCount() { return sDrawables.length; } @Override public Object instantiateItem(ViewGroup container, int position) { ImageView imageView=new ImageView(container.getContext()); imageView.setImageResource(sDrawables[position]); container.addView(imageView,LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT); return imageView; } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0==(View)arg1; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } @Override public void onRefresh(PullToRefreshBase<ViewPager> refreshView) { try { Thread.sleep(4000);//模拟加载时间 } catch (InterruptedException e) { e.printStackTrace(); } mPullToRefreshViewPager.onRefreshComplete(); } }