• SimpleAdapter真不简单!


          作为一名编程初学者,我总是认为自己什么都不会,什么都不行,就算实现了文档指定的功能,我永远都是觉得自己写过的代码实在是太烂了,它只是恰巧能够运行而已!它只是在运行的时候恰巧没有发现错误而已!!一直都是抱着这样的念头,但迫于工作进度以及工作心情(这点必须承认,被上头追着进度的感觉让人很郁闷),在项目完结的一段时间内都不想看到自己的代码!!所以,迫切提醒各位和我一样的菜鸟,不要放过每一次重构和优化的机会,这种优化可以是小步骤的,有时就是代码结构的一个优化,或者是某个变量名的修改,并不要求我们从一开始就对结构进行优化,记住这句话:

          程序员只要对自己的代码负责就行。

          自己写过的代码迟早是要被人看的,被人用的,所以,它就像是我们在这圈子里的名片,无论我们把自己吹得再牛,一看我们的代码,就真的是什么馅都清楚了。所以,不要对自己正在写的代码马虎,最后吃亏的是自己。

          在结束项目的某个进度后,就来写写博客转换一下心情,想起常用控件ListView,于是就来研究研究它。

          使用ListView关键的就是适配器,可怕的是,用于ListView的适配器很多。

          我们先从名字看似最简单其实不简单的SimpleAdapter开始。

          我们先来看一个简单的例子:

        private ListView mListView;
        private LinearLayout mLayout;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            mLayout = new LinearLayout(this);
            mLayout.setOrientation(LinearLayout.VERTICAL);
            mListView = new ListView(this);
            LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
                    LinearLayout.LayoutParams.MATCH_PARENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT);
            mLayout.addView(mListView, param);
            setContentView(mLayout);
            Map<String, String> keyValuePair = new HashMap<String, String>();
            keyValuePair.put("Name", "小智");
            keyValuePair.put("Age", "10");
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            list.add(keyValuePair);
    
            ListAdapter adapter = new SimpleAdapter(this, list,
                    android.R.layout.simple_list_item_2, new String[] { "Name",
                            "Age" }, new int[] { android.R.id.text1,
                            android.R.id.text2 });
    
            mListView.setAdapter(adapter);
        }
    
        @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);
            return true;
        }

         

         我们先从SimpleAdapter的构造开始。
         要构造一个SimpleAdapter,需要以下的参数:

    1.Context context:上下文,这个是每个组件都需要的,它指明了SimpleAdapter关联的View的运行环境,也就是我们当前的Activity。

    2.List<? extends Map<String, ?>> data:这是一个由Map组成的List,在该List中的每个条目对应ListView的一行,每一个Map中包含的就是所有在from参数中指定的key。

    3.int resource:定义列表项的布局文件的资源ID,该资源文件至少应该包含在to参数中定义的ID。

    4.String[] from:将被添加到Map映射上的key。

    5.int[] to:将绑定数据的视图的ID跟from参数对应,这些被绑定的视图元素应该全是TextView。

        上面的例子中我们是手动的添加视图,然后使用的是系统默认的视图元素,像是android.R.id.text1。当然,我们也可以自定义TextView的样式,而且,说是应该全是TextView,也只是应该,并不是绝对的:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ListView listView = (ListView) this.findViewById(R.id.list);
            List<Map<String, ?>> list = new ArrayList<Map<String, ?>>();
            for (int i = 0; i < 5; i++) {
                Map<String, String> keyValuePair = new HashMap<String, String>();
                keyValuePair.put("Text", "Text" + i);
                keyValuePair.put("Button", "Button" + i);
                list.add(keyValuePair);
            }
    
            ListAdapter adapter = new SimpleAdapter(this, list, R.layout.listitem,
                    new String[] { "Text", "Button" }, new int[] { R.id.text,
                            R.id.button });
    
            listView.setAdapter(adapter);

           

          从这里我们可以看到,要想使用ListView,我们应用程序的主界面必须包含ListView,然后ListView的内容可以自己定义,而不仅仅是TextView。

          要想知道这是什么回事,我们就要知道SimpleAdapter是如何绑定数据到视图的,这个过程我们甚至可以自定义:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ListView listView = (ListView) this.findViewById(R.id.list);
            List<Map<String, String>> list = new ArrayList<Map<String, String>>();
            for (int i = 0; i < 3; i++) {
                Map<String, String> keyValuePair = new HashMap<String, String>();
                keyValuePair.put("text", "text" + i);
                list.add(keyValuePair);
            }
    
            CustomSimpleAdapter adapter = new CustomSimpleAdapter(this, list,
                    R.layout.listitem);
    
            listView.setAdapter(adapter);
    class CustomSimpleAdapter extends SimpleAdapter {
            private int mResource;
            private List<? extends Map<String, ?>> mData;
    
            public CustomSimpleAdapter(Context context,
                    List<? extends Map<String, ?>> data, int resource) {
                super(context, data, resource, null, null);
                this.mResource = resource;
                this.mData = data;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup group) {
                LayoutInflater layoutInflater = getLayoutInflater();
                View view = layoutInflater.inflate(mResource, null);
                TextView text = (TextView) view.findViewById(R.id.text);
                text.setText(mData.get(position).get("text").toString());
                if (position == 2) {
                    text.setTextColor(Color.RED);
                }
                return view;
            }
        }

        

          要想实现自定义的ListView,最主要的是实现getView(),因为SimpleAdapter的数据绑定就是发生在这里。
          现在我们可以总结一下SimpleAdapter的数据绑定是怎样的:利用传入的view(该view包含ListView每行要渲染的视图元素)的ResourceID得到该view,然后通过每个vie所在的索引,也就是它们的行数,得到data中相应内容的key,接着就是利用这些key的value填充这些视图元素,最后返回view作为ListView每行的内容显示出来。

          由此可见,from和to并不是必须的,要想实现ListView,前三个参数才是必要的,也许大家会看到网上有些例子为了实现自定义的SimpleAdapter,会覆写它的许多方法,其实如果单纯只是想要利用SimpleAdapter来实现自定义的ListView,只要覆写getView()就行,其他的完全可以交给SimpleAdapter原先的方法来做,除非我们有特殊的要求。

          SimpleAdapter并不仅仅用在ListView上,事实上,Spinner同样可以使用:

    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Spinner spinner = (Spinner) this.findViewById(R.id.spinner);
            List<Map<String, ?>> list = new ArrayList<Map<String, ?>>();
            for (int i = 0; i < 5; i++) {
                Map<String, String> keyValuePair = new HashMap<String, String>();
                keyValuePair.put("Text", "Text" + i);
                list.add(keyValuePair);
            }
    
            SimpleAdapter adapter = new SimpleAdapter(this, list,
                    R.layout.listitem, new String[] { "Text" },
                    new int[] { R.id.text });
    
            spinner.setAdapter(adapter);
        }

         

           因为Spinner显示的列表本质上就是一个ListView,所以,和ListView有关的一切它几乎都可以使用,这个还是放在Spinner那时候再讲吧。
          原本只是想要将所有的适配器讲完,但碍于篇幅有限,所以只好分开讲,还有,SimpleCursorAdapter由于涉及到数据库,所以打算单独拿出来讲。

         

         

          

         

         

         

  • 相关阅读:
    RADAR毫米波雷达传感器
    固态LiDAR,半固态混合LiDAR,机械LiDAR
    Lidar激光雷达市场
    echarts 环形图中自定义文字
    uni-app base64 无法显示问题
    实战二(上):针对非业务的通用框架开发,如何做需求分析和设计?
    实战一(下):如何实现一个遵从设计原则的积分兑换系统?
    实战一(上):针对业务系统的开发,如何做需求分析和设计?
    学而不记,不学无异 -- English learning
    springmvc 传入返回参数更改
  • 原文地址:https://www.cnblogs.com/wenjiang/p/3189082.html
Copyright © 2020-2023  润新知