您的位置:首页 > 移动开发 > Android开发

Android打造个性十足的组件技术之复合组件

2011-06-15 23:18 197 查看
在Android中,我们可以通过继承View来打造完全如我们所愿的组件,但是,有的时候,我们需要的组件是一个由现有的几个组件的组合实现的,那么我们就可以利用组件合成技术,呵呵,这个名字我自己起的。

在Android中打造复合组件,其实只需要继承Layout或者其子类,比如LinearLayout等,然后在其中定义需要完成该功能的现有的几个组件。

然后定义一个监听器(就是一个简单的接口,暴露给用户使用,获取返回的数据,给用户使用)

本文通过使用两个Spinner来打造一个省份城市信息联动的选择控件,省份和城市信息的联动是开发中经常遇到的,这里我们看看使用组件合成技术如何简单巧妙的实现该功能。本例是雏形,强大的功能待大家完善。

闲话少说,直接上实例:

1、自定义一个CitySpinner,代码:

 

view plaincopy to clipboardprint?
01.package org.widget.spinner; 
02.import java.util.ArrayList; 
03.import java.util.HashMap; 
04.import android.content.Context; 
05.import android.util.AttributeSet; 
06.import android.view.LayoutInflater; 
07.import android.view.View; 
08.import android.widget.AdapterView; 
09.import android.widget.ArrayAdapter; 
10.import android.widget.LinearLayout; 
11.import android.widget.Spinner; 
12./**
13. * 自定义复合组件,实现省份城市联动Spinner组件
14. * 定义复合组件通常继承自Layout,不必重写onDraw,onMesure等方法,除非有特殊的需求
15. * @author Administrator
16. *
17. */ 
18.public class CitySpinner extends LinearLayout { 
19.     
20.    private Context context; 
21.     
22.    private Spinner mProvinceSpinner, mCitySpinner; 
23.     
24.    private HashMap<String, ArrayList<String>> proCities; //存放数据 
25.     
26.    private ArrayList<String> provinces; 
27.     
28.    private OnCitySelectListener cityListener; 
29.     
30.     
31.    private AdapterView.OnItemSelectedListener provinceSelectListener = new AdapterView.OnItemSelectedListener() { 
32.        @Override 
33.        public void onItemSelected(AdapterView<?> p, View v, int position, 
34.                long id) { 
35.            // 在选择了一个省份后,我们需要更新对应的城市列表 
36.            String currProvince = (String)p.getItemAtPosition(position); 
37.            switchCity(currProvince); 
38.             
39.        } 
40.        @Override 
41.        public void onNothingSelected(AdapterView<?> arg0) { 
42.            // TODO Auto-generated method stub 
43.             
44.        } 
45.    }; 
46.     
47.    private AdapterView.OnItemSelectedListener citySelectListener = new AdapterView.OnItemSelectedListener() { 
48.        @Override 
49.        public void onItemSelected(AdapterView<?> p, View v, int position, 
50.                long id) { 
51.             
52.            if(cityListener != null){ 
53.                //这里获取当前选择的省份和城市 
54.                String province = (String)mProvinceSpinner.getSelectedItem(); 
55.                String city = (String)p.getItemAtPosition(position); 
56.                cityListener.onCitySelected(province, city); 
57.            } 
58.             
59.        } 
60.        @Override 
61.        public void onNothingSelected(AdapterView<?> arg0) { 
62.            // TODO Auto-generated method stub 
63.            //Do nothing; 
64.        } 
65.    }; 
66.     
67.     
68.    public CitySpinner(Context context, HashMap<String, ArrayList<String>> data){ 
69.        super(context); 
70.        this.context = context;  
71.        if(data != null){ 
72.            init(data); 
73.        } 
74.    } 
75.     
76.    public CitySpinner(Context context, HashMap<String, ArrayList<String>> data, AttributeSet attrs){ 
77.        super(context, attrs); 
78.        this.context = context;  
79.        if(data != null){ 
80.            init(data); 
81.        }        
82.    }    
83.     
84.    private void init(HashMap<String, ArrayList<String>> data){ 
85.        this.setOrientation(HORIZONTAL); //水平布局 
86.        this.setWeightSum(0.5f); 
87.        //然后设置省份Spinner的数据 
88.         
89.        //首先,我们直接在代码中定义组件 
90.//      mProvinceSpinner = new Spinner(context); 
91.//      mCitySpinner = new Spinner(context); 
92.        //我们看看从xml文件中获取 
93.        View v = LayoutInflater.from(context).inflate(R.layout.city, null); 
94.        mProvinceSpinner = (Spinner)v.findViewById(R.id.province); 
95.        mCitySpinner = (Spinner)v.findViewById(R.id.city); 
96.        //在将这两个组件添加到新的LinearLayout中时,需要首先将这两个组件从原来的Layout中删除 
97.        LinearLayout temp = (LinearLayout)v.findViewById(R.id.layout_city); 
98.        temp.removeAllViews(); 
99.        //添加监听 
100.        mProvinceSpinner.setOnItemSelectedListener(provinceSelectListener); 
101.        mCitySpinner.setOnItemSelectedListener(citySelectListener); 
102.         
103.        //如何对其进行定制布局格式呢??待解决 
104.        this.proCities = data; 
105.        initProvince(); 
106.         
107.        this.addView(mProvinceSpinner,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); 
108.        this.addView(mCitySpinner,LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);         
109.    } 
110.     
111.    //初始化省份信息 
112.    private void initProvince(){ 
113.        provinces = new ArrayList<String>(); 
114.        Object[] temps = proCities.keySet().toArray(); 
115.        for(int i=0; i<temps.length; i++){ 
116.            provinces.add((String)temps[i]); 
117.        } 
118.        ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,provinces); 
119.        adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line); 
120.        mProvinceSpinner.setAdapter(adapter);        
121.    } 
122.     
123.    //根据当前指定的省份更新对应的城市信息 
124.    private void switchCity(String currProvince){ 
125.         
126.        ArrayList<String> cities = proCities.get(currProvince); 
127.         
128.        ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,cities); 
129.        adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line); 
130.        mCitySpinner.setAdapter(adapter);        
131.    } 
132.    public Spinner getmProvinceSpinner() { 
133.        return mProvinceSpinner; 
134.    } 
135.    public void setmProvinceSpinner(Spinner mProvinceSpinner) { 
136.        this.mProvinceSpinner = mProvinceSpinner; 
137.    } 
138.    public Spinner getmCitySpinner() { 
139.        return mCitySpinner; 
140.    } 
141.    public void setmCitySpinner(Spinner mCitySpinner) { 
142.        this.mCitySpinner = mCitySpinner; 
143.    } 
144.     
145.    public void setOnCitySelectListener(OnCitySelectListener listener){ 
146.        this.cityListener = listener; 
147.    } 
148.} 

