Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 459|回复: 0

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

[复制链接]

该用户从未签到

发表于 2011-10-25 09:49:38 | 显示全部楼层 |阅读模式
Android中,我们可以通过继承View来打造完全如我们所愿的组件,但是,有的时候,我们需要的组件是一个由现有的几个组件的组合实现的,那么我们就可以利用组件合成技术,呵呵,这个名字我自己起的。
在Android中打造复合组件,其实只需要继承Layout或者其子类,比如LinearLayout等,然后在其中定义需要完成该功能的现有的几个组件。
然后定义一个监听器(就是一个简单的接口,暴露给用户使用,获取返回的数据,给用户使用)
本文通过使用两个Spinner来打造一个省份城市信息联动的选择控件,省份和城市信息的联动是开发中经常遇到的,这里我们看看使用组件合成技术如何简单巧妙的实现该功能。本例是雏形,强大的功能待大家完善。
闲话少说,直接上实例:
1、自定义一个CitySpinner,代码:
view plaincopy to clipboardprint?


package org.widget.spinner;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.LinearLayout;
import android.widget.Spinner;
/**
* 自定义复合组件,实现省份城市联动Spinner组件
* 定义复合组件通常继承自Layout,不必重写onDraw,onMesure等方法,除非有特殊的需求
* @author Administrator
*
*/
public class CitySpinner extends LinearLayout {

private Context context;

private Spinner mProvinceSpinner, mCitySpinner;

private HashMap<String, ArrayList<String>> proCities; //存放数据

private ArrayList<String> provinces;

private OnCitySelectListener cityListener;


private AdapterView.OnItemSelectedListener provinceSelectListener = new AdapterView.OnItemSelectedListener() {
@Override

public void onItemSelected(AdapterView<?> p, View v, int position,
long id) {
// 在选择了一个省份后,我们需要更新对应的城市列表
String currProvince = (String)p.getItemAtPosition(position);
switchCity(currProvince);

}
@Override

public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub

}
};

private AdapterView.OnItemSelectedListener citySelectListener = new AdapterView.OnItemSelectedListener() {
@Override

public void onItemSelected(AdapterView<?> p, View v, int position,
long id) {

if(cityListener != null){
//这里获取当前选择的省份和城市
String province = (String)mProvinceSpinner.getSelectedItem();
String city = (String)p.getItemAtPosition(position);
cityListener.onCitySelected(province, city);
}

}
@Override

public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
//Do nothing;
}
};


public CitySpinner(Context context, HashMap<String, ArrayList<String>> data){
super(context);
this.context = context;
if(data != null){
init(data);
}
}

public CitySpinner(Context context, HashMap<String, ArrayList<String>> data, AttributeSet attrs){
super(context, attrs);
this.context = context;
if(data != null){
init(data);
}
}

private void init(HashMap<String, ArrayList<String>> data){
this.setOrientation(HORIZONTAL); //水平布局
this.setWeightSum(0.5f);
//然后设置省份Spinner的数据

//首先,我们直接在代码中定义组件
// mProvinceSpinner = new Spinner(context);
// mCitySpinner = new Spinner(context);
//我们看看从xml文件中获取
View v = LayoutInflater.from(context).inflate(R.layout.city, null);
mProvinceSpinner = (Spinner)v.findViewById(R.id.province);
mCitySpinner = (Spinner)v.findViewById(R.id.city);
//在将这两个组件添加到新的LinearLayout中时,需要首先将这两个组件从原来的Layout中删除
LinearLayout temp = (LinearLayout)v.findViewById(R.id.layout_city);
temp.removeAllViews();
//添加监听
mProvinceSpinner.setOnItemSelectedListener(provinceSelectListener);
mCitySpinner.setOnItemSelectedListener(citySelectListener);

//如何对其进行定制布局格式呢??待解决
this.proCities = data;
initProvince();

this.addView(mProvinceSpinner,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
this.addView(mCitySpinner,LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
}

//初始化省份信息
private void initProvince(){
provinces = new ArrayList<String>();
Object[] temps = proCities.keySet().toArray();
for(int i=0; i<temps.length; i++){
provinces.add((String)temps);
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,provinces);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
mProvinceSpinner.setAdapter(adapter);
}

//根据当前指定的省份更新对应的城市信息
private void switchCity(String currProvince){

ArrayList<String> cities = proCities.get(currProvince);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,cities);
adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);
mCitySpinner.setAdapter(adapter);
}
public Spinner getmProvinceSpinner() {
return mProvinceSpinner;
}
public void setmProvinceSpinner(Spinner mProvinceSpinner) {
this.mProvinceSpinner = mProvinceSpinner;
}
public Spinner getmCitySpinner() {
return mCitySpinner;
}
public void setmCitySpinner(Spinner mCitySpinner) {
this.mCitySpinner = mCitySpinner;
}

