BaseAdapter使用比较麻烦,它是个抽象类,需要重写4个方法分别是getCount() getItem(..) getItemId(..) getVew(..),相应的使用BaseAdapter

可以自由的定义自己想要的布局,先看看程序效果图:

这个布局一共有5个元素分别是:ImageViw 2个TextView CheckBox Button

先看这个ListView的Item布局文件list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="50dp">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_launcher"
android:id="@+id/iv_image"/>
<!-- 注意这个里两个TextView的布局是垂注布局的-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_weight="4">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="25dp"
android:text="hah"
android:id="@+id/tv_item"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="content"
android:id="@+id/tv_content"/>
</LinearLayout> <CheckBox
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/ck_box"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:textSize="20sp"
android:text="Select"
android:id="@+id/btn_select"
android:background="@drawable/btn_selector"/>
</LinearLayout>

整理一下我们要做的事情:1、首先在主布局里要放一个ListView;
            2、准备ListView显示需要的数据;

3、重写适配器,将布局文件与数据放到ListView中显示,这一部分最复杂,还有布局文件中还有点击事件需要设置。

下面是主程序代码:

package com.skymaster.hs.baseadaptertest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import java.util.ArrayList;
import java.util.HashMap; public class MainActivity extends AppCompatActivity {
private ListView listView;
private HsAdapter hsAdapter;
private ArrayList<HashMap<String,Object>> listItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.lv_list);
hsAdapter = new HsAdapter(getLayoutInflater());
DataInit();
listView.setAdapter(hsAdapter);
}
/*
* 初始化显示的内容ListView表的数据结构对应的是ArrayList
* 但是ListView内部每一项Item有细分多个View,所以ArrayList泛型定义为Map
* 这样就可以定义多中数据类型了,没一个key对应一个View,适配器在填充内容的时候
* 可以根据key来获取内容,这里要注意一点:HashMap<String,Object> hashMap = new HashMap<>();
* 一定要放到循环里面,因为ListView有多少个Item就应该有多少个数据对象也就是说有多少new出来得对象实例
* */
private void DataInit(){
listItem = new ArrayList<>();
for(int i=0;i<10;i++){
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("title","title:"+i);
hashMap.put("content","content:"+i);
hashMap.put("image",image_index[i]);
listItem.add(hashMap);
}
}
/*
* 这里定义ImageView的数组索引,适配器在设置ImageView背景的时候使用比较方便
* */
private final int[] image_index = {
R.drawable.ic_launcher,
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
R.drawable.image6,
R.drawable.image7,
R.drawable.image8,
R.drawable.image9,
};
/*
* convertView配合ViewHolder可以提高UI加载的效率,这里定义成static型
* 相当于全局保存布局文件中的View对象实例。
* */
static class ViewHolder{
TextView tv_item;
TextView tv_content;
ImageView iv_image;
Button btn_select;
CheckBox ck_box;
} private class HsAdapter extends BaseAdapter{
/*
* 这里需要解释一下LayoutInflater的用法:/**
* Instantiates a layout XML file into its corresponding {@link android.view.View}
* objects. It is never used directly. Instead, use
* {@link android.app.Activity#getLayoutInflater()} or
* {@link Context#getSystemService} to retrieve a standard LayoutInflater instance
* that is already hooked up to the current context and correctly configured
* for the device you are running on.
* 以上是源码的注释
* 首先这个是一个抽象对象,所以从来不会直接实例化来引用,而且它也没有任何的子类。
* 所以要使用这个类,唯一的办法就是:1、从Activity.getLayoutInflater()中获得
* 2、从上下文Context.getSystemService找回当前上下文连接的
* LayoutInflater实例。
* eg:LayoutInflater inflater = (LayoutInflater)context.getSystemService
* (Context.LAYOUT_INFLATER_SERVICE)
* 因此我们设置适配器构造函数的时候传入了Activity的布局解析器
* */
private LayoutInflater mInflator;
private ViewHolder viewHolder;
public HsAdapter(LayoutInflater mInflator){
this.mInflator = mInflator;
}
@Override
public int getCount() {
return listItem.size();
} @Override
public Object getItem(int position) {
System.out.println("getItem");
return null;
} @Override
public long getItemId(int position) {
System.out.println("getItemId:"+position);
return 0;
} @Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
/*
* 1.这段代码执行的次数与ListView的项数有关系,如果手机屏幕最大显示数目是6个,那么执行的次数
* 就是7次,最后会保留一个convertView实例在viewHolder中,并且保存在convertView的Tag中,
* 这样做的目的是当ListView滑动,显示变化需要加载新的Item的时候可以不用再执行这一段代码
* 直接用tag中保存的引用来填充Item,提高效率。这就是setTag()的目的。
* 2.注意viewHolder = new ViewHolder();与convertView = mInflator.inflate(R.layout.list_item, null);
* 是对应的,不然会引起空指针错误。
* 3.一段代码加载的原理就是:在ListView初始化的时候每加载一项Item都会执行一次getView,并且这个时候
* convertView都是空,如果反过来理解其实每一项viewHolder的引用都必须通过findViewById来指向一个实例,不然就会报错。
* 当屏幕最大显示的6项加载完毕,在多保留一个viewHolder引用备用就不会执行了。这个时候如果滑动ListView
* 需要加载新的Item,这个时候又会调用getView,而这个时候会直接用预留的一个convertView。如果继续滑动,
* 这个时候convertView并不为空,这是因为滑动的过程中除了会出现新的Item,旧的Item会移出屏幕不在显示,这个时候
* convertView其实装载的是旧的引用,如此循环,因此可以判断如果手机整个屏幕ListView最大显示的
* item的数据是n那么convertView的引用数据就是n+1了
* */
viewHolder = new ViewHolder();
convertView = mInflator.inflate(R.layout.list_item, null);
viewHolder.tv_item = (TextView)convertView.findViewById(R.id.tv_item);
viewHolder.iv_image = (ImageView)convertView.findViewById(R.id.iv_image);
viewHolder.tv_content = (TextView)convertView.findViewById(R.id.tv_content);
viewHolder.btn_select = (Button)convertView.findViewById(R.id.btn_select);
viewHolder.ck_box = (CheckBox)convertView.findViewById(R.id.ck_box); viewHolder.btn_select.setTag(position);//设置按键的 Tag辅助判断是哪一个按键按下,因为这里所有项的按键实体id只有一个所有需要
//position来辅助判断
viewHolder.btn_select.setOnClickListener(new KeyPressService());//设置按键监听一定要放在里面,因为getView调用的次数非常多
//而我们只需要对有效Item的按键设置监听。
viewHolder.ck_box.setTag(position);//同理按键
viewHolder.ck_box.setOnClickListener(new KeyPressService());//同理按键 convertView.setTag(viewHolder);//保存引用
}else{
viewHolder = (ViewHolder)convertView.getTag();
viewHolder.btn_select.setTag(position);
viewHolder.btn_select.setOnClickListener(new KeyPressService());
viewHolder.ck_box.setOnClickListener(new KeyPressService());
viewHolder.ck_box.setTag(position);
}
/*
* 这里就是适配器绑定数据源与View的过程。利用Map的数据结构可以方便找到
* 因为是HashMap<String,Object>返回的value是object所以要强转
* */
viewHolder.iv_image.setBackgroundResource((Integer) listItem.get(position).get("image"));
viewHolder.tv_item.setText((String) listItem.get(position).get("title"));
viewHolder.tv_content.setText((String) listItem.get(position).get("content")); return convertView;
}
} private class KeyPressService implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_select:
ClickEventProcess(v,"Button");
break;
case R.id.ck_box:
ClickEventProcess(v,"checkbox");
break;
} }
private void ClickEventProcess(View v,String str){ switch ((Integer)v.getTag()){
case 0:
Toast.makeText(MainActivity.this,"click:0"+str,Toast.LENGTH_SHORT)
.show();
break;
case 1:
Toast.makeText(MainActivity.this,"click:1"+str,Toast.LENGTH_SHORT)
.show();
break;
case 2:
Toast.makeText(MainActivity.this,"click:2"+str,Toast.LENGTH_SHORT)
.show();
break;
case 3:
Toast.makeText(MainActivity.this,"click:3"+str,Toast.LENGTH_SHORT)
.show();
break;
case 4:
Toast.makeText(MainActivity.this,"click:4"+str,Toast.LENGTH_SHORT)
.show();
break;
case 5:
Toast.makeText(MainActivity.this,"click:5"+str,Toast.LENGTH_SHORT)
.show();
break;
case 6:
Toast.makeText(MainActivity.this,"click:6"+str,Toast.LENGTH_SHORT)
.show();
break;
case 7:
Toast.makeText(MainActivity.this,"click:7"+str,Toast.LENGTH_SHORT)
.show();
break;
case 8:
Toast.makeText(MainActivity.this,"click:8"+str,Toast.LENGTH_SHORT)
.show();
break;
case 9:
Toast.makeText(MainActivity.this,"click:9"+str,Toast.LENGTH_SHORT)
.show();
break;
}
}
}
}

