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由於涉及到數據庫,所以打算單獨拿出來講。

 

     

     

      

     

     

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM