zoukankan      html  css  js  c++  java
  • Android Adapter 与 Listview

    一、Adapter,BaseAdapter

        BaseAdapter应用程序中经常用到的基础数据适配器,它的主要用途是将一组数据传到像ListView、Spinner、Gallery及GridView等UI显示组件,它是继承自接口类Adapter,Adapter有如下结构:

    Public Methods
                abstract                                                            int getCount()
    How many items are in the data set represented by this Adapter.
                abstract                                                            Object getItem(int position)
    Get the data item associated with the specified position in the data set.
    abstract long getItemId(int position)
    Get the row id associated with the specified position in the list.
                abstract                                                            int getItemViewType(int position)
    Get the type of View that will be created by getView(int, View, ViewGroup) for the specified item.
                abstract                                                            View getView(int position, View convertView, ViewGroup parent)
    Get a View that displays the data at the specified position in the data set.
                abstract                                                            int getViewTypeCount()

    Returns the number of types of Views that will be created by getView(int, View, ViewGroup).

                abstract                                                            boolean hasStableIds()
    Indicates whether the item ids are stable across changes to the underlying data.
                abstract                                                            boolean isEmpty()
                abstract                                                            void registerDataSetObserver(DataSetObserver observer)
    Register an observer that is called when changes happen to the data used by this adapter.
                abstract                                                            void unregisterDataSetObserver(DataSetObserver observer)
    Unregister an observer that has previously been registered with this adapter via registerDataSetObserver(DataSetObserver).

      

    BaseAdapter用的最多,BaseAdapter实现了ListAdapter和SpinnerAdapter两个接口,当然它也可以直接给ListView和Spinner等UI组件直接提供数据。使用BaseAdapter必须写一个类继承它,同时BaseAdapter是一个抽象类,继承它必须实现它的方法。BaseAdapter的灵活性就在于它要重写很多方法,其中最重要的即为getView()方法,当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回1,那么只显示一行。而getItem()getItemId()则在需要处理和取得Adapter中的数据时调用。查阅关于getView方法的api手册如下:


    public abstract View getView(int position, View convertView, ViewGroup parent) 

    Get a View that displays the data at the specified position in the data set. You can either create a View manually or inflate it from an XML layout file. When the View is inflated, the parent View (GridView, ListView...) will apply default layout parameters unless you use inflate(int, android.view.ViewGroup, boolean) to specify a root view and to prevent attachment to the root.

    Parameters

    position

    The position of the item within the adapter's data set of the item whose view we want.

    convertView

    The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)).

    parent

    The parent that this view will eventually be attached to

    Returns

    A View corresponding to the data at the specified position.


     二、使用自定义Adapter承载的ListView

      常用的Adapter:BaseAdapter,ArrayAdapter,SimpleAdapter和SimpleCursorAdapter,ArrayAdapter最为简单,只能展示一行字。SimpleAdapter有最好的扩充性,可以自定义出各种效果。 BaseAdapter自由度更高,SimpleAdpater 是BaseAdapter的子类之一。SimpleCursorAdapter可以认为是SimpleAdapter对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。这里两个Demo分别使用SimpleAdapter和BaseAdapter来实现两种功能自由度比较高的ListView。

    1,SimpleAdapter Demo

    构建一个显示图片和文字的ListView,捕获点击和长按的操作。

    ListItem的XML实现,data.xml

    <?xml version="1.0" encoding="utf-8"?>
        <RelativeLayout 
            android:id="@+id/RelativeLayout01" 
            android:layout_width="fill_parent" 
            xmlns:android="http://schemas.android.com/apk/res/android" 
            android:layout_height="wrap_content" 
            android:paddingBottom="4dip" 
            android:paddingLeft="12dip"
            android:paddingRight="12dip">
            <ImageView 
                android:paddingTop="12dip"
                android:layout_alignParentRight="true"
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content" 
                android:id="@+id/ItemImage"
            /> 
            <TextView 
                android:text="TextView01" 
                android:layout_height="wrap_content" 
                android:textSize="20dip" 
                android:layout_width="fill_parent" 
                android:id="@+id/ItemTitle"
            />
            <TextView 
                android:text="TextView02" 
                android:layout_height="wrap_content" 
                android:layout_width="fill_parent" 
                android:layout_below="@+id/ItemTitle" 
                android:id="@+id/ItemText"
            />
        </RelativeLayout>

    /layout/activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 
        android:id="@+id/LinearLayout01" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        xmlns:android="http://schemas.android.com/apk/res/android">
    
        <ListView
            android:id="@+id/ListView01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" >
        </ListView>
    </LinearLayout>

    MainActivity.java

    捕获点击和长按的操作,并且在menu里面加入点击导航到另外一个Baseadapter demo里面

    public class MainActivity extends Activity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            //绑定Layout里面的ListView  
            ListView list = (ListView) findViewById(R.id.ListView01);  
            
          //生成动态数组,加入数据  
            ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();  
            for(int i=0;i<20;i++)  
            {  
                HashMap<String, Object> map = new HashMap<String, Object>();  
                map.put("ItemImage", R.drawable.ic_launcher);//图像资源的ID  
                map.put("ItemTitle", "Title"+i);  
                map.put("ItemText", "the info of this Item!");  
                listItem.add(map);  
            }  
            
          //生成适配器的Item和动态数组对应的元素  
            SimpleAdapter listItemAdapter = new SimpleAdapter(this,listItem,//数据源   
                R.layout.data,//ListItem的XML实现  
                //动态数组与ImageItem对应的子项          
                new String[] {"ItemImage","ItemTitle", "ItemText"},   
                //ImageItem的XML文件里面的一个ImageView,两个TextView ID  
                new int[] {R.id.ItemImage,R.id.ItemTitle,R.id.ItemText}  
            );
            
          //添加并且显示  
            list.setAdapter(listItemAdapter);  
            
          //添加点击  
            list.setOnItemClickListener(new  AdapterView.OnItemClickListener() {  
    
                @Override
                public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                        long arg3) {
                    // TODO Auto-generated method stub
                    setTitle("点击第"+arg2+"个项目");  
                    
                }  
            });  
            
          //添加长按点击  
            list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  
    
                @Override
                public void onCreateContextMenu(ContextMenu arg0, View arg1,
                        ContextMenuInfo arg2) {
                    // TODO Auto-generated method stub
                    arg0.setHeaderTitle("长按菜单-ContextMenu");     
                    arg0.add(0, 0, 0, "弹出长按菜单0");  
                    arg0.add(0, 1, 0, "弹出长按菜单1");  
                    
                }  
            }); 
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            MenuItem menuItem= menu.getItem(0);
            menuItem.setTitle("自定义ListView");
            menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
                
                public boolean onMenuItemClick(MenuItem item) {
                    // TODO Auto-generated method stub
                    Intent intent=new Intent();     
    
                    intent.setClass(MainActivity.this, SecondActivity.class);
                    MainActivity.this.startActivity(intent);
                    return false;
                }
            });
            return true;
        }
        
        //长按菜单响应函数  
        @Override  
        public boolean onContextItemSelected(MenuItem item) {  
            setTitle("点击了长按菜单里面的第"+item.getItemId()+"个项目");   
            return super.onContextItemSelected(item);  
        }  
    
    }

    2,BaseAdapter demo

     实现带Checkbox的ListView

    ListItem的XML实现,m_data.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="fill_parent"
        android:orientation="horizontal" >
                    <ImageView    
                    android:id="@+id/img"   
                    android:layout_width="wrap_content"   
                    android:layout_height="wrap_content"   
                    android:layout_gravity="center_vertical"/>    
                    <TextView    
                    android:id="@+id/title"   
                    android:textSize="18dip"   
                    android:layout_weight="1"
                    android:textStyle="bold"
                    android:gravity="center_horizontal|center_vertical"   
                    android:layout_width="wrap_content"   
                    android:layout_height="wrap_content"/>    
                    <CheckBox    
                    android:id="@+id/cb"   
                    android:layout_width="wrap_content"   
                    android:layout_height="wrap_content"   
                    android:focusable="false"   
                    android:focusableInTouchMode="false"   
                    android:clickable="false"   
                    android:checkMark="?android:attr/listChoiceIndicatorMultiple"/>    
    </LinearLayout>

    /layout/second_activity.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="fill_parent"
        android:orientation="vertical" >
        <ListView    
        android:id="@+id/lv"   
        android:layout_width="fill_parent"   
        android:layout_height="wrap_content"/> 
    </LinearLayout>

     MyListViewAdapter.java

    自定义Adapter MyListViewAdapter

    public class MyListViewAdapter extends BaseAdapter{
        private LayoutInflater mInflater;
        private List<Map<String, Object>> mData;
        public static Map<Integer, Boolean> isSelected;   //记录checkbox状态的
        String  [] string ={"Title"};
        int  [] img ={R.drawable.ic_launcher};
        public MyListViewAdapter(Context context ){
            mInflater = LayoutInflater.from(context);   
            init();
        }
        private void init() {
            // TODO Auto-generated method stub
            mData=new ArrayList<Map<String, Object>>();    
            for(int i=0;i<100;i++){
                Map<String,Object> map=new HashMap<String, Object>();
                map.put("img",img[0]);
                map.put("title",string[0] );
                mData.add(map);
            }
            
            //这儿定义isSelected这个map是记录每个listitem的状态,初始状态全部为false。
            isSelected = new HashMap<Integer, Boolean>();    
            for(int i=0;i<mData.size();i++){
                isSelected.put(i, false);
            }
        }
        
        public int getCount(){
            return mData.size();
        }
        public Object getItem(int position){
            return null;
        }
        public long getItemId(int position){
            return 0;
        }
        public View getView(int position,View convertView,ViewGroup parent) {
            ViewHolder holder = null;//
            if(convertView==null){
                holder=new ViewHolder();
                convertView = mInflater.inflate(R.layout.m_data, null);    
                holder.img = (ImageView) convertView.findViewById(R.id.img); 
                holder.title = (TextView) convertView.findViewById(R.id.title);    
                holder.cBox = (CheckBox) convertView.findViewById(R.id.cb);    
                convertView.setTag(holder);    
            }else {
                holder = (ViewHolder) convertView.getTag();    
            }
            holder.img.setBackgroundResource((Integer) mData.get(position).get( "img"));    
            holder.title.setText(mData.get(position).get("title").toString());    
            holder.cBox.setChecked(isSelected.get(position));    
        return convertView; 
        }
    }

    临时存储器ViewHoder类

    public final class ViewHolder {
        public ImageView img;
        public TextView  title;
        public CheckBox  cBox;
    }

    从MainActivity跳转到的第二个Activity:SecondActivity.java

    public class SecondActivity extends Activity {
        
        private  ListView  listview;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.second_activity);
            
            listview =(ListView)findViewById(R.id.lv);
            MyListViewAdapter  myListViewAdapter=new MyListViewAdapter(this);
            listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
            listview.setItemsCanFocus(false);
            listview.setAdapter((ListAdapter) myListViewAdapter);
            
            listview.setOnItemClickListener(clickListener);
            listview.getCheckedItemPositions();
        }
        private OnItemClickListener clickListener=new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position,long id){
                ViewHolder vHollder = (ViewHolder) view.getTag(); 
                //在每次获取点击的item时将对于的checkbox状态改变,同时修改map的值。
                vHollder.cBox.toggle();    
                MyListViewAdapter.isSelected.put(position, vHollder.cBox.isChecked());
            }
        }; 
        
    }

    效果图:


    demo的java包均没有包含,需要根据提示自行导入。

    刚接触android编程,发现java和C#如此相近,eclipse也用起来很顺手。

  • 相关阅读:
    mysql 5.7 安装手册(for linux)
    Git服务器分类
    Git服务器安装详解及安装遇到问题解决方案
    使用git进行版本管理
    Git 忽略一些文件不加入版本控制
    Windows下搭建基于SSH的Git服务器
    linux系统下mysql跳过密码验证登录和创建新用户
    阅读《不止代码》之心得分享
    Sonar安装和常见问题解决
    Eclipse安装Sonarlint插件
  • 原文地址:https://www.cnblogs.com/xiepeixing/p/3117471.html
Copyright © 2011-2022 走看看