本人叙述能力不好,且所学不精。如看不懂本人所述,本文章中会有案例,如案例也看不懂。对不起,本人心有余而力不足啊。
首先导入: compile 'com.github.userswlwork:pull-to-refresh:1.0.0' 依赖
在xml文件中写入控件。之后就可以在MainActivity中写需要的配置等等了。
找到在xml中写的控件。
设置用户进入应用时显示的初始数据。(个人习惯封装成一个方法)
之后设置上拉加载及下拉刷新
刷新方法: ?.setOnRefreshListener
加载方法: ?.setOnLastItemVisibleListener
下拉刷新的方法中需要先清空数据。 ?.clear();
之后重新初始化数据。
最后刷新适配器。 ?.notifyDataSetChanged();
上拉加载的方法中需要接口地址后缀++递增1,使得数据加载更多。
再调用上拉加载的方法,刷新适配器。最后停止加载即可。
好了,案例如下:
---------------------------activity_main---------------------------------
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.com.myapplication.MainActivity"> <com.handmark.pulltorefresh.library.PullToRefreshListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/pulltorefresh"/> </RelativeLayout>
---------------------------MainActivity-----------------------------
package com.example.com.myapplication; import android.annotation.SuppressLint; import android.os.AsyncTask; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.ListView; import com.google.gson.Gson; import com.handmark.pulltorefresh.library.PullToRefreshBase; import com.handmark.pulltorefresh.library.PullToRefreshListView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private PullToRefreshListView pulltorefresh; String json_url = "http://api.expoon.com/AppNews/getNewsList/type/1/p/";//接口地址可自己找 private ArrayList<String> list = new ArrayList<>(); int page = 1; private MyAdapter adapter; private List<Bean.DataBean> data = new ArrayList<>();//原数据集合 private List<Bean.DataBean> datas = new ArrayList<>();//加载新增数据集合 private Handler handler = new Handler(){}; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); pulltorefresh = findViewById(R.id.pulltorefresh); MyTasks(); //------------------------------刷新 pulltorefresh.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() { @Override public void onRefresh(PullToRefreshBase<ListView> pullToRefreshBase) { handler.postDelayed(new Runnable() { @Override public void run() { //此方法为停止刷新------延时1000毫秒(即1秒) pulltorefresh.onRefreshComplete(); } },1000); //清空数据 list.clear(); //初始化数据 MyTasks(); //刷新数据 adapter.notifyDataSetChanged(); } }); //---------------------------------------加载 pulltorefresh.setOnLastItemVisibleListener(new PullToRefreshBase.OnLastItemVisibleListener() { @Override public void onLastItemVisible() { //地址后缀递增1,使数据增加 page++; //调用上拉加载的方法 MyTask(); //适配器刷新 adapter.notifyDataSetChanged(); //停止加载 pulltorefresh.onRefreshComplete(); } }); } //下拉刷新的方法 @SuppressLint("StaticFieldLeak") private void MyTasks() { new AsyncTask<String,Integer,String>(){ @Override protected String doInBackground(String... strings) { //得到数据地址并得到数据 Utils utils = new Utils(); String jsonData = utils.getJsonData(json_url+page); return jsonData; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); //GSON解析数据 Gson gson = new Gson(); Bean bean = gson.fromJson(s, Bean.class); //初始显示的数据 data = bean.getData(); adapter = new MyAdapter(MainActivity.this, data); //设置适配器 pulltorefresh.setAdapter(adapter); } }.execute(); } //上拉加载的方法 @SuppressLint("StaticFieldLeak") private void MyTask() { new AsyncTask<String,Integer,String>(){ @Override protected String doInBackground(String... strings) { //得到数据地址并得到数据 Utils utils = new Utils(); String jsonData = utils.getJsonData(json_url+page); return jsonData; } @Override protected void onPostExecute(String s) { super.onPostExecute(s); //GSON解析数据 Gson gson = new Gson(); Bean bean = gson.fromJson(s, Bean.class); datas = bean.getData(); //将解析的新数据接到旧数据后 data.addAll(datas); //刷新数据 adapter.notifyDataSetChanged(); } }.execute(); } } ------------------------------Utils-------------------------------
package com.example.com.myapplication; import android.util.Log; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; public class Utils { public String getJsonData(String jsonurl){ String jsonstr = ""; try { URL url = new URL(jsonurl); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); int responseCode = urlConnection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = urlConnection.getInputStream(); byte[] b = new byte[1024]; int len = 0; while ((len = inputStream.read(b))!=-1){ String s = new String(b, 0, len); jsonstr+=s; } Log.d("Main",jsonstr); } } catch (Exception e) { e.printStackTrace(); } return jsonstr; } }
------------------------------ MyAdapter--------------------------
package com.example.com.myapplication; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.nostra13.universalimageloader.core.ImageLoader; import java.util.List; public class MyAdapter extends BaseAdapter { private Context context; private List<Bean.DataBean> list; public MyAdapter(Context context, List<Bean.DataBean> list) { this.context = context; this.list = list; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int i) { return list.get(i); } @Override public long getItemId(int i) { return i; } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder holder; if (view == null){ view = View.inflate(context,R.layout.item_layout,null); holder = new ViewHolder(); holder.image = view.findViewById(R.id.news_image); holder.news_summary = view.findViewById(R.id.summary); holder.news_title = view.findViewById(R.id.title); view.setTag(holder); }else { holder = (ViewHolder) view.getTag(); } holder.news_title.setText(list.get(i).getNews_title()); holder.news_summary.setText(list.get(i).getNews_summary()); ImageLoader.getInstance().displayImage(list.get(i).getPic_url(),holder.image); return view; } class ViewHolder{ ImageView image; TextView news_title,news_summary; } }----------------------------MyApplicaton----------------------------
package com.example.com.myapplication; import android.app.Application; import android.graphics.Bitmap; import android.os.Environment; import com.nostra13.universalimageloader.cache.disc.impl.UnlimitedDiscCache; import com.nostra13.universalimageloader.cache.disc.naming.HashCodeFileNameGenerator; import com.nostra13.universalimageloader.cache.memory.impl.LruMemoryCache; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.ImageLoader; import com.nostra13.universalimageloader.core.ImageLoaderConfiguration; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.assist.QueueProcessingType; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import java.io.File; public class MaApplicaton extends Application { File cacheFile= new File(Environment.getExternalStorageDirectory()+"/"+"imgages"); @Override public void onCreate() { super.onCreate(); //初始化组件,链式开发思想,整个框架的参数初始化配置 ImageLoaderConfiguration configuration = new ImageLoaderConfiguration.Builder(this) .memoryCacheExtraOptions(480, 800) // default = device screen dimensions 内存缓存文件的最大长宽 .diskCacheExtraOptions(480, 800, null) // 本地缓存的详细信息(缓存的最大长宽),最好不要设置这个 .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现 .memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值 .memoryCacheSizePercentage(13) // default .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值 .diskCacheFileCount(100) // 可以缓存的文件数量 .diskCache(new UnlimitedDiscCache(cacheFile))//自定义缓存目录 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() // 打印debug log .build(); ImageLoader.getInstance().init(configuration); } public class ImageLoaderUtils_circle { public DisplayImageOptions getDisplayImageOption() { DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.mipmap.ic_launcher) //设置图片在下载期间显示的图片 .showImageForEmptyUri(R.mipmap.ic_launcher)//设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.mipmap.ic_launcher) //设置图片加载/解码过程中错误时候显示的图片 .cacheInMemory(true)//设置下载的图片是否缓存在内存中 .cacheOnDisk(true) .considerExifParams(true) //是否考虑JPEG图像EXIF参数(旋转,翻转) .imageScaleType(ImageScaleType.EXACTLY_STRETCHED)//设置图片以如何的编码方式显示 .bitmapConfig(Bitmap.Config.RGB_565)//设置图片的解码类型// .displayer(new RoundedBitmapDisplayer(5))//是否设置为圆角,弧度为多少 // .displayer(new FadeInBitmapDisplayer(100))//是否图片加载好后渐入的动画时间 .build();//构建完成 return options; } } }-------------------------------item_layout.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="match_parent"> <TextView android:layout_width="350dp" android:text="title" android:layout_height="wrap_content" android:id="@+id/title"/> <TextView android:id="@+id/summary" android:layout_width="350dp" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_below="@+id/title" android:text="summary" /> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/ic_launcher" android:layout_alignParentRight="true" android:id="@+id/news_image"/> </RelativeLayout>--------------------------------Bean---------------------------------
package com.example.com.myapplication; import java.util.List; /** * Created by hp on 2018.01.11. */ public class Bean { private int status; private String info; private List<DataBean> data; public int getStatus() { return status; } public void setStatus(int status) { this.status = status; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } public List<DataBean> getData() { return data; } public void setData(List<DataBean> data) { this.data = data; } public static class DataBean { /** * news_id : 13811 * news_title : 深港澳台千里连线,嘉年华会今夏入川 * news_summary : 6月17—20日,“2016成都深港澳台嘉年华会”(简称嘉年华会)将在成都世纪城国际会展中心举办。其主办方励展华博借力旗 * pic_url : http://f.expoon.com/sub/news/2016/01/21/887844_230x162_0.jpg */ private String news_id; private String news_title; private String news_summary; private String pic_url; public String getNews_id() { return news_id; } public void setNews_id(String news_id) { this.news_id = news_id; } public String getNews_title() { return news_title; } public void setNews_title(String news_title) { this.news_title = news_title; } public String getNews_summary() { return news_summary; } public void setNews_summary(String news_summary) { this.news_summary = news_summary; } public String getPic_url() { return pic_url; } public void setPic_url(String pic_url) { this.pic_url = pic_url; } } }