Android各类Adapter的用法

 Android各类Adapter的用法

  一样是一个ListView,能够用不一样的java

Adapter让它显示出来,好比说最经常使用的ArrayAdapter,SimpleAdapter,SimpleCursorAdapter,以及重写BaseAdapter等方法。

  ArrayAdapter比较简单,但它只能用于显示文字。而SimpleAdapter则有很强的扩展性,能够自定义出各类效果,SimpleCursorAdapter则能够从数据库中读取数据显示在列表上,经过从写BaseAdapter能够在列表上加处理的事件等。

  下面先来看看ArrayAdapter:
android

package com.shang.test;

 import java.util.ArrayList;

 import android.app.Activity;
 import android.os.Bundle;
 import android.widget.ArrayAdapter;
 import android.widget.ListView;

 /**
 * 
 * @author shangzhenxiang
 *
 */
 public class TestArrayAdapterActivity extends Activity{

    private ListView mListView;
    private ArrayList<String> mArrayList = new ArrayList<String>();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testarrayadapter);
        mListView = (ListView) findViewById(R.id.myArrayList);
        mListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData()));
    }
    
    private ArrayList<String> getData() {
        mArrayList.add("测试数据1");
        mArrayList.add("测试数据2");
        mArrayList.add("测试数据3");
        mArrayList.add("测试数据4");
        mArrayList.add("测试数据5");
        mArrayList.add("测试数据6");
        return mArrayList;
    }
}

布局里面有个ListView就能够了:git

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="fill_parent">
    <TextView  
        android:layout_width="match_parent" 
        android:layout_height="wrap_content" 
        android:text="@string/hello"/>
    <ListView
        android:id="@+id/myArrayList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>    
 </LinearLayout>

  上面的代码中用到了ArrayAdapter的构造方法:数据库

public ArrayAdapter (Context context, int textViewResourceId, T[] objects)

Api中是这么描述的:express


其中Context为当前的环境变量,能够显示一行文字的一个布局文件,和一个List的集合,也就是数据源。apache

布局文件能够本身写,也能够用系统的,我这里是用的系统的。本身写的布局中包含一个TextView就能够了,固然系统中也有包含一个TextView的布局文件:就是 android.R.layout.simple_expandable_list_item_1,调用这个比较方便。数组

这里给出运行后的效果图:app

  


下面说说SimpleCursorAdapter:less

  Api中是这么说的:An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file. You can specify which columns you want, which views you want to display the columns, and the XML file that defines the appearance of these views.ide

  简单的说就是 方便把Cursor中获得的数据进行列表显示,并能够把指定的列映射到指定的TextView上。

  我这里写的是从联系人中拿到数据并显示在列表上。代码以下:

package com.shang.test;

 import android.app.Activity;
 import android.database.Cursor;
 import android.os.Bundle;
 import android.provider.Contacts.People;
 import android.widget.ListView;
 import android.widget.SimpleCursorAdapter;

 /**
 * 
 * @author shangzhenxiang
 *
 */
public class TestSimpleCursorAdapter extends Activity {

    private ListView mListView;
    private Cursor mCursor;
    private SimpleCursorAdapter mAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testsimplecursoradapter);
        mListView = (ListView) findViewById(R.id.mySimpleCursorList);
        mCursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
        startManagingCursor(mCursor);
        mAdapter = new SimpleCursorAdapter(TestSimpleCursorAdapter.this, android.R.layout.simple_expandable_list_item_1, mCursor, new String[]{People.NAME}, new int[]{android.R.id.text1});
        mListView.setAdapter(mAdapter);
    }
}

mCursor = getContentResolver().query(People.CONTENT_URI, null, null, null, null);是先得到一个指向系统联系人的Cursor

startManagingCursor(mCursor);是指咱们把Cursor交给这个Activity保管,这样Cursor便会和Activity同步,咱们不用手动管理了。

simpleCursorAdapter API中是这样说的:

