• Android开发学习——ListView+BaseAdapter的使用


    ListView

    就是用来显示一行一行的条目的
    MVC结构
     * M:model模型层,要显示的数据           ————people集合
     * V:view视图层,用户看到的界面          ————ListView
     * c:control控制层,操作数据如何显示     ————adapter对象
    每一个条目都是一个View对象
    BaseAdapter
    * 必须实现的两个方法

     * 第一个

       //系统调用此方法,用来获知模型层有多少条数据
       @Override
       public int getCount() {
        return people.size();
       }

     * 第二个

       //系统调用此方法,获取要显示至ListView的View对象
       //position:是return的View对象所对应的数据在集合中的位置
       @Override
       public View getView(int position, View convertView, ViewGroup parent) {
        System.out.println("getView方法调用" + position);
        TextView tv = new TextView(MainActivity.this);
        //拿到集合中的元素
        Person p = people.get(position);
        tv.setText(p.toString());
        
        //把TextView的对象返回出去,它会变成ListView的条目
        return tv;
       }
    屏幕上能显示多少个条目,getView方法就会被调用多少次,屏幕向下滑动时,getView会继续被调用,创建更多的View对象显示至屏幕
    条目的缓存
    当条目划出屏幕时,系统会把该条目缓存至内存,当该条目再次进入屏幕,系统在重新调用getView时会把缓存的条目作为convertView参数传入,但是传入的条目不一定是之前被缓存的该条目,即系统有可能在调用getView方法获取第一个条目时,传入任意一个条目的缓存

    代码如下:

    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"
        
        tools:context="com.example.list.MainActivity" >
    
        <ListView 
           android:id="@+id/lv"
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"       
           ></ListView>
    
    
    </LinearLayout>

    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" >
        <ImageView
            android:id="@+id/iv"
            android:src="@drawable/xing"
            android:layout_width="80dp"
            android:layout_height="80dp" 
                 
            />
        <TextView 
            android:id="@+id/t1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            
            />
        <TextView 
            android:id="@+id/t2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" 
                 
            />
        
    
    </LinearLayout>

    MainActivity.java

    public class MainActivity extends Activity {
        List<shopInfo> l;
        ListView lv;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lv = (ListView) findViewById(R.id.lv);
            //准备集合数据
            l = new ArrayList<shopInfo>();
            l.add(new shopInfo(R.drawable.xing, "name-1", "content-1"));
            l.add(new shopInfo(R.drawable.xing, "name-2", "content-2"));
            l.add(new shopInfo(R.drawable.xing, "name-3", "content-3"));
            l.add(new shopInfo(R.drawable.xing, "name-4", "content-4"));
            l.add(new shopInfo(R.drawable.xing, "name-5", "content-5"));
            l.add(new shopInfo(R.drawable.xing, "name-6", "content-6"));
            l.add(new shopInfo(R.drawable.xing, "name-7", "content-7"));
            l.add(new shopInfo(R.drawable.xing, "name-8", "content-8"));
       //准备BaseAdapter对象
            MyAdapter a = new MyAdapter();
            //设置Adapter显示数据
            lv.setAdapter(a);
    
        }
    //这个类可以写在里面,也可以写在外面
        public class MyAdapter extends BaseAdapter {
    
            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return l.size();
            }
    
            @Override
            public Object getItem(int arg0) {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public long getItemId(int arg0) {
                // TODO Auto-generated method stub
                return 0;
            }
    

    //第一种:没有任何处理,不建议这样写。如果数据量少看将就,但是如果列表项数据量很大的时候,会每次都重新创建View,设置资源,严重影响性能,所以从一开始就不要用这种方式 @Override
    public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub // 加载item的布局 View view = View.inflate(MainActivity.this, R.layout.item, null); shopInfo s = l.get(position); ImageView i = (ImageView) view.findViewById(R.id.iv); TextView t1 = (TextView) view.findViewById(R.id.t1); TextView t2 = (TextView) view.findViewById(R.id.t2); i.setImageResource(s.getIcon()); t1.setText(s.getName()); t2.setText(s.getContent()); convertView = view ; return convertView; } } }

    shopInfo.java

    //每行item的数据信息封装类
    public class shopInfo {
        private int icon;
        private String name;
        private String content;
        
        
        public int getIcon() {
            return icon;
        }
        public void setIcon(int icon) {
            this.icon = icon;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public shopInfo(int icon, String name, String content) {
            super();
            this.icon = icon;
            this.name = name;
            this.content = content;
        }
        @Override
        public String toString() {
            return "shopInfo [icon=" + icon + ", name=" + name + ", content="
                    + content + "]";
        }
        public shopInfo() {
            super();
            // TODO Auto-generated constructor stub
        }
        
    
    }

    运行结果如下:

     

     接下来实现getView()的方法和上边的实现一样的功能。

    第二种ListView优化:通过缓存convertView,这种利用缓存contentView的方式可以判断如果缓存中不存在View才创建View,如果已经存在可以利用缓存中的View,提升了性能

    public View getView(int position, View convertView, ViewGroup parent) {
                if(convertView == null)
                {
                    convertView = mInflater.inflate(R.layout.list_item, null);
                }
                
                ImageView img = (ImageView)convertView.findViewById(R.id.iv) ;
                TextView title = (TextView)convertView.findViewById(R.id.t1);
                TextView info = (TextView)ConvertView.findViewById(R.id.t2);
                img.setImageResource(R.drawable.xing);
                title.setText("Hello");
                info.setText("world");
                
                return convertView;
            }

    第三种ListView优化:通过convertView+ViewHolder来实现,ViewHolder就是一个静态类,使用 ViewHolder 的关键好处是缓存了显示数据的视图(View),加快了 UI 的响应速度。

    当我们判断 convertView == null  的时候,如果为空,就会根据设计好的List的Item布局(XML),来为convertView赋值,并生成一个viewHolder来绑定converView里面的各个View控件(XML布局里面的那些控件)。再用convertView的setTag将viewHolder设置到Tag中,以便系统第二次绘制ListView时从Tag中取出。(看下面代码中)

    如果convertView不为空的时候,就会直接用convertView的getTag(),来获得一个ViewHolder。

    public View getView(int position, View convertView, ViewGroup parent) {
                // LayoutInflater mInflater = null;
                ViewHolder holder = null;
                shopInfo s = l.get(position);
                if (convertView == null) {
                    holder = new ViewHolder();
    //                 convertView = LinearLayout.inflate(MainActivity.this,
    //                 R.layout.item, null);
                    convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null);
                    /* 得到各个控件的对象 */
                    holder.iv = (ImageView) convertView.findViewById(R.id.iv);
                    holder.t1 = (TextView) convertView.findViewById(R.id.t1);
                    holder.t2 = (TextView) convertView.findViewById(R.id.t2); // to
                                                                                // ItemButton
    
                    convertView.setTag(holder); // 绑定ViewHolder对象
                } else {
                    holder = (ViewHolder) convertView.getTag(); // 取出ViewHolder对象
                }
    
                /* 设置TextView显示的内容,即我们存放在动态数组中的数据 */
    
                holder.iv.setImageResource(s.getIcon());
                holder.t1.setText(s.getName());
                holder.t2.setText(s.getContent());
    
                return convertView;
    
            }
    
            /* 存放控件 的ViewHolder */
            public final class ViewHolder {
                public ImageView iv;
                public TextView t1;
                public TextView t2;
            }

    在上述的代码中方法getView(int position, View convertView, ViewGroup parent)的方法体中,holder这个变量其实就是一个每一个item的View的结构。

    这个holder结构存储了item对应布局里面的一些组件,而convertView.setTag(holder),就是把convertView中的Tag关联到holder这个结构中。

    而convertView.getTag(),就是把convertView中的Tag取出来。

    最后的holder.textView.setText(mData.get(position));就是把holder中的对应的组件初始化或者重定义(改变一些值),然后就可以显示出不同的内容了。

    如果要实现单双行颜色交替

    MainActivity.java:

    加下边三个语句就可以了。

    public class MainActivity extends Activity {
        List<shopInfo> l;
        ListView lv;
        private int[] colors = new int[] { 0xff3cb371, 0xffa0a0a0 };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            lv = (ListView) findViewById(R.id.lv);
            // 准备集合数据
            l = new ArrayList<shopInfo>();
            l.add(new shopInfo(R.drawable.xing, "name-1", "content-1"));
            l.add(new shopInfo(R.drawable.xing, "name-2", "content-2"));
            l.add(new shopInfo(R.drawable.xing, "name-3", "content-3"));
            l.add(new shopInfo(R.drawable.xing, "name-4", "content-4"));
            l.add(new shopInfo(R.drawable.xing, "name-5", "content-5"));
            l.add(new shopInfo(R.drawable.xing, "name-6", "content-6"));
            l.add(new shopInfo(R.drawable.xing, "name-7", "content-7"));
            l.add(new shopInfo(R.drawable.xing, "name-8", "content-8"));
            // 准备BaseAdapter对象
            MyAdapter a = new MyAdapter();
            // 设置Adapter显示数据
            lv.setAdapter(a);
    
        }
    
        // 这个类可以写在里面,也可以写在外面
        public class MyAdapter extends BaseAdapter {
    
            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return l.size();
            }
    
            @Override
            public Object getItem(int arg0) {
                // TODO Auto-generated method stub
                return null;
            }
    
            @Override
            public long getItemId(int arg0) {
                // TODO Auto-generated method stub
                return arg0;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub
                // 加载item的布局
                // View view = View.inflate(MainActivity.this, R.layout.item, null);
                //
                // shopInfo s = l.get(position);
                // ImageView i = (ImageView) view.findViewById(R.id.iv);
                // TextView t1 = (TextView) view.findViewById(R.id.t1);
                // TextView t2 = (TextView) view.findViewById(R.id.t2);
                //
                // i.setImageResource(s.getIcon());
                // t1.setText(s.getName());
                // t2.setText(s.getContent());
                // convertView = view ;
                // return convertView;
    
                // LayoutInflater mInflater = null;
                
    //            if(position%2==0){
    //                lv.setBackgroundColor(Color.argb(250 ,  255 ,  255 ,  255 ));
    //            }else{
    //                lv.setBackgroundColor(Color.argb(250 ,  224 ,  243 ,  250 ));
    //            }
                
                
    
                ViewHolder holder = null;
                shopInfo s = l.get(position);
                if (convertView == null) {
                    holder = new ViewHolder();
    //                 convertView = LinearLayout.inflate(MainActivity.this,
    //                 R.layout.item, null);
                    convertView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item, null);
                    /* 得到各个控件的对象 */
                    holder.iv = (ImageView) convertView.findViewById(R.id.iv);
                    holder.t1 = (TextView) convertView.findViewById(R.id.t1);
                    holder.t2 = (TextView) convertView.findViewById(R.id.t2); // to
                                                                                // ItemButton
    
                    convertView.setTag(holder); // 绑定ViewHolder对象
                } else {
                    holder = (ViewHolder) convertView.getTag(); // 取出ViewHolder对象
                }
    
                /* 设置TextView显示的内容,即我们存放在动态数组中的数据 */
    
                holder.iv.setImageResource(s.getIcon());
                holder.t1.setText(s.getName());
                holder.t2.setText(s.getContent());
                
                int colorPos = position % colors.length;
                convertView.setBackgroundColor(colors[colorPos]);
    
    
                return convertView;
    
            }
    
            /* 存放控件 的ViewHolder */
            public final class ViewHolder {
                public ImageView iv;
                public TextView t1;
                public TextView t2;
            }
    
        }
    }

    效果如图:

  • 相关阅读:
    2019-2020-1 20199314 《Linux内核原理与分析》 第六周作业
    编译内核及系统调用的坑之make menuconfig
    20199314 Linux内核原理与分析 第五周作业
    20199314 Linux内核原理与分析 第四周作业
    2019-2020-1 20199314 <Linux内核原理与分析>第三周作业
    2019-2020-1 20199314 <Linux内核原理与分析>第二周作业
    2019-2020-1 20199314 <Linux内核原理与分析>第一周作业
    简单单层前馈神经网络
    wait,waitpid学习测试
    2019-2020-1 20199307《Linux内核原理与分析》第八周作业
  • 原文地址:https://www.cnblogs.com/mengxiao/p/6046381.html
Copyright © 2020-2023  润新知