public void setOnCitySelectListener(OnCitySelectListener listener){
this.cityListener = listener;
}
}


package org.widget.spinner;import java.util.ArrayList;import java.util.HashMap;import android.content.Context;import android.util.AttributeSet;import android.view.LayoutInflater;import android.view.View;import android.widget.AdapterView;import android.widget.ArrayAdapter;import android.widget.LinearLayout;import android.widget.Spinner;/** * 自定义复合组件,实现省份城市联动Spinner组件 * 定义复合组件通常继承自Layout,不必重写onDraw,onMesure等方法,除非有特殊的需求 * @author Administrator * */public class CitySpinner extends LinearLayout {                private Context context;                private Spinner mProvinceSpinner, mCitySpinner;                private HashMap<String, ArrayList<String>> proCities; //存放数据                private ArrayList<String> provinces;                private OnCitySelectListener cityListener;                        private AdapterView.OnItemSelectedListener provinceSelectListener = new AdapterView.OnItemSelectedListener() {                @Override                public void onItemSelected(AdapterView<?> p, View v, int position,                                long id) {                        // 在选择了一个省份后,我们需要更新对应的城市列表                        String currProvince = (String)p.getItemAtPosition(position);                        switchCity(currProvince);                                        }                @Override                public void onNothingSelected(AdapterView<?> arg0) {                        // TODO Auto-generated method stub                                        }        };                private AdapterView.OnItemSelectedListener citySelectListener = new AdapterView.OnItemSelectedListener() {                @Override                public void onItemSelected(AdapterView<?> p, View v, int position,                                long id) {                                                if(cityListener != null){                                //这里获取当前选择的省份和城市                                String province = (String)mProvinceSpinner.getSelectedItem();                                String city = (String)p.getItemAtPosition(position);                                cityListener.onCitySelected(province, city);                        }                                        }                @Override                public void onNothingSelected(AdapterView<?> arg0) {                        // TODO Auto-generated method stub                        //Do nothing;                }        };                        public CitySpinner(Context context, HashMap<String, ArrayList<String>> data){                super(context);                this.context = context;                        if(data != null){                        init(data);                }        }                public CitySpinner(Context context, HashMap<String, ArrayList<String>> data, AttributeSet attrs){                super(context, attrs);                this.context = context;                        if(data != null){                        init(data);                }                        }                        private void init(HashMap<String, ArrayList<String>> data){                this.setOrientation(HORIZONTAL); //水平布局                this.setWeightSum(0.5f);                //然后设置省份Spinner的数据                                //首先,我们直接在代码中定义组件//                mProvinceSpinner = new Spinner(context);//                mCitySpinner = new Spinner(context);                //我们看看从xml文件中获取                View v = LayoutInflater.from(context).inflate(R.layout.city, null);                mProvinceSpinner = (Spinner)v.findViewById(R.id.province);                mCitySpinner = (Spinner)v.findViewById(R.id.city);                //在将这两个组件添加到新的LinearLayout中时,需要首先将这两个组件从原来的Layout中删除                LinearLayout temp = (LinearLayout)v.findViewById(R.id.layout_city);                temp.removeAllViews();                //添加监听                mProvinceSpinner.setOnItemSelectedListener(provinceSelectListener);                mCitySpinner.setOnItemSelectedListener(citySelectListener);                                //如何对其进行定制布局格式呢??待解决                this.proCities = data;                initProvince();                                this.addView(mProvinceSpinner,LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);                this.addView(mCitySpinner,LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);                        }                //初始化省份信息        private void initProvince(){                provinces = new ArrayList<String>();                Object[] temps = proCities.keySet().toArray();                for(int i=0; i<temps.length; i++){                        provinces.add((String)temps);                }                ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,provinces);                adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);                mProvinceSpinner.setAdapter(adapter);                        }                //根据当前指定的省份更新对应的城市信息        private void switchCity(String currProvince){                                ArrayList<String> cities = proCities.get(currProvince);                                ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, android.R.layout.simple_spinner_item,cities);                adapter.setDropDownViewResource(android.R.layout.simple_dropdown_item_1line);                mCitySpinner.setAdapter(adapter);                        }        public Spinner getmProvinceSpinner() {                return mProvinceSpinner;        }        public void setmProvinceSpinner(Spinner mProvinceSpinner) {                this.mProvinceSpinner = mProvinceSpinner;        }        public Spinner getmCitySpinner() {                return mCitySpinner;        }        public void setmCitySpinner(Spinner mCitySpinner) {                this.mCitySpinner = mCitySpinner;        }                public void setOnCitySelectListener(OnCitySelectListener listener){                this.cityListener = listener;        }}
2、该代码中使用到了一个监听器OnCitySelectListener,其实就是一个简单的接口,在用户使用的时候,由用户来具体实现。
view plaincopy to clipboardprint?


/**
* 选择事件监听器
* @author Administrator
*
*/
public interface OnCitySelectListener {

public void onCitySelected(String province, String city);
}


/** * 选择事件监听器 * @author Administrator * */public interface OnCitySelectListener {                public void onCitySelected(String province, String city);}
3、测试代码,目前不能再配置文件中使用该控件,只能在代码中使用,如何使其能在配置文件中使用,也很简单。后期待完成。代码:
view plaincopy to clipboardprint?


package demo.spinner;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.Toast;
public class DemoActivity extends Activity {
/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
HashMap<String, ArrayList<String>> data = new HashMap<String, ArrayList<String>>();
for(int i=0; i<5; i++){
ArrayList<String> cities = new ArrayList<String>();
for(int j=0; j<5; j++){
cities.add("cities"+i+j);
}
data.put("province"+i, cities);
}
final CitySpinner spinner = new CitySpinner(this, data);
LinearLayout layout = (LinearLayout)this.findViewById(R.id.layout_demo);
layout.addView(spinner);
//CitySpinner spinner = (CitySpinner)this.findViewById(R.id.city_spinner);//在布局文件中加入,目前不行,待完善
spinner.setOnCitySelectListener(new OnCitySelectListener() {

@Override

public void onCitySelected(String province, String city) {
//

Toast.makeText(DemoActivity.this, "当前省市:"+province+city, Toast.LENGTH_LONG).show();
}
});

}
}


package demo.spinner;import java.util.ArrayList;import java.util.HashMap;import android.app.Activity;import android.os.Bundle;import android.widget.LinearLayout;import android.widget.Toast;public class DemoActivity extends Activity {    /** Called when the activity is first created. */            @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        HashMap<String, ArrayList<String>> data = new HashMap<String, ArrayList<String>>();        for(int i=0; i<5; i++){                ArrayList<String> cities = new ArrayList<String>();                for(int j=0; j<5; j++){                        cities.add("cities"+i+j);                }                data.put("province"+i, cities);        }        final CitySpinner spinner = new CitySpinner(this, data);        LinearLayout layout = (LinearLayout)this.findViewById(R.id.layout_demo);        layout.addView(spinner);                //CitySpinner spinner = (CitySpinner)this.findViewById(R.id.city_spinner);//在布局文件中加入,目前不行,待完善        spinner.setOnCitySelectListener(new OnCitySelectListener() {                                                @Override                        public void onCitySelected(String province, String city) {                                //                                 Toast.makeText(DemoActivity.this, "当前省市:"+province+city, Toast.LENGTH_LONG).show();                        }                });            }}
可以看到,组件合成技术,如此简单而已!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-11 14:27 , Processed in 0.329026 second(s), 36 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表