其中前面的2个参数跟ArrayAdapter中是同样的,第三个参数是传个来的参数, 其实也是数据源,后面的2个参数是2个数组,前一个是String【】类型的,然后一个是int【】类型的,说明前一个参数中的值对应的是从数据库中的字 段,后一个是布局文件中和这个字段对应的id,也就是说这个字段对应得值要显示在哪里(好比说咱们这里查到的联系人中的NAME字段,要显示在一个对应的 TextView上面)。

这里咱们具体看一下系统的布局,也就是咱们这里的第二个参数的布局,便于理解,android.R.layout.simple_expandable_list_item_1.xml文件中是这么写的:

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2006 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:gravity="center_vertical"
/>

注意他有一个id,这个id也是系统的id,这个布局中只有一个TextView,因此只能显示一个字段,咱们这里显示的联系人的名字,

而最后的一个参数就是由这么写id组成的一个数据(若是有不少TextView的话)。好比说咱们要显示不少字段,布局文件中就要写不少TextView,而每个TextView都有一个ID,第三个参数中有多少个字段,第四个参数中就有多少个id,并一一对应。

咱们来看一下运行效果图:

上面说到的2种方法都是显示的文字,比方说咱们要显示图片怎么办呢,还要显示不少内容,还要按本身喜欢的布局排列怎么办呢,用SimpleAdapter,扩展性好,能够定义各类各样的布局。

代码以下:

package com.shang.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

/**
 * 
 * @author shangzhenxiang
 *
 */
public class TestSimpleAdapter extends Activity {

    private ListView mListView;
    private SimpleAdapter mAdapter;
    private List<HashMap<String, Object>> mHashMaps;
    private HashMap<String, Object> map;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.testsimpleadapter);
        mListView = (ListView) findViewById(R.id.mySimpleList);
        mAdapter = new SimpleAdapter(this, getData(), R.layout.simpleitem, new String[]{"image", "title", "info"}, new int[]{R.id.img, R.id.title, R.id.info});
        mListView.setAdapter(mAdapter);
    }
    
    private List<HashMap<String, Object>> getData() {
        mHashMaps = new ArrayList<HashMap<String,Object>>();
        map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_1);
        map.put("title", "G1");
        map.put("info", "google 1");
        mHashMaps.add(map);
        
        map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_2);
        map.put("title", "G2");
        map.put("info", "google 2");
        mHashMaps.add(map);
        
        map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_3);
        map.put("title", "G3");
        map.put("info", "google 3");
        
        mHashMaps.add(map);
        return mHashMaps;
    }
}

simpleAdapter的数据都是用HashMap构成的List,List里面的每一节对应的是ListView的没一行,这里先建一个HashMap构成的List,布局中有3个元素,ImageView,2个TextView,每一个item项的布局文件以下:

<?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 
        android:layout_width="wrap_content" 
        android:id="@+id/img" 
        android:layout_margin="5px"
        android:layout_height="wrap_content">
        </ImageView>
    <LinearLayout 
        android:id="@+id/linearLayout1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView 
            android:id="@+id/title" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:textSize="22px"></TextView>
        <TextView 
            android:id="@+id/info" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:textSize="13px"></TextView>
    </LinearLayout>
</LinearLayout>

因此有了HashMap构成的数组后,咱们要在HashMap中加入数据,按顺序加入图片,title,info,一个HashMap就构成了ListView中的一个Item项,咱们在看下API中是怎么描述simpleAdapter的:


第一个参数和第三个参数跟ArrayAdapter中的是同样的,第二个参数就是由HashMap组成的List,也就是数据源,而第5个参数也就是map中的key,最后一个参数就是map中key对应的值要显示在布局中的位置的id。

看下效果:


若是咱们想在每一个Item中加个button,并且点击button有对应的操做,那该怎么办呢。

这时咱们能够重写baseAdapter,看代码:

package com.shang.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
 * 
 * @author shangzhenxiang
 *
 */
public class TestBaseAdapter extends Activity {

