IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]Android ListView例子详解

    lincyang发表于 2012-01-06 20:00:50
    love 0

    三种实现方法,由浅入深。这中间要注意Adapter的用法,其实你要是看过Android的文档,你会发现有很多Adapter,

    如果你还不太清楚适配器模式,可以先补补这方面的知识。在实际工作中,设计模式是个很好的帮手。

    两个layout文件:

    main.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" >
    
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello" />
        
        <ListView 
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            ></ListView>
    
    </LinearLayout>

    listview.xml

    <?xml version="1.0" encoding="utf-8"?>  
    <LinearLayout  
      xmlns:android="http://schemas.android.com/apk/res/android"  
      android:id="@+id/linerlayout1"  
      android:orientation="vertical"  
      android:layout_height="fill_parent"  
      android:layout_width="fill_parent"  
      >  
         <TextView  
            android:id="@+id/person_name"  
            android:textSize="23sp"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
         />  
         <TextView  
            android:id="@+id/person_age"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
        />  
        <TextView  
            android:id="@+id/person_email"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
        />  
        <TextView  
            android:id="@+id/person_address"  
            android:layout_width="wrap_content"  
            android:layout_height="wrap_content"  
        />  
    </LinearLayout>  

    Activity:LincListViewActivity.java

    package com.linc.listview;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    
    public class LincListViewActivity extends Activity {
    	private final static String[] data = {"张飞","张辽","张角","张三丰","张牙舞爪","张灯结彩","张唑啉","张大民"};
    	
    	//创建数据源.  
        Zhang[] data2 = new Zhang[]{  
            new Zhang("张飞",38,"zhangfei@gmail.com","燕山"),  
            new Zhang("张辽",36,"zhangliao@sina.com","雁门"),  
            new Zhang("张角",51,"zhangjiao@gmail.com","钜鹿"),  
            new Zhang("张三丰",200,"sanfeng@gmail.com","辽东"),  
            new Zhang("张牙舞爪",25,"5zhao@gmail.com","冀州"),
            new Zhang("张灯结彩",25,"5zhao@gmail.com","冀州") ,
            new Zhang("张唑啉",25,"5zhao@gmail.com","冀州") ,
            new Zhang("张大民",25,"5zhao@gmail.com","冀州") ,
            new Zhang("张牙舞爪",25,"5zhao@gmail.com","冀州")  
        };  
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            
            ListView listview = (ListView)findViewById(R.id.listview);
            /*
             * 第一种:普通字符串
             */
            ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this, 
            		android.R.layout.simple_list_item_1,data);
            
            /*
             * 第二种:文艺类对象
             */
            ArrayAdapter<Zhang> adapter2 = new ArrayAdapter<Zhang>(this, 
            		android.R.layout.simple_list_item_1,data2);
            
            /*
             * 第三种:自定义适配器
             */
            ListAdapter adapter3 = new ListAdapter(this, R.layout.listview,data2) ;//okay, the resource id is passed.
            
            listview.setAdapter(adapter3);
        }
    }

    数据类对象:Zhang.java

    package com.linc.listview;
    
    public class Zhang {
    	       
        private String name;  
        private int age;  
        private String email;  
        private String address;  
        public String getName() {
    		return name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public String getEmail() {
    		return email;
    	}
    
    	public String getAddress() {
    		return address;
    	}
    
       
        public Zhang(String name, int age, String email, String address) {  
            super();  
            this.name = name;  
            this.age = age;  
            this.email = email;  
            this.address = address;  
        }  
       
        @Override  
        public String toString() {  
            return "Person [name=" + name + ", age=" + age + ", email=" + email  
                    + ", address=" + address + "]";  
        }  
       
    }  
    

    适配器类:ListAdapter.java

    package com.linc.listview;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ArrayAdapter;
    import android.widget.TextView;
    
    public class ListAdapter extends ArrayAdapter<Zhang> {
    	private LayoutInflater mInflater; 
    	
    	public ListAdapter(Context context, int textViewResourceId,Zhang[] obj) {
    		super(context, textViewResourceId,obj);
    		// TODO Auto-generated constructor stub
    		
    		this.mInflater = LayoutInflater.from(context);
    	}
    	
    	@Override
        public View getView(int position, View convertView, ViewGroup parent) {
    		if(convertView == null){  
                //创建新的view视图.  
                convertView = mInflater.inflate(R.layout.listview, null); //see above, you can use the passed resource id.
            }  
              
            ViewHolder holder = null;  
            if(holder==null){  
                holder = new ViewHolder();  
                //查找每个ViewItem中,各个子View,放进holder中  
                holder.name = (TextView) convertView.findViewById(R.id.person_name);  
                holder.age = (TextView) convertView.findViewById(R.id.person_age);  
                holder.email = (TextView) convertView.findViewById(R.id.person_email);  
                holder.address = (TextView) convertView.findViewById(R.id.person_address);  
                //保存对每个显示的ViewItem中, 各个子View的引用对象  
                convertView.setTag(holder);  
            }
            else// I think this a bug, program can not run here!!!--linc2014.11.12
            {
            	holder = (ViewHolder)convertView.getTag(); 
            }
              
            //获取当前要显示的数据  
            Zhang person = getItem(position);  
      
            holder.name.setText(person.getName());  
            holder.age.setText(String.valueOf(person.getAge()));  
            holder.email.setText(person.getEmail());  
            holder.address.setText(person.getAddress());  
            return convertView;
        }
        
    	private static class ViewHolder
    	{
    		TextView name;  
            TextView age;  
            TextView email;  
            TextView address;
    	}
    	
    	
    }
    

    更复杂的一个例子:单行与多行并存

    还可以参考:View Tag的介绍

    或者对比着GridView来学习一下它们的异同,Android自定义GridView之实现一个图片加多个文本框

    它们的Adapter一个是继承自ArrayAdapter,另一个是BaseAdapter。


    另外,API demo中相关的例子一定要看看。那才是真正的宝藏呢。

    下面直接给出List14源码:

    /*
     * Copyright (C) 2008 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.
     */
    
    package com.example.android.apis.view;
    
    import android.app.ListActivity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    import android.widget.ImageView;
    import android.graphics.BitmapFactory;
    import android.graphics.Bitmap;
    import com.example.android.apis.R;
    
    /**
     * Demonstrates how to write an efficient list adapter. The adapter used in this example binds
     * to an ImageView and to a TextView for each row in the list.
     *
     * To work efficiently the adapter implemented here uses two techniques:
     * - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
     * - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
     *
     * The ViewHolder pattern consists in storing a data structure in the tag of the view returned by
     * getView(). This data structures contains references to the views we want to bind data to, thus
     * avoiding calls to findViewById() every time getView() is invoked.
     */
    public class List14 extends ListActivity {
    
        private static class EfficientAdapter extends BaseAdapter {
            private LayoutInflater mInflater;
            private Bitmap mIcon1;
            private Bitmap mIcon2;
    
            public EfficientAdapter(Context context) {
                // Cache the LayoutInflate to avoid asking for a new one each time.
                mInflater = LayoutInflater.from(context);
    
                // Icons bound to the rows.
                mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
                mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
            }
    
            /**
             * The number of items in the list is determined by the number of speeches
             * in our array.
             *
             * @see android.widget.ListAdapter#getCount()
             */
            public int getCount() {
                return DATA.length;
            }
    
            /**
             * Since the data comes from an array, just returning the index is
             * sufficent to get at the data. If we were using a more complex data
             * structure, we would return whatever object represents one row in the
             * list.
             *
             * @see android.widget.ListAdapter#getItem(int)
             */
            public Object getItem(int position) {
                return position;
            }
    
            /**
             * Use the array index as a unique id.
             *
             * @see android.widget.ListAdapter#getItemId(int)
             */
            public long getItemId(int position) {
                return position;
            }
    
            /**
             * Make a view to hold each row.
             *
             * @see android.widget.ListAdapter#getView(int, android.view.View,
             *      android.view.ViewGroup)
             */
            public View getView(int position, View convertView, ViewGroup parent) {
                // A ViewHolder keeps references to children views to avoid unneccessary calls
                // to findViewById() on each row.
                ViewHolder holder;
    
                // When convertView is not null, we can reuse it directly, there is no need
                // to reinflate it. We only inflate a new View when the convertView supplied
                // by ListView is null.
                if (convertView == null) {
                    convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
    
                    // Creates a ViewHolder and store references to the two children views
                    // we want to bind data to.
                    holder = new ViewHolder();
                    holder.text = (TextView) convertView.findViewById(R.id.text);
                    holder.icon = (ImageView) convertView.findViewById(R.id.icon);
    
                    convertView.setTag(holder);
                } else {
                    // Get the ViewHolder back to get fast access to the TextView
                    // and the ImageView.
                    holder = (ViewHolder) convertView.getTag();
                }
    
                // Bind the data efficiently with the holder.
                holder.text.setText(DATA[position]);
                holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
    
                return convertView;
            }
    
            static class ViewHolder {
                TextView text;
                ImageView icon;
            }
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setListAdapter(new EfficientAdapter(this));
        }
    
        private static final String[] DATA = Cheeses.sCheeseStrings;
    }
    




沪ICP备19023445号-2号
友情链接