ListView中不同类型view的实现
首先创建请求队列,一个活动中只需要一个,因此放在Application中:
public class MyApplication extends Application{
private static RequestQueue requestQueue; @Override
public void onCreate() {
super.onCreate();
requestQueue = Volley.newRequestQueue(getApplicationContext()); }
public static RequestQueue getRequestQueue(){
return requestQueue;
} }
注意:需要在清单文件中注册o~
<application
android:name=".MyApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
然后我们需要下载并解析json数据,这时候就需要自定义request继承request了,这里需要一个泛型参数,一般需要解析什么就设置什么,但是推荐使用泛型T,这样可以更方便为我们所使用了
NewsBeanRequest:
/**
* Created by Administrator on 2016/9/27.
*/
public class NewsBeanRequest extends Request<NewsBean> {
private Response.Listener<NewsBean> listener; public NewsBeanRequest(int method, String url, Response.ErrorListener listener, Response.Listener<NewsBean> listener1) {
super(method, url, listener);
this.listener = listener1;
} @Override
protected Response<NewsBean> parseNetworkResponse(NetworkResponse response) {
NewsBean newsBean = new NewsBean();
Gson gson = new Gson();
try {
newsBean = gson.fromJson(new String(response.data, HttpHeaderParser.parseCharset(response.headers)),NewsBean.class);
} catch (UnsupportedEncodingException e) {
newsBean = gson.fromJson(new String(response.data),NewsBean.class);
} return Response.success(newsBean, HttpHeaderParser.parseCacheHeaders(response));
} @Override
protected void deliverResponse(NewsBean response) {
listener.onResponse(response);
}
}
上面代码分为三部分:
0.定义构造方法,传入请求网络需要的参数,通过父类去请求网络
1.解析网络请求的响应结果,将 字节数组类型的数据转换成自己想要的 T (通常是java bean数据模型)
2.deliverResponse(T response) 分发响应结果(处理监听)调用请求成功的监听器
接下来就是主程序了,
main:
public class MainActivity extends AppCompatActivity { private ListView listview;
private RequestQueue requestQueue;
private static final String URL = "http://ikft.house.qq.com/index.php?guid=866500021200250&devua=appkft_1080_1920_XiaomiMI4LTE_1.8.3_Android19&devid=866500021200250&appname=QQHouse&mod=appkft&reqnum=&pageflag=&act=newslist&channel=71&buttonmore=&cityid=1";
private List<NewsBean.DataBean> dataList = new ArrayList<>();
private NewsListAdapter newsListAdapter; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listview);
//创建适配器
newsListAdapter = new NewsListAdapter(this,dataList);
//设置适配器
listview.setAdapter(newsListAdapter);
//1,创建RequestQueue
requestQueue = MyApplication.getRequestQueue();
//2.自定义对象请求
NewsBeanRequest newsBeanRequest = new NewsBeanRequest(Request.Method.GET, URL, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.i("tag", "下载数据失败");
}
}, new Response.Listener<NewsBean>() {
@Override
public void onResponse(NewsBean response) {
//返回的数据为下载并解析后的newsBean对象
newsListAdapter.addData(response.getData());
}
});
//设置标记
newsBeanRequest.setTag(URL);
//3.添加到请求队列中
requestQueue.add(newsBeanRequest); } @Override
protected void onDestroy() {
super.onDestroy();
//4.取消该标记对应的请求
requestQueue.cancelAll(URL);
}
}
一般的从网上获取数据就是上面这四步了,
给请求设置一个tag是为了请求队列取消请求的时候,可以通过tag来取消tag对应的请求
还有一种方式可以取消:newsBeanrequest.canel();//取消自己
一般在活动销毁的时候将请求也取消
接下来就是适配器中对数据进行设置了:
class NewsListAdapter extends BaseAdapter {
private Context context;
private List<NewsBean.DataBean>dataList; public NewsListAdapter(Context context, List<NewsBean.DataBean> dataList) {
this.context = context;
this.dataList = dataList;
} /**
*添加数据
* @param dataList
*/
public void addData(List<NewsBean.DataBean> dataList){
this.dataList.addAll(dataList);
notifyDataSetChanged();
}
@Override
public int getCount() {
return dataList.size();
} @Override
public Object getItem(int position) {
return dataList.get(position);
} @Override
public long getItemId(int position) {
return position;
} /* 获得当前adapter中view的种类的数量*/
@Override
public int getViewTypeCount() {
return 2;
}
/*根据position来获得当前的要显示的item的view类型*/
@Override
public int getItemViewType(int position) {
return new Integer(dataList.get(position).getType());
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
//得到当前复用的view的类型
// int type = Integer.parseInt(dataList.get(position).getType());
//得打NewsBean.DataBean中的参数int type
int type = getItemViewType(position);
NewsBean.DataBean dataBean = dataList.get(position);
//1.创建ImageLoader对象
ImageLoader imageLoader = new ImageLoader(MyApplication.getRequestQueue(),new MyImageCache());
ViewHolder1 viewHolder1 = null;
ViewHolder2 viewHolder2 = null;
switch (type){
case 0:
if(convertView == null){
convertView = LayoutInflater.from(context).inflate(R.layout.listview_item_news_1,parent,false);
viewHolder1 = new ViewHolder1(convertView);
convertView.setTag(viewHolder1);
}else{
viewHolder1 = (ViewHolder1)convertView.getTag();
}
viewHolder1.tvSummary.setText(dataBean.getSummary());
viewHolder1.tvTitle.setText(dataBean.getTitle()); //2.声明监听
ImageLoader.ImageListener listener = ImageLoader.getImageListener(viewHolder1.imgGroupthumbnail, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
//3.加载图片
imageLoader.get(dataBean.getGroupthumbnail(),listener);
break;
case 1:
if(convertView ==null){
convertView = View.inflate(context,R.layout.listview_item_news_2,null);
viewHolder2 = new ViewHolder2(convertView);
convertView.setTag(viewHolder2);
}else{
viewHolder2 = (ViewHolder2)convertView.getTag();
}
ImageLoader.ImageListener listener1 = ImageLoader.getImageListener(viewHolder2.imgGroupthumbnail, R.mipmap.ic_launcher, R.mipmap.ic_launcher);
imageLoader.get(dataBean.getGroupthumbnail(),listener1);
break;
} return convertView;
}
class ViewHolder1 {
public ImageView imgGroupthumbnail;
public TextView tvTitle;
public TextView tvSummary; public ViewHolder1(View view) {
this.imgGroupthumbnail = (ImageView) view.findViewById(R.id.img_groupthumbnail);
this.tvTitle = (TextView) view.findViewById(R.id.tv_title);
this.tvSummary = (TextView) view.findViewById(R.id.tv_summary);
}
} class ViewHolder2 {
public ImageView imgGroupthumbnail; public ViewHolder2(View view) {
this.imgGroupthumbnail = (ImageView) view.findViewById(R.id.img_groupthumbnail); }
}
class MyImageCache implements ImageLoader.ImageCache{
private LruCache<String,Bitmap> lruCache; public MyImageCache() {
lruCache = new LruCache<String,Bitmap>((int) (Runtime.getRuntime().maxMemory()/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
} @Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
} @Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url,bitmap);
}
}
}
方法解析:
addData:自定义的对外暴露的添加数据的方法,当数据发生改变的时候调用,添加数据
重写适配器中的两个方法,
getViewTypeCount()//得到类型的个数
getItemViewType()//得到当前复用view的类型
在adapter的getView方法中,得到当前显示view的type并判断,然后根据判断的type类型对该类型对应的view布局来进行操作
,如果可复用的布局为空,首先得到当前需要显示的布局,布局通过布局加载器来加载布局,并传入自定义类ViewHolder中,而viewholder的作用是装载控件的,我们可以通过id找到布局中对应的控件,最后,该viewHolder设置为convertview的一个标记,然后我们就可以通过dataList.get(position)得到当前item的数据,并设置到控件上了,当然,如果当前可复用的view不为空,直接通过getTag()方法就可以得到viewHolderl ,操作同上
我们下载图片是通过imageLoader来实现的
ImageLoader是一个图片加载器,可以设置缓存,
首先创建一个ImageLoader对象,里面传递两个参数,
第一个参数是请求队列,一般通过Volley.newRequestQueue来获取,但是一般一个activity中有一个就足够,因此我设置到了MyApplication中.
第二个参数是图片缓存的实现类对象,里面实现了两个方法,分别是对图片的取和存,不过得先创建一个内存缓存,我将他的实现放在了构造方法里面,这样在创建该对象的时候就直接创建了,创建对象需要传入一个参数,该参数指定缓存的大小,这里我设置的是总空间大小的1/8,然后重写sizeOf方法返回每张图片的大小,当构造方法中设置的是一个固定的数值的时候,返回参数设置为1
然后为图片设置监听器:监听回调的数据
参数1: 需要展示图片的imageview , 2.默认图片 3.错误图片
最后ImageLoader加载图片
放入请求队列
参数1:path 网络地址 参数2: 请求成功的监听,请求成功会回调listener
imageLoader.get(path,imagelistener);
现在图片也下载完成了,我们可以看到效果:
ListView中不同类型view的实现的更多相关文章
- 【我的Android进阶之旅】如何去除ListView中Header View、Footer View中的分割线
最近的项目中给ListView 加入了一个Header View之后,发现Header View的下方也有了分割线,很难看,UI要求将Header View的分割器去掉,好吧.现在就来说一说如何如何去 ...
- ListView之多种类型Item
一.概述 一般而言,listview每个item的样式是一样的,但也有很多应用场景下不同位置的item需要不同的样式. 拿微信举例,前者的代表作是消息列表,而后者的典型则是聊天会话界面. 本文重点介绍 ...
- C#中清空ListView中的数据
我的显示数据的方式通过button按钮点击事件,当点击之后查询数据库库并将数据显示出来. 代码如下: private void button6_Click(object sender, EventAr ...
- android ListView 中getview学习总结
最近在做android相关的开发,ListView中有一个图片错位的问题,今天查了很多人写的一些东西,所以记录下来,算是一种加深理解吧. ListView是一个非常常用的控件,功能可以扩展的很丰富,而 ...
- 在ListView中使用多个布局
要想在一个ListView中使用多个布局文件,比如一个信息List包含了一个信息标题和每个信息对应的时间. 关键的步骤是实现Adapter类的getItemViewType 和getViewTypeC ...
- Android ListView中 每一项都有不同的布局
实现代码 Adapter的代码 其中:ViewHolder分别是三个不同的布局,也就是ListView中每一项的布局 TYPE_1...是三种类型. 在使用不同布局的时候,getItemViewTyp ...
- 关于ListView中convertView的缓存个数的探究
在面试的时候经常会被问到一个有关ListView的问题:一个ListView的高度最多可以显示5个item,但是却有20条数据要显示,问最多会有多少个convertView会被复用?或者如在ListV ...
- Android开发-Listview中显示不同的视图布局
1. 使用场景 在重写ListView的BaseAdapter时,我们常常在getView()方法中复用convertView,以提高性能.convertView在Item为单一的同种类型布局时,能够 ...
- listview中的adapter学习小结
概述 Adapter是数据和UI之间的一个桥梁,在listview,gridview等控件中都会使用到,android给我们提拱了4个adapte供我们使用: BaseAdapter是一个抽象类,继承 ...
随机推荐
- Loadrunner通过sitescope监控mysql
1. Loadrunner通过sitescope监控mysql 1.1. Sitescope下载 第一次在网上下载的是sitescope11.30,安装之后无法破解,所以最后卸载了,重新下载了si ...
- ASP.NET运行原理_2
当一个HTTP请求到服务器并被IIS接收到之后,IIS首先通过客户端请求的页面类型为其加载相应的.dll文件,然后在处理过程中将这条请求发送给能够处理这个请求的模块.在ASP.NET 3.5中,这个模 ...
- MSP430F5438点亮led
今天只是想点亮一个led灯,因为没有视频,搞得很多的东西都是自己摸,下午本来讲和咨询店家,TMD说好给一点技术支持,结果一点也不给,我真想草泥马了,其实代码早就写出来了,只是哥哥不知道这款开发板还有接 ...
- 使用asp.net MVC4中的Bundle遇到的问题及解决办法
背景 之前有过使用MVC3的经验,也建过MVC4的基本样例看过,知道有bundle这么一个方法. 近日想建个网站使用MVC4,但是我觉得在基本样例上改不好,有太多无用的东西,所以就建了一个空白的MVC ...
- cocos2d-x 3.0版本已经加了socket部分
cocos2d-x开发者的福音到了,在3.0版本中新增了HttpClient.HttpRequest.SocketIO.Websocket库,需要网络交互的同学应该可以用到,并且它已经与cocos2d ...
- leetcode@ [211] Add and Search Word - Data structure design
https://leetcode.com/problems/add-and-search-word-data-structure-design/ 本题是在Trie树进行dfs+backtracking ...
- 【hdu3065】病毒侵袭持续中
题意: 求目标串中每个模式串出现几次 目标串长度<=2000000 模式串<=1000个 模式串长度<=50 题解: 这不就是AC自动机的模板题吗! 求fail树中模式串的子树中有几 ...
- inter
网卡不稳定的罪魁祸首 近期新上的DB SERVER服务器,在压测中发现网卡很不稳定,压力测试刚刚进行十几分钟后,服务器反应就变得非常慢,PING的时候经常丢包而且SSH连接也时断时 续.刚开始以为 ...
- 独树一帜的字符串匹配算法——RK算法
参加了雅虎2015校招,笔试成绩还不错,谁知初面第一题就被问了个字符串匹配,要求不能使用KMP,但要和KMP一样优,当时瞬间就呵呵了.后经过面试官的一再提示,也还是没有成功在面试现场写得.现将该算法记 ...
- sts中从svn导入maven项目
1.创建资源库 2.导入项目作为本地项目 3.将子module从本地导入(默认情况下,只会将主pom所在的工程导入)