一. MAinActivity.java
package com.LianXi; import android.support.v4.app.FragmentActivity; import android.support.v4.widget.DrawerLayout; import android.os.Bundle; import android.view.View; import android.widget.LinearLayout; import com.fragment.DongFragment; import com.fragment.GuanZhu_Fragment; import com.fragment.NewsFragment; import com.fragment.SetFragment; public class MainActivity extends FragmentActivity implements View.OnClickListener{ private DrawerLayout drawerlayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //抽屉,即侧滑菜单的布局 drawerlayout = (DrawerLayout) findViewById(R.id.drawer_layout); //抽屉显示的布局 LinearLayout linearLayout = findViewById(R.id.linearLayout); //菜单选项布局 LinearLayout linear_01 = findViewById(R.id.linear_01); LinearLayout linear_02 = findViewById(R.id.linear_02); LinearLayout linear_03 = findViewById(R.id.linear_03); LinearLayout linear_04 = findViewById(R.id.linear_04); //要有一个fragment替换后面主内容的frameLayout NewsFragment newsFragment = new NewsFragment(); //主内容区域Framelayout布局先用一个Fragment布局占位 getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, newsFragment).commit(); //菜单的点击事件 linear_01.setOnClickListener(this); linear_02.setOnClickListener(this); linear_03.setOnClickListener(this); linear_04.setOnClickListener(this); } //判断点击 的布局 @Override public void onClick(View view) { switch (view.getId()){ //获取第一页的新闻数据 case R.id.linear_01: GuanZhu_Fragment guanZhu_fragment = new GuanZhu_Fragment(); //主内容区域Framelayout布局先用一个Fragment布局占位 getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, guanZhu_fragment).commit(); drawerlayout.closeDrawers(); break; //获取第2页的数据 case R.id.linear_02: DongFragment dongFragment = new DongFragment(); //主内容区域Framelayout布局用一个Fragment布局占位 getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, dongFragment).commit(); drawerlayout.closeDrawers(); break; //获取第3页的数据 case R.id.linear_03: NewsFragment newsFragment = new NewsFragment(); //主内容区域Framelayout布局用一个Fragment布局占位 getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, newsFragment).commit(); drawerlayout.closeDrawers(); break; //获取第4页的数据 case R.id.linear_04: SetFragment setFragment = new SetFragment(); //主内容区域Framelayout布局用一个Fragment布局占位 getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout, setFragment).commit(); drawerlayout.closeDrawers(); break; } } }
二. 自定义适配器类
package com.adapter; 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.LianXi.R; import com.bean.NewsBean; import com.nostra13.universalimageloader.core.ImageLoader; import com.util.ImageLoaderUtil; import java.util.List; public class XListViewAdapter extends BaseAdapter{ private Context context; private List<NewsBean.DataBean> list; public XListViewAdapter(Context context, List<NewsBean.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,null); holder = new ViewHolder(); //查找控件 holder.text = view.findViewById(R.id.text); holder.image = view.findViewById(R.id.image); //绑定数据 view.setTag(holder); }else { //解绑 holder = (ViewHolder) view.getTag(); } //获取数据重新赋值 holder.text.setText(list.get(i).getNews_title()); ImageLoader.getInstance().displayImage(list.get(i).getPic_url(),holder.image, ImageLoaderUtil.getDefaultOption()); return view; } static class ViewHolder{ TextView text; ImageView image; } }
三. 自定义bean类(导入Gson包)
四. 自定义fragment类
package com.fragment; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.LianXi.R; import com.adapter.XListViewAdapter; import com.bean.NewsBean; import com.google.gson.Gson; import com.util.StringUtil; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import view.XListView; public class NewsFragment extends Fragment implements XListView.IXListViewListener{ private List<NewsBean.DataBean> list = new ArrayList<>(); private XListViewAdapter adapter; private XListView xListView; private int num = 1; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.news_layout, container, false); //查找控件 xListView = view.findViewById(R.id.xListView); //设置XListView的上拉刷新功能 xListView.setPullLoadEnable(true); xListView.setPullRefreshEnable(true); //XListView的监听事件 xListView.setXListViewListener(this); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //获取刷新的数据 getDataFromNet(); } //网络获取刷新的数据 private void getDataFromNet() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/3/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(0,newsBean.getData()); //设置适配器 setAdapter(); //停止刷新数据 xListView.stopRefresh(); //设置刷新的时间 Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("HH:mm"); xListView.setRefreshTime(format.format(date)); } }; task.execute(); } private void setAdapter() { if (adapter == null){ adapter = new XListViewAdapter(getActivity(), list); xListView.setAdapter(adapter); }else { adapter.notifyDataSetChanged(); } } //下拉刷新 @Override public void onRefresh() { num++; getDataFromNet(); //加载到数据之后停止 } @Override public void onLoadMore() { num++; getData(); //加载到数据之后停止 } //网络获取刷新的数据 private void getData() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/1/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(newsBean.getData()); //设置适配器 setAdapter(); //停止加载数据 xListView.stopLoadMore(); } }; task.execute(); } }
package com.fragment; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.LianXi.R; import com.adapter.XListViewAdapter; import com.bean.NewsBean; import com.google.gson.Gson; import com.util.StringUtil; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import view.XListView; public class GuanZhu_Fragment extends Fragment implements XListView.IXListViewListener{ private List<NewsBean.DataBean> list = new ArrayList<>(); private XListViewAdapter adapter; private XListView xListView; private int num = 1; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.news_layout, container, false); //查找控件 xListView = view.findViewById(R.id.xListView); //设置XListView的上拉刷新功能 xListView.setPullLoadEnable(true); xListView.setPullRefreshEnable(true); //XListView的监听事件 xListView.setXListViewListener(this); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //获取刷新的数据 getDataFromNet(); } //网络获取刷新的数据 private void getDataFromNet() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/2/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(0,newsBean.getData()); //设置适配器 setAdapter(); //停止刷新数据 xListView.stopRefresh(); //设置刷新的时间 Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("HH:mm"); xListView.setRefreshTime(format.format(date)); } }; task.execute(); } private void setAdapter() { if (adapter == null){ adapter = new XListViewAdapter(getActivity(), list); xListView.setAdapter(adapter); }else { adapter.notifyDataSetChanged(); } } //下拉刷新 @Override public void onRefresh() { num++; getDataFromNet(); //加载到数据之后停止 } @Override public void onLoadMore() { num++; getData(); //加载到数据之后停止 } //网络获取刷新的数据 private void getData() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/1/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(newsBean.getData()); //设置适配器 setAdapter(); //停止加载数据 xListView.stopLoadMore(); } }; task.execute(); } }
package com.fragment; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.LianXi.R; import com.adapter.XListViewAdapter; import com.bean.NewsBean; import com.google.gson.Gson; import com.util.StringUtil; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import view.XListView; public class DongFragment extends Fragment implements XListView.IXListViewListener{ private List<NewsBean.DataBean> list = new ArrayList<>(); private XListViewAdapter adapter; private XListView xListView; private int num = 1; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.news_layout, container, false); //查找控件 xListView = view.findViewById(R.id.xListView); //设置XListView的上拉刷新功能 xListView.setPullLoadEnable(true); xListView.setPullRefreshEnable(true); //XListView的监听事件 xListView.setXListViewListener(this); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //获取刷新的数据 getDataFromNet(); } //网络获取刷新的数据 private void getDataFromNet() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/3/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(0,newsBean.getData()); //设置适配器 setAdapter(); //停止刷新数据 xListView.stopRefresh(); //设置刷新的时间 Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("HH:mm"); xListView.setRefreshTime(format.format(date)); } }; task.execute(); } private void setAdapter() { if (adapter == null){ adapter = new XListViewAdapter(getActivity(), list); xListView.setAdapter(adapter); }else { adapter.notifyDataSetChanged(); } } //下拉刷新 @Override public void onRefresh() { num++; getDataFromNet(); //加载到数据之后停止 } @Override public void onLoadMore() { num++; getData(); //加载到数据之后停止 } //网络获取刷新的数据 private void getData() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/1/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(newsBean.getData()); //设置适配器 setAdapter(); //停止加载数据 xListView.stopLoadMore(); } }; task.execute(); } }
package com.fragment; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.LianXi.R; import com.adapter.XListViewAdapter; import com.bean.NewsBean; import com.google.gson.Gson; import com.util.StringUtil; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import view.XListView; public class SetFragment extends Fragment implements XListView.IXListViewListener{ private List<NewsBean.DataBean> list = new ArrayList<>(); private XListViewAdapter adapter; private XListView xListView; private int num = 1; @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.news_layout, container, false); //查找控件 xListView = view.findViewById(R.id.xListView); //设置XListView的上拉刷新功能 xListView.setPullLoadEnable(true); xListView.setPullRefreshEnable(true); //XListView的监听事件 xListView.setXListViewListener(this); return view; } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); //获取刷新的数据 getDataFromNet(); } //网络获取刷新的数据 private void getDataFromNet() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/1/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(0,newsBean.getData()); //设置适配器 setAdapter(); //停止刷新数据 xListView.stopRefresh(); //设置刷新的时间 Date date = new Date(System.currentTimeMillis()); SimpleDateFormat format = new SimpleDateFormat("HH:mm"); xListView.setRefreshTime(format.format(date)); } }; task.execute(); } private void setAdapter() { if (adapter == null){ adapter = new XListViewAdapter(getActivity(), list); xListView.setAdapter(adapter); }else { adapter.notifyDataSetChanged(); } } //下拉刷新 @Override public void onRefresh() { num++; getDataFromNet(); //加载到数据之后停止 } @Override public void onLoadMore() { num++; getData(); //加载到数据之后停止 } //网络获取刷新的数据 private void getData() { AsyncTask<Void,Void,String> task = new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { try { String path="http://api.expoon.com/AppNews/getNewsList/type/1/p/"+num; URL url = new URL(path); //post方式网络连接,注意HttpURLConnection请求数据,不是HttpsURLConnection类 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setReadTimeout(5000); //响应数据 int responseCode = connection.getResponseCode(); if (responseCode == 200){ InputStream inputStream = connection.getInputStream(); //返回数据 String json = StringUtil.streamToString(inputStream,"utf-8"); return json; } } catch (Exception e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(String result) { //解析数据 NewsBean newsBean = new Gson().fromJson(result, NewsBean.class); //把获取的数据添加到集合中 list.addAll(newsBean.getData()); //设置适配器 setAdapter(); //停止加载数据 xListView.stopLoadMore(); } }; task.execute(); } }
五. 工具类(导入ImageLoader包)
1. 全局化配置ImageLoader(需在清单文件中声明name属性)
package com.util; import android.app.Application; //全局初始化Application类 public class BaseApplication extends Application { @Override public void onCreate() { super.onCreate(); //配置imageLoader ImageLoaderUtil.init(this); } }
package com.util; import android.content.Context; import android.graphics.Bitmap; import com.LianXi.R; 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.decode.BaseImageDecoder; import com.nostra13.universalimageloader.core.display.RoundedBitmapDisplayer; import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; import com.nostra13.universalimageloader.core.download.BaseImageDownloader; import com.nostra13.universalimageloader.utils.StorageUtils; import java.io.File; public class ImageLoaderUtil { /** * 初始化imageLoader * @param context */ public static void init(Context context) { //1.获取配置config对象 File cacheDir = StorageUtils.getCacheDirectory(context); //缓存文件夹路径 ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context) .threadPoolSize(3) // default 线程池内加载的数量 .threadPriority(Thread.NORM_PRIORITY - 2) // default 设置当前线程的优先级 .tasksProcessingOrder(QueueProcessingType.FIFO) // default .denyCacheImageMultipleSizesInMemory() .memoryCache(new LruMemoryCache(2 * 1024 * 1024)) //可以通过自己的内存缓存实现 .memoryCacheSize(2 * 1024 * 1024) // 内存缓存的最大值 .memoryCacheSizePercentage(13) // default .diskCache(new UnlimitedDiscCache(cacheDir)) // default 可以自定义缓存路径 .diskCacheSize(50 * 1024 * 1024) // 50 Mb sd卡(本地)缓存的最大值 .diskCacheFileCount(100) // 可以缓存的文件数量 // default为使用HASHCODE对UIL进行加密命名, 还可以用MD5(new Md5FileNameGenerator())加密 .diskCacheFileNameGenerator(new HashCodeFileNameGenerator()) .imageDownloader(new BaseImageDownloader(context)) // default .imageDecoder(new BaseImageDecoder(true)) // default .defaultDisplayImageOptions(DisplayImageOptions.createSimple()) // default .writeDebugLogs() // 打印debug log .build(); //开始构建 //2.初始化配置...ImageLoader.getInstance()图片加载器的对象,单例模式 ImageLoader.getInstance().init(config); } /** * imageLoader加载图片的默认选项 * @return */ public static DisplayImageOptions getDefaultOption(){ DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.app_default) // 设置图片下载期间显示的默认图片 .showImageForEmptyUri(R.drawable.app_default) // 设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.drawable.app_default) // 设置图片加载或解码过程中发生错误显示的图片 .resetViewBeforeLoading(true) // default 设置图片在加载前是否重置、复位 .delayBeforeLoading(1000) // 下载前的延迟时间 .cacheInMemory(true) // default 设置下载的图片是否缓存在内存中 .cacheOnDisk(true) // default 设置下载的图片是否缓存在SD卡中 .considerExifParams(true) // default .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示 .bitmapConfig(Bitmap.Config.RGB_565) // default 设置图片的解码类型 .displayer(new SimpleBitmapDisplayer()) // default 还可以设置圆角图片new RoundedBitmapDisplayer(20) .build(); return options; } /** * imageLoader加载圆角图片....指定圆角的大小 * @return */ public static DisplayImageOptions getRoundedOption(int corner){ DisplayImageOptions options = new DisplayImageOptions.Builder() .showImageOnLoading(R.drawable.app_default) // 设置图片下载期间显示的图片 .showImageForEmptyUri(R.drawable.app_default) // 设置图片Uri为空或是错误的时候显示的图片 .showImageOnFail(R.drawable.app_default) // 设置图片加载或解码过程中发生错误显示的图片 .resetViewBeforeLoading(true) // default 设置图片在加载前是否重置、复位 .delayBeforeLoading(1000) // 下载前的延迟时间 .cacheInMemory(true) // default 设置下载的图片是否缓存在内存中 .cacheOnDisk(true) // default 设置下载的图片是否缓存在SD卡中 .considerExifParams(true) // default .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2) // default 设置图片以如何的编码方式显示 .bitmapConfig(Bitmap.Config.RGB_565) // default 设置图片的解码类型 .displayer(new RoundedBitmapDisplayer(corner)) // default 还可以设置圆角图片new RoundedBitmapDisplayer(20) .build(); return options; } }
2. 解析json串
package com.util; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; public class StringUtil { public static String streamToString(InputStream inputStream, String charset) { try { InputStreamReader inputStreamReader = new InputStreamReader(inputStream,charset); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); String s = null; StringBuilder builder = new StringBuilder(); while ((s = bufferedReader.readLine()) != null){ builder.append(s); } bufferedReader.close(); return builder.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } }
3. view包下的XListView的配置:
/** * @file XListView.java * @package me.maxwin.view * @create Mar 18, 2012 6:28:41 PM * @author Maxwin * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. * Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). */ package view; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.animation.DecelerateInterpolator; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.RelativeLayout; import android.widget.Scroller; import android.widget.TextView; import com.LianXi.R; public class XListView extends ListView implements OnScrollListener { private float mLastY = -1; // save event y private Scroller mScroller; // used for scroll back private OnScrollListener mScrollListener; // user's scroll listener // the interface to trigger refresh and load more. private IXListViewListener mListViewListener; // -- header view private XListViewHeader mHeaderView; // header view content, use it to calculate the Header's height. And hide it // when disable pull refresh. private RelativeLayout mHeaderViewContent; private TextView mHeaderTimeView; private int mHeaderViewHeight; // header view's height private boolean mEnablePullRefresh = true; private boolean mPullRefreshing = false; // is refreashing. // -- footer view private XListViewFooter mFooterView; private boolean mEnablePullLoad; private boolean mPullLoading; private boolean mIsFooterReady = false; // total list items, used to detect is at the bottom of listview. private int mTotalItemCount; // for mScroller, scroll back from header or footer. private int mScrollBack; private final static int SCROLLBACK_HEADER = 0; private final static int SCROLLBACK_FOOTER = 1; private final static int SCROLL_DURATION = 400; // scroll back duration private final static int PULL_LOAD_MORE_DELTA = 50; // when pull up >= 50px // at bottom, trigger // load more. private final static float OFFSET_RADIO = 1.8f; // support iOS like pull // feature. /** * @param context */ public XListView(Context context) { super(context); initWithContext(context); } public XListView(Context context, AttributeSet attrs) { super(context, attrs); initWithContext(context); } public XListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initWithContext(context); } private void initWithContext(Context context) { mScroller = new Scroller(context, new DecelerateInterpolator()); // XListView need the scroll event, and it will dispatch the event to // user's listener (as a proxy). super.setOnScrollListener(this); // init header view mHeaderView = new XListViewHeader(context); mHeaderViewContent = (RelativeLayout) mHeaderView .findViewById(R.id.xlistview_header_content); mHeaderTimeView = (TextView) mHeaderView .findViewById(R.id.xlistview_header_time); addHeaderView(mHeaderView); // init footer view mFooterView = new XListViewFooter(context); // init header height mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mHeaderViewHeight = mHeaderViewContent.getHeight(); getViewTreeObserver() .removeGlobalOnLayoutListener(this); } }); } @Override public void setAdapter(ListAdapter adapter) { // make sure XListViewFooter is the last footer view, and only add once. if (mIsFooterReady == false) { mIsFooterReady = true; addFooterView(mFooterView); } super.setAdapter(adapter); } /** * enable or disable pull down refresh feature. * * @param enable */ public void setPullRefreshEnable(boolean enable) { mEnablePullRefresh = enable; if (!mEnablePullRefresh) { // disable, hide the content mHeaderViewContent.setVisibility(View.INVISIBLE); } else { mHeaderViewContent.setVisibility(View.VISIBLE); } } /** * enable or disable pull up load more feature. * * @param enable */ public void setPullLoadEnable(boolean enable) { mEnablePullLoad = enable; if (!mEnablePullLoad) { mFooterView.hide(); mFooterView.setOnClickListener(null); //make sure "pull up" don't show a line in bottom when listview with one page setFooterDividersEnabled(false); } else { mPullLoading = false; mFooterView.show(); mFooterView.setState(XListViewFooter.STATE_NORMAL); //make sure "pull up" don't show a line in bottom when listview with one page setFooterDividersEnabled(true); // both "pull up" and "click" will invoke load more. mFooterView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startLoadMore(); } }); } } /** * stop refresh, reset header view. */ public void stopRefresh() { if (mPullRefreshing == true) { mPullRefreshing = false; resetHeaderHeight(); } } /** * stop load more, reset footer view. */ public void stopLoadMore() { if (mPullLoading == true) { mPullLoading = false; mFooterView.setState(XListViewFooter.STATE_NORMAL); } } /** * set last refresh time * * @param time */ public void setRefreshTime(String time) { mHeaderTimeView.setText(time); } private void invokeOnScrolling() { if (mScrollListener instanceof OnXScrollListener) { OnXScrollListener l = (OnXScrollListener) mScrollListener; l.onXScrolling(this); } } private void updateHeaderHeight(float delta) { mHeaderView.setVisiableHeight((int) delta + mHeaderView.getVisiableHeight()); if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头 if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) { mHeaderView.setState(XListViewHeader.STATE_READY); } else { mHeaderView.setState(XListViewHeader.STATE_NORMAL); } } setSelection(0); // scroll to top each time } /** * reset header view's height. */ private void resetHeaderHeight() { int height = mHeaderView.getVisiableHeight(); if (height == 0) // not visible. return; // refreshing and header isn't shown fully. do nothing. if (mPullRefreshing && height <= mHeaderViewHeight) { return; } int finalHeight = 0; // default: scroll back to dismiss header. // is refreshing, just scroll back to show all the header. if (mPullRefreshing && height > mHeaderViewHeight) { finalHeight = mHeaderViewHeight; } mScrollBack = SCROLLBACK_HEADER; mScroller.startScroll(0, height, 0, finalHeight - height, SCROLL_DURATION); // trigger computeScroll invalidate(); } private void updateFooterHeight(float delta) { int height = mFooterView.getBottomMargin() + (int) delta; if (mEnablePullLoad && !mPullLoading) { if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load // more. mFooterView.setState(XListViewFooter.STATE_READY); } else { mFooterView.setState(XListViewFooter.STATE_NORMAL); } } mFooterView.setBottomMargin(height); // setSelection(mTotalItemCount - 1); // scroll to bottom } private void resetFooterHeight() { int bottomMargin = mFooterView.getBottomMargin(); if (bottomMargin > 0) { mScrollBack = SCROLLBACK_FOOTER; mScroller.startScroll(0, bottomMargin, 0, -bottomMargin, SCROLL_DURATION); invalidate(); } } private void startLoadMore() { mPullLoading = true; mFooterView.setState(XListViewFooter.STATE_LOADING); if (mListViewListener != null) { mListViewListener.onLoadMore(); } } @Override public boolean onTouchEvent(MotionEvent ev) { if (mLastY == -1) { mLastY = ev.getRawY(); } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: final float deltaY = ev.getRawY() - mLastY; mLastY = ev.getRawY(); if (getFirstVisiblePosition() == 0 && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) { // the first item is showing, header has shown or pull down. updateHeaderHeight(deltaY / OFFSET_RADIO); invokeOnScrolling(); } else if (getLastVisiblePosition() == mTotalItemCount - 1 && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) { // last item, already pulled up or want to pull up. updateFooterHeight(-deltaY / OFFSET_RADIO); } break; default: mLastY = -1; // reset if (getFirstVisiblePosition() == 0) { // invoke refresh if (mEnablePullRefresh && mHeaderView.getVisiableHeight() > mHeaderViewHeight) { mPullRefreshing = true; mHeaderView.setState(XListViewHeader.STATE_REFRESHING); if (mListViewListener != null) { mListViewListener.onRefresh(); } } resetHeaderHeight(); } else if (getLastVisiblePosition() == mTotalItemCount - 1) { // invoke load more. if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA && !mPullLoading) { startLoadMore(); } resetFooterHeight(); } break; } return super.onTouchEvent(ev); } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { if (mScrollBack == SCROLLBACK_HEADER) { mHeaderView.setVisiableHeight(mScroller.getCurrY()); } else { mFooterView.setBottomMargin(mScroller.getCurrY()); } postInvalidate(); invokeOnScrolling(); } super.computeScroll(); } @Override public void setOnScrollListener(OnScrollListener l) { mScrollListener = l; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { if (mScrollListener != null) { mScrollListener.onScrollStateChanged(view, scrollState); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // send to user's listener mTotalItemCount = totalItemCount; if (mScrollListener != null) { mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount, totalItemCount); } } public void setXListViewListener(IXListViewListener l) { mListViewListener = l; } /** * you can listen ListView.OnScrollListener or this one. it will invoke * onXScrolling when header/footer scroll back. */ public interface OnXScrollListener extends OnScrollListener { public void onXScrolling(View view); } /** * implements this interface to get refresh/load more event. */ public interface IXListViewListener { public void onRefresh(); public void onLoadMore(); } }
/** * @file XFooterView.java * @create Mar 31, 2012 9:33:43 PM * @author Maxwin * @description XListView's footer */ package view; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import com.LianXi.R; public class XListViewFooter extends LinearLayout { public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_LOADING = 2; private Context mContext; private View mContentView; private View mProgressBar; private TextView mHintView; public XListViewFooter(Context context) { super(context); initView(context); } public XListViewFooter(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } public void setState(int state) { mHintView.setVisibility(View.INVISIBLE); mProgressBar.setVisibility(View.INVISIBLE); mHintView.setVisibility(View.INVISIBLE); if (state == STATE_READY) { mHintView.setVisibility(View.VISIBLE); mHintView.setText(R.string.xlistview_footer_hint_ready); } else if (state == STATE_LOADING) { mProgressBar.setVisibility(View.VISIBLE); } else { mHintView.setVisibility(View.VISIBLE); mHintView.setText(R.string.xlistview_footer_hint_normal); } } public void setBottomMargin(int height) { if (height < 0) return ; LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.bottomMargin = height; mContentView.setLayoutParams(lp); } public int getBottomMargin() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); return lp.bottomMargin; } /** * normal status */ public void normal() { mHintView.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.GONE); } /** * loading status */ public void loading() { mHintView.setVisibility(View.GONE); mProgressBar.setVisibility(View.VISIBLE); } /** * hide footer when disable pull load more */ public void hide() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.height = 0; mContentView.setLayoutParams(lp); } /** * show footer */ public void show() { LayoutParams lp = (LayoutParams)mContentView.getLayoutParams(); lp.height = LayoutParams.WRAP_CONTENT; mContentView.setLayoutParams(lp); } private void initView(Context context) { mContext = context; LinearLayout moreView = (LinearLayout)LayoutInflater.from(mContext).inflate(R.layout.xlistview_footer, null); addView(moreView); moreView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); mContentView = moreView.findViewById(R.id.xlistview_footer_content); mProgressBar = moreView.findViewById(R.id.xlistview_footer_progressbar); mHintView = (TextView)moreView.findViewById(R.id.xlistview_footer_hint_textview); } }
/** * @file XListViewHeader.java * @create Apr 18, 2012 5:22:27 PM * @author Maxwin * @description XListView's header */ package view; import android.content.Context; import android.util.AttributeSet; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.TextView; import com.LianXi.R; public class XListViewHeader extends LinearLayout { private LinearLayout mContainer; private ImageView mArrowImageView; private ProgressBar mProgressBar; private TextView mHintTextView; private int mState = STATE_NORMAL; private Animation mRotateUpAnim; private Animation mRotateDownAnim; private final int ROTATE_ANIM_DURATION = 180; public final static int STATE_NORMAL = 0; public final static int STATE_READY = 1; public final static int STATE_REFRESHING = 2; public XListViewHeader(Context context) { super(context); initView(context); } /** * @param context * @param attrs */ public XListViewHeader(Context context, AttributeSet attrs) { super(context, attrs); initView(context); } private void initView(Context context) { // 初始情况,设置下拉刷新view高度为0 LayoutParams lp = new LayoutParams( LayoutParams.FILL_PARENT, 0); mContainer = (LinearLayout) LayoutInflater.from(context).inflate( R.layout.xlistview_header, null); addView(mContainer, lp); setGravity(Gravity.BOTTOM); mArrowImageView = (ImageView)findViewById(R.id.xlistview_header_arrow); mHintTextView = (TextView)findViewById(R.id.xlistview_header_hint_textview); mProgressBar = (ProgressBar)findViewById(R.id.xlistview_header_progressbar); mRotateUpAnim = new RotateAnimation(0.0f, -180.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION); mRotateUpAnim.setFillAfter(true); mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION); mRotateDownAnim.setFillAfter(true); } public void setState(int state) { if (state == mState) return ; if (state == STATE_REFRESHING) { // 显示进度 mArrowImageView.clearAnimation(); mArrowImageView.setVisibility(View.INVISIBLE); mProgressBar.setVisibility(View.VISIBLE); } else { // 显示箭头图片 mArrowImageView.setVisibility(View.VISIBLE); mProgressBar.setVisibility(View.INVISIBLE); } switch(state){ case STATE_NORMAL: if (mState == STATE_READY) { mArrowImageView.startAnimation(mRotateDownAnim); } if (mState == STATE_REFRESHING) { mArrowImageView.clearAnimation(); } mHintTextView.setText(R.string.xlistview_header_hint_normal); break; case STATE_READY: if (mState != STATE_READY) { mArrowImageView.clearAnimation(); mArrowImageView.startAnimation(mRotateUpAnim); mHintTextView.setText(R.string.xlistview_header_hint_ready); } break; case STATE_REFRESHING: mHintTextView.setText(R.string.xlistview_header_hint_loading); break; default: } mState = state; } public void setVisiableHeight(int height) { if (height < 0) height = 0; LayoutParams lp = (LayoutParams) mContainer .getLayoutParams(); lp.height = height; mContainer.setLayoutParams(lp); } public int getVisiableHeight() { return mContainer.getLayoutParams().height; } }
六. 自定义布局
1. activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" > <!--主内容区域的视图--> <FrameLayout android:id="@+id/frame_layout" android:layout_width="match_parent" android:layout_height="match_parent" /> <!--抽屉展示的布局--> <LinearLayout android:layout_gravity="left" android:background="#ffffff" android:orientation="vertical" android:layout_width="200dp" android:id="@+id/linearLayout" android:layout_height="match_parent"> <LinearLayout android:padding="20dp" android:id="@+id/linear_01" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <ImageView android:src="@drawable/weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> <TextView android:text="新闻" android:textSize="18sp" android:gravity="center_vertical" android:layout_marginLeft="6dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:padding="20dp" android:id="@+id/linear_02" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <ImageView android:src="@drawable/weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> <TextView android:text="关注" android:textSize="18sp" android:gravity="center_vertical" android:layout_marginLeft="6dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:padding="20dp" android:id="@+id/linear_03" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <ImageView android:src="@drawable/weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> <TextView android:text="动态" android:textSize="18sp" android:gravity="center_vertical" android:layout_marginLeft="6dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> <LinearLayout android:padding="20dp" android:id="@+id/linear_04" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true"> <ImageView android:src="@drawable/weixin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> <TextView android:text="设置" android:textSize="18sp" android:layout_marginLeft="6dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout> </LinearLayout> </android.support.v4.widget.DrawerLayout>
2. item.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:padding="10dp" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_vertical" /> <TextView android:id="@+id/text" android:textSize="18sp" android:layout_marginLeft="10dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" /> </LinearLayout>
3. news_layout.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <view.XListView android:id="@+id/xListView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center_horizontal"/> </LinearLayout>
4. xlistview_header.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="wrap_content"
android:gravity="bottom" >
<RelativeLayout
android:id="@+id/xlistview_header_content"
android:layout_width="fill_parent"
android:layout_height="60dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical" android:id="@+id/xlistview_header_text">
<TextView
android:id="@+id/xlistview_header_hint_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/xlistview_header_hint_normal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/xlistview_header_last_time"
android:textSize="12sp" />
<TextView
android:id="@+id/xlistview_header_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
<ImageView
android:id="@+id/xlistview_header_arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@id/xlistview_header_text"
android:layout_centerVertical="true"
android:layout_marginLeft="-35dp"
android:src="@drawable/xlistview_arrow" />
<ProgressBar
android:id="@+id/xlistview_header_progressbar"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignLeft="@id/xlistview_header_text"
android:layout_centerVertical="true"
android:layout_marginLeft="-40dp"
android:visibility="invisible" />
</RelativeLayout>
</LinearLayout>
5. xlistview_footer.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="wrap_content" > <RelativeLayout android:id="@+id/xlistview_footer_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" > <ProgressBar android:id="@+id/xlistview_footer_progressbar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:visibility="invisible" /> <TextView android:id="@+id/xlistview_footer_hint_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="@string/xlistview_footer_hint_normal" /> </RelativeLayout> </LinearLayout>
6. values文件夹下的strings.xml
<string name="xlistview_header_hint_normal">下拉刷新</string>
<string name="xlistview_header_hint_ready">松开刷新数据</string>
<string name="xlistview_header_hint_loading">正在加载...</string>
<string name="xlistview_header_last_time">上次更新时间:</string>
<string name="xlistview_footer_hint_normal">查看更多</string>
<string name="xlistview_footer_hint_ready">松开载入更多</string>