ListView与Adapter

ListView在Android中是专门用于显示列表的,是要是View的子类,都可以在ListView中显示出来,它以垂直列表的形式显示所有列表项。每一个条目都是一View对象

     ListView生成列表视图有两种方式:

         (1)直接使用ListView进行创建

           (2)让Activity继承ListActivity(相当于该Activity显示的组件为ListView)

一旦在程序中获得了ListView之后,接下来就需要为ListView设置它要显示的列表项了。在这一点上,ListView显示出AdapterView的特征,通过setAdapter(Adapter)方法为之提供Adapter,并有Adapter提供列表项即可。

Adapter本身只是一个接口,因此我们要用Adapter提供数据的话,就要使用它的实现类。

        Adapter常用的实现类如下:

 ArrayAdapter:简单,易用的Adapter,通用用于将数组或List集合的多个值包装成多个列表项

 SimpleAdapter:它不像它的名字一个简单,它是功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。

BassAdapter:通常用于被扩展。扩展BaseAdapter可以对各项列表进行最大限度的定制。

 Demo如下:

    (1): ArrayAdapter: 数组适配器,只能处理一种数据类型。当需要处理一种数据类型的时候可以用ArrayAdapter。它的列表项只能是TextView.

     首先定义两个ListView,在activity_main.xml中

<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity" >

    <ListView   
         android:id="@+id/list_view1"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:divider="#f00"  //设置listView的分割符为红色
        android:dividerHeight="2px" //设置分隔符高
        android:headerDividersEnabled="false"  //设置为false,则不在header View之后绘制分隔符     
        />
    
</LinearLayout>
      再定义Textview用于显示数据在array_item.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"
    android:orientation="vertical" >
    
    <TextView 
         android:id="@+id/tv_view"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:textSize="24dp"
         android:padding="10px"
         android:shadowDx="4"  //设置文本框内文本的阴影在水平方向的偏移
         android:shadowDy="4"   //在垂直方向的偏移
         android:shadowRadius="2"    //设置文本框内文本的阴影在模糊程度,该值越大,阴影越模糊
        /
</LinearLayout>

   最后实现功能在MainActivity.java

 

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
 		
      ListView listView1=(ListView) findViewById(R.id.list_view1);
		//定义一个数组
       String[] arr1 ={"孙悟空","猪八戒","沙僧"};
       //将数组包装为ArrayAdapter
       ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,R.layout.array_item, R.id.tv_view,arr1);
       //为ListView设置Adapter
       listView1.setAdapter(adapter1);

}
程序运行结果如下:

      

解释:

new ArrayAdapter<String>(Context context, int resource, int textViewResourceId, String[] objects)

     参数:

       参数一:context:它代表了访问整个Android应用的接口

      参数二: resource: 布局文件的资源id. ListView的每个条目都是一个View对象,则View对象是怎么来的,由布局文件填充而来。

      参数三:textViewResourceId:一个资源ID,该资源id代表一TextView,该TextView组件将作为ArrayAdapter的列表项组件,来显示数据。

      参数四:objects : 数组或List, 该数组或List将负责为多个列表项提供数据。把要显示的数据放在这里就可以了。

 

(2)SimpleAdapter: 比ArrayAdapter强大,可以处理多种数据。

      1)首先定义ListView在activity_main.xml中

<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity" >

    <ListView   
         android:id="@+id/mylist"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"  
        />
</LinearLayout>
       2)定义布局文件simple_item.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"
    android:orientation="horizontal" >
    <!-- 定义一个ImageView,用于作为列表项的一部分。 -->
       <ImageView 
            android:id="@+id/header"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="10dp"
           />
       
            <LinearLayout 
                   android:layout_width="match_parent"
                   android:layout_height="wrap_content"
                   android:orientation="vertical"
                >
                <TextView 
                     android:id="@+id/name"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:textSize="20dp"
                     android:textColor="#f0f"
                     android:paddingLeft="10dp"
                    />
                
                 <TextView
                        android:id="@+id/desc"
	                    android:layout_width="wrap_content" 
                   	   android:layout_height="wrap_content"
	                    android:textSize="14dp"
	                    android:paddingLeft="10dp"
	                    />

            </LinearLayout>
</LinearLayout>
   3) 实现功能在MainActivity.java

public class MainActivity extends Activity {