2、该代码中使用到了一个监听器OnCitySelectListener,其实就是一个简单的接口,在用户使用的时候,由用户来具体实现。

 

view plaincopy to clipboardprint?
01./**
02. * 选择事件监听器
03. * @author Administrator
04. *
05. */ 
06.public interface OnCitySelectListener { 
07.     
08.    public void onCitySelected(String province, String city); 
09.} 

3、测试代码,目前不能再配置文件中使用该控件,只能在代码中使用,如何使其能在配置文件中使用,也很简单。后期待完成。代码:

 

view plaincopy to clipboardprint?
01.package demo.spinner; 
02.import java.util.ArrayList; 
03.import java.util.HashMap; 
04.import android.app.Activity; 
05.import android.os.Bundle; 
06.import android.widget.LinearLayout; 
07.import android.widget.Toast; 
08.public class DemoActivity extends Activity { 
09.    /** Called when the activity is first created. */ 
10.     
11.    @Override 
12.    public void onCreate(Bundle savedInstanceState) { 
13.        super.onCreate(savedInstanceState); 
14.        setContentView(R.layout.main); 
15.        HashMap<String, ArrayList<String>> data = new HashMap<String, ArrayList<String>>(); 
16.        for(int i=0; i<5; i++){ 
17.            ArrayList<String> cities = new ArrayList<String>(); 
18.            for(int j=0; j<5; j++){ 
19.                cities.add("cities"+i+j); 
20.            } 
21.            data.put("province"+i, cities); 
22.        } 
23.        final CitySpinner spinner = new CitySpinner(this, data); 
24.        LinearLayout layout = (LinearLayout)this.findViewById(R.id.layout_demo); 
25.        layout.addView(spinner);         
26.        //CitySpinner spinner = (CitySpinner)this.findViewById(R.id.city_spinner);//在布局文件中加入,目前不行,待完善 
27.        spinner.setOnCitySelectListener(new OnCitySelectListener() { 
28.             
29.            @Override 
30.            public void onCitySelected(String province, String city) { 
31.                //  
32.                Toast.makeText(DemoActivity.this, "当前省市:"+province+city, Toast.LENGTH_LONG).show(); 
33.            } 
34.        }); 
35.         
36.    } 
37.} 

可以看到,组件合成技术,如此简单而已!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenjie19891104/archive/2011/04/23/6344250.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息