下面是程序执行的效果:

主界面的布局activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.skymaster.hs.baseadaptertest.MainActivity"> <ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/lv_list"/>
</RelativeLayout>

按键的drawable文件btn_normal.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="45dp"/>
<size android:height="10dp"
android:width="30dp"/>
<solid android:color="@color/colorPrimary"/>
</shape>

btn_press.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="45dp"/>
<size android:height="10dp"
android:width="30dp"/>
<solid android:color="@color/colorPrimary"/>
<stroke android:color="#ff0000"
android:width="10dp"/>
</shape>

btn_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/btn_press"/>
<item android:state_pressed="false" android:drawable="@drawable/btn_normal"/>
</selector>

ListView配合BaseAdapter的更多相关文章

  1. 第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter

    第29讲 UI组件之 ListView与 BaseAdapter,SimpleAdapter 1.BaseAdapter BaseAdapter是Android应用程序中经常用到的基础数据适配器,它的 ...

  2. ListView之BaseAdapter

    BaseAdapter可以实现自定义的丰富子项视图,本文实现如下所示结果: 实现代码: /* ListView :列表 BaseAdapter 通用的基础适配器 * * */ public class ...

  3. Android 杂谈---ListView 之BaseAdapter

    前言 几种适配器里面相对来说比较简单的一种适配器,在使用时需要实现几个方法,并且也需要对convertView进行优化 此篇文章以使用listView与BaseAdapter来实现表格样式的布局举例( ...

  4. andorid 列表视图 ListView 之BaseAdapter

    .xml <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android=&qu ...

  5. Android关于listView的BaseAdapter以及getView的三级优化

    1.4个重写方法的含义 自定义Adapter继承自BaseAdapter(通用适配器)   getCount(); getItem(); getItemId(); getViewTypaCount() ...

  6. android 中listview之BaseAdapter的使用

    Listview控件不像其他安卓控件那种直接拖拽到界面上就能用,而是采用类似J2EE中的MVC模型的方式使用,需要通过适配器将某种样式的数据或控件添加到其上而使用. MVC模型实现原理是 数据模型M( ...

  7. android ListView 和 BaseAdapter 应用

    步聚: 1.建立ListView对象:--(作用:绑定Adapter呈现数据) 2.建立ListView实现的Item栏位.xml布局:--(作用:实现ListView的栏位布局) 3.建立Item. ...

  8. ListView之BaseAdapter的使用

    话说开发用了各种Adapter之后感觉用的最舒服的还是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView.GridView.Gal ...

  9. 43.Android之ListView中BaseAdapter学习

    实际开发中个人觉得用的比较多是BaseAdapter,尽管使用起来比其他适配器有些麻烦,但是使用它却能实现很多自己喜欢的列表布局,比如ListView.GridView.Gallery.Spinner ...

随机推荐

  1. github pages搭建个人网站如何添加导航

    折腾过github pages的同学都清楚使用jekyll搭建个人网站的目录结构,而导航最终的代码是在使用的主题目录中的default.html文件中的. 我的结构如下: . ├── .html ├─ ...

  2. hdu 2053 Switch Game 水题一枚,鉴定完毕

    Switch Game Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  3. CentOS 安装ftp

    Linux安装ftp组件 1 安装vsftpd组件 安装完后,有/etc/vsftpd/vsftpd.conf 文件,是vsftp的配置文件. [root@bogon ~]# yum -y insta ...

  4. Annotation实战【自定义AbstractProcessor】

    前言 在使用Java的过程中,每个开发人员都接触过@Override, @Deprecated等等各式各样的注解,这些东西是java最基础的一些原生定义好的annotation.本文通过一个实例演示如 ...

  5. 2016年10月13日 星期四 --出埃及记 Exodus 18:24

    2016年10月13日 星期四 --出埃及记 Exodus 18:24 Moses listened to his father-in-law and did everything he said.于 ...

  6. python学习笔记三 函数(基础篇)

    函数 内置函数 常用的内建函数: type()  列出指定对象的类型 help()  能够提供详细的帮助信息 dir()    将对象的所有特性列出 vars()  列出当前模块的所有变量 file, ...

  7. 免费PHP WEB环境套件介绍

    PHPNOW--Apache + PHP + MySQL(windows) easyphp--Apache + PHP + MySQL+phpmyadmin(windows) xampp(中文站点)- ...

  8. 【Java】hashcode()和equals()

    大家知道,在集合中判断集合中的两个元素是否相同,依赖的是hashcode()和equals()两个方法. > 一个简单的实验 public class Teacher { private Int ...

  9. UIEdgeInsetsMake, CGRectOffset等API参数详解

    1, UIEdgeInsetsMake ( CGFloat top, CGFloat left, CGFloat bottom, CGFloat right ) 2,position点是相对suerL ...

  10. 【转载】Linux的进程间通信-信号量

    原文:Linux的进程间通信-信号量 Linux的进程间通信-信号量 版权声明: 本文章内容在非商业使用前提下可无需授权任意转载.发布. 转载.发布请务必注明作者和其微博.微信公众号地址,以便读者询问 ...