    private ListView mListView;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.baseadapterlist);
        mListView = (ListView) findViewById(R.id.baselist);
        mListView.setAdapter(new BaseListAdapter(this));
    }
    
    private List<HashMap<String, Object>> getData() {
        List<HashMap<String, Object>> maps = new ArrayList<HashMap<String,Object>>();
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_1);
        map.put("title", "G1");
        map.put("info", "google 1");
        maps.add(map);
        
        map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_2);
        map.put("title", "G2");
        map.put("info", "google 2");
        maps.add(map);
        
        map = new HashMap<String, Object>();
        map.put("image", R.drawable.gallery_photo_3);
        map.put("title", "G3");
        map.put("info", "google 3");
        maps.add(map);
        return maps;
    }
    
    private class BaseListAdapter extends BaseAdapter implements OnClickListener {

        private Context mContext;
        private LayoutInflater inflater;
        
        public BaseListAdapter(Context mContext) {
            this.mContext = mContext;
            inflater = LayoutInflater.from(mContext);
        }
        
        @Override
        public int getCount() {
            return getData().size();
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;
            if(convertView == null) {
                viewHolder = new ViewHolder();
                convertView = inflater.inflate(R.layout.testbaseadapter, null);
                viewHolder.img = (ImageView) convertView.findViewById(R.id.img);
                viewHolder.title = (TextView) convertView.findViewById(R.id.title);
                viewHolder.info = (TextView) convertView.findViewById(R.id.info);
                viewHolder.button = (Button) convertView.findViewById(R.id.basebutton);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
            
            System.out.println("viewHolder = " + viewHolder);
            viewHolder.img.setBackgroundResource((Integer) getData().get(position).get("image"));
            viewHolder.title.setText((CharSequence) getData().get(position).get("title"));
            viewHolder.info.setText((CharSequence) getData().get(position).get("info"));
            viewHolder.button.setOnClickListener(this);
            
            return convertView;
        }
        
        class ViewHolder {
            ImageView img;
            TextView title;
            TextView info;
            Button button;
        }

        @Override
        public void onClick(View v) {
            int id = v.getId();
            switch(id) {
            case R.id.basebutton:
                showInfo();
                break;
            }
        }

        private void showInfo() {
            new AlertDialog.Builder(TestBaseAdapter.this).setTitle("my listview").setMessage("introduce....").
            setPositiveButton("OK", new DialogInterface.OnClickListener() {
                
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // TODO Auto-generated method stub
                    
                }
            }).show();
        }
    }
}

在看下item的布局文件:

<?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 
        android:layout_width="wrap_content" 
        android:id="@+id/img" 
        android:layout_margin="5px"
        android:layout_height="wrap_content">
        </ImageView>
    <LinearLayout 
        android:id="@+id/linearLayout1" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <TextView 
            android:id="@+id/title" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:textSize="22px"></TextView>
        <TextView 
            android:id="@+id/info" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:textColor="#ffffff"
            android:textSize="13px"></TextView>
    </LinearLayout>
    
    <Button
        android:id="@+id/basebutton"
        android:text="more"
        android:focusable="false"
        android:layout_gravity="bottom|right"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"/>
</LinearLayout>

  listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值获得listView的长度(这也是为何在开始的第一张图特 别的标出列表长度),而后根据这个长度,调用getView()逐一绘制每一行。若是你的getCount()返回值是0的话,列表将不显示一样 return 1,就只显示一行。

  若是咱们要自定义适配器,那就要重写getView方法,getView()有三个参数,position表示将显示的是第几 行,covertView是从布局文件中inflate来的布局。咱们写一个类来描述布局文件中的各个组件,好比ImageView,TextView 等,而后判断convertView是否为空,若是为空就从inflate中拿到布局,并新建一个ViewHolder,而后从convertView中 拿到布局中的各个组件,同时把ViewHolder放到tag中去,下次就不用重写new了,直接从tag中拿就能够了,而后把布局中的各个组件都设上对 应的值,这里的Position对应到含有HashMap的List中的position。

在实际的运行过程当中会发现listView的每一行没有焦点了,这是由于Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了。

看下运行效果:

源代码:

源代码

相关文章
相关标签/搜索