	       private  String[] names =new String[]{"虎头", "弄玉", "李清照", "李白"};
			private String[] desc=new String[]{"可爱的小孩", "一个擅长音乐的女孩"
					, "一个擅长文学的女性", "浪漫主义诗人"};
			private int[] imageIds=new int[]{R.drawable.tiger,R.drawable.nongyu,R.drawable.qingzhao,R.drawable.libai};
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		// 创建一个List集合,List集合的元素是Map
         List<Map<String, Object>> listItems= new ArrayList<Map<String,Object>>();
       for(int i=0;i<names.length;i++){
    	    Map<String, Object> listItem = new HashMap<String, Object>();
    	    listItem.put("header", imageIds[i]);
    	    listItem.put("personName", names[i]);
    	    listItem.put("desc", desc[i]); 
    	    listItems.add(listItem);
       }
    // 创建一个SimpleAdapter     使用simple_item.xml 文件作为列表项组件
       SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item,
    		   new String[]{"personName","header","desc"},new int[]{R.id.name,R.id.header,R.id.desc});
          
         ListView list=     (ListView) findViewById(R.id.mylist);
         list.setAdapter(simpleAdapter);
         
         //为listView的列表项的单击事件绑定事件监视器
         list.setOnItemClickListener(new OnItemClickListener() {

        	 //第position项被单击时激发该方法
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
                   				System.out.println(names[position]+"被单击了");
			}
         });
         
      // 为ListView的列表项的选中事件绑定事件监听器
         list.setOnItemSelectedListener(new OnItemSelectedListener() {

        	// 第position项被选中时激发该方法
			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				System.out.println(names[position]+ "被选中了");
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {
				
			}
		});
	}
}

 程序运行如下:


 
解释:new 
SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

 参数一: 见Demo1   

参数二: List<? extends Map<String, ?>> data:  该参数应该是一个List<?extends Map<String,?>>类型的集合对象,该集合中每个Map<String,?>对象生成一个列表项。负责提供数据

参数三:该参数指定一个界面布局的的Id                  负责提供列表项组件

 参数四: 该参数应该是一个String[]类型的参数,该参数决定提取Map<String,?>对象中哪些key对应的value来生成列表项。

参数五:该参数应该是一个int[]类型的参数,该参数巨大填充哪些组件
     第5个参数,第4个 参数指定使用id为R.id.name组件显示personName对应的值,是用id为R.id.header显示header对应的值,使用id为R.id.desc 的组件显示desc对应的值。这样第一个列表项组件所包含的三个组件都有了显示内容,后面的每个列表项依次类推。  

(3)BaseAdapter:扩展BaseAdapter可以取得对Adapter最大的控制权,程序要创建多少个列表项,每个列表项的组件都由开发者来决定。

    1)首先定义ListView在activity_main.xml中

<LinearLayout 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:orientation="vertical"
    tools:context=".MainActivity" >

    <ListView   
         android:id="@+id/mylist"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"  
        />
    
</LinearLayout>
    2)实现功能在MainActivity.java

        

public class MainActivity extends Activity {	
	private ListView mList;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	   mList = (ListView) findViewById(R.id.mylist);
	   BaseAdapter adapter = new BaseAdapter() {
		
		// 重写该方法,该方法返回的View将作为列表项
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			// 创建一个LinearLayout,并向其中添加两个组件
			LinearLayout line = new LinearLayout(MainActivity.this);
			line.setOrientation(0); //水平布局
			
			ImageView image = new ImageView(MainActivity.this);
			image.setImageResource(R.drawable.ic_launcher);
			TextView text = new TextView(MainActivity.this);
			text.setText("第" + (position +1 ) + "个列表项");
			text.setTextSize(20);
			text.setTextColor(Color.RED);
			
			line.addView(image);
			line.addView(text);
			// 返回LinearLayout实例
			return line;
		}
		
		// 重写该方法,该方法的返回值将作为列表项的ID
		@Override
		public long getItemId(int position) {
			return position;
		}
		
		@Override
		public Object getItem(int position) {
			return null;
		}
		
		// 指定一共包含40个选项
		@Override
		public int getCount() {
			return 40;
		}
	};
	   mList.setAdapter(adapter);
  
	}
}
程序运行结果如下:




解释:扩展BaseAdapter对象需要重写如下4个方法:

  getCount(): 该方法的返回值控制该Adapter将会包含多少个列表项,系统调用此方法,用来获知模型层有多少条数据

 getItem(int position): 该方法的返回值决定第position处的列表项的内容

getItemId(int position):该方法的返回值决定第 position处的列表项的id.

getView(int position,View convertView,ViewGroup parent):该方法的返回值决定第position出的列表项组件,系统调用此方法,获取要显示至ListView的View对象;

    position:本次getView方法调用所返回的View对象,ListView中处于第几个条目,那么position的值就是多少

     屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕。

   convertView:系统缓存的条目,当有缓存是直接把convertViewView,就不需要填充新的View对象了

   ListView的缓存机制:

   当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存,所有不论是否有缓存,都要重新设置TextView的值。

    BaseAdapter: 里面的代码是我们自己写的,进行高度的封装。所以它能完成的功能就比较多,比其它的Adapter。但是如果需求不是很复杂的话,用BaseAdapter的子类是更方便的。









         


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值