本人是一个不擅长Android的开发的,但是这几天在做联通的一个服务器配件管理系统,做完B/S的又要写C/S的,老板要求没办法。在做的过程中遇到了一个下拉菜单联动的问题,以前没做过,突然做还真有点不知所措了,在网上找了一大堆发现数据都是本地的应该构造好了,没卵用,不过也给了我很多想发,一开始想到用树去解决,可是每个树的节点个数不知道,要是动态创建就会很麻烦。最后在自己的努力下来构造JSON数据格式,其实弄明白感觉很简单,就是并保存你的上一级是谁,你的下一级是谁就可以了,但是数据库做的表没有结构可言很难构造出来有用的数据结构。
factory 下有多个 type ,这里有一点需要注意,不是 type 下有多个 products_name 而是,factory 和 type 要共同确定有那些 products_name , 好了就这样一次类推,顺序分别是 factory、type 、products_name 、 products_no 、 function .
由此得到的数据库查询语句有:
select factory from bjlt_products_type group by factory ;
select type from bjlt_products_type where factory=#{0} group by type;
select products_name from bjlt_products_type where factory=#{0} and type=#{1} group by products_name;
select products_no from bjlt_products_type where factory=#{0} and type=#{1} and products_name=#{2} group by products_no;
select function from bjlt_products_type where factory=#{0} and type=#{1} and products_name=#{2} and products_no=#{3} group by function;
知道Mybatis的很容易看懂,我这里就不说了; 查询数据结构构造json数据代码
@ResponseBody
@RequestMapping("/user_info/requestproductstypeApplication.html")
public String user_infoProductsFactory(HttpServletRequest request, HttpServletResponse response)
throws IOException {
List<String> str_1 = bjlt_products_typeService.factory();
String str1 = "";
String str2 = "";
String str3 = "";
String str4 = "";
String str5 = "";
Json json = new Json();
for (int i = 0; i < str_1.size(); i++) {
str1 = str1 + str_1.get(i) + "$$";
List<String> str_2 = bjlt_products_typeService.type(str_1.get(i));
str2 = "";
for (int j = 0; j < str_2.size(); j++) {
str2 = str2 + str_2.get(j) + "$$";
List<String> str_3 = bjlt_products_typeService.products_name(str_1.get(i), str_2.get(j));
str3 = "";
for (int z = 0; z < str_3.size(); z++) {
str3 = str3 + str_3.get(z) + "$$";
List<String> str_4 = bjlt_products_typeService.products_no(str_1.get(i), str_2.get(j),
str_3.get(z));
str4 = "";
for (int q = 0; q < str_4.size(); q++) {
str4 = str4 + str_4.get(q) + "$$";
List<String> str_5 = bjlt_products_typeService.function(str_1.get(i), str_2.get(j),
str_3.get(z), str_4.get(q));
str5 = "";
for (int k = 0; k < str_5.size(); k++) {
str5 = str5 + str_5.get(k) + "$$";
}
json.add(str_1.get(i) + "$$" + str_2.get(j) + "$$" + str_3.get(z) + "$$" + str_4.get(q), str5);
}
json.add(str_1.get(i) + "$$" + str_2.get(j) + "$$" + str_3.get(z), str4);
}
json.add(str_1.get(i) + "$$" + str_2.get(j), str3);
}
json.add(str_1.get(i), str2);
}
json.add("factory", str1);
json.add("result", "ok");
System.out.println(json.toString());
// response.addHeader("Access-Control-Allow-Origin",
// "http://127.0.0.1:8020");
return json.toString();
}
此代码是循环获取每个类别的数据,主要思想为键值保存他的父亲,值保存他下面的儿子,举个例子
{"华为": "BBU$$RRU$$"}//代表华为下有两个类别,到时候value可以直接用split取出字符数组
{"华为$$RRU": "RRU3775$$RRU3959$$"}//当有了华为下的儿子,就可以和儿子组合起来和成一个唯一的键,为一个字符串//
下面是获取到的整个JSON字符串
String str = { "爱立信$$BBU$$DUS4102": "KDU137624/11$$",
"华为$$RRU$$RRU3959$$WD5MIRUYC10E": "基带板$$",
"factory": "华为$$爱立信$$",
"华为": "BBU$$RRU$$",
"爱立信$$BBU$$DUS4102$$KDU137624/11": "基带板$$",
"华为$$BBU": "UMPTb2$$",
"华为$$RRU": "RRU3775$$RRU3959$$",
"华为$$RRU$$RRU3959": "WD5MIRUYC10E$$",
"华为$$BBU$$UMPTb2": "WD22UMPTb2$$",
"华为$$RRU$$RRU3775$$D5MPRUC19BC": "电源模块$$",
"result": "ok",
"华为$$BBU$$UMPTb2$$WD22UMPTb2": "射频单元$$",
"华为$$RRU$$RRU3775": "D5MPRUC19BC$$",
"爱立信$$BBU": "DUS4102$$",
"爱立信$$RRU": "RRUS01B1$$",
"爱立信$$RRU$$RRUS01B1": "KRC161255/2$$",
"爱立信$$RRU$$RRUS01B1$$KRC161255/2": "电源模块$$",
"爱立信": "BBU$$RRU$$"};
和android交互会出现乱码问题,大家可以使用URL编码进行编解码,在最后返回字符串的时候,加入一下代码
UrlUtil.getURLEncoderString(json.toString());//为自己的编码类
public class Main2Activity extends AppCompatActivity {
//下拉组件
private Spinner factorySpinner = null; //厂商
private Spinner typeSpinner = null; //大类
private Spinner products_nameSpinner = null; //产品名称
private Spinner products_noSpinner = null; //产品号
private Spinner functionSpinner = null; //产品号
//数据适配器
ArrayAdapter<String> factoryAdapter = null;//
ArrayAdapter<String> typeAdapter = null; //
ArrayAdapter<String> products_nameAdapter = null; //
ArrayAdapter<String> products_noAdapter = null; //
ArrayAdapter<String> functionAdapter = null; //
JSONObject root = null;
static int provincePosition = 3;
HttpClient client;
//
private String[] text = new String[]{"请选择"};
private String[] factory_1 = null;
ProgressDialog waitingDialog=null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
waitingDialog= new ProgressDialog(Main2Activity.this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
client = new DefaultHttpClient();
readNet(Contents.HOST+"user_info/requestproductstypeApplication.html");
showWaitingDialog();
}
private void showWaitingDialog() {
waitingDialog.setTitle("我是一个等待Dialog");
waitingDialog.setMessage("等待中...");
waitingDialog.setIndeterminate(true);
waitingDialog.setCancelable(false);
waitingDialog.show();
}
/*
* 设置下拉框,默认的值,内容为请选择
*/
private void setSpinner()
{
factorySpinner = (Spinner)findViewById(R.id.spin_factory);
typeSpinner = (Spinner)findViewById(R.id.spin_type);
products_nameSpinner = (Spinner)findViewById(R.id.spin_products_name);
products_noSpinner = (Spinner)findViewById(R.id.spin_products_no);
functionSpinner = (Spinner)findViewById(R.id.spin_function);
//绑定适配器和值
try{
System.out.println(root.getString("factory").split("\\$\\$")[0]);
factoryAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, factory_1);
}catch (Exception e){
e.printStackTrace();
}
factorySpinner.setAdapter(factoryAdapter);
factorySpinner.setSelection(0,true); //设置默认选中项,此处为默认选中第4个值
typeAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, text);
typeSpinner.setAdapter(typeAdapter);
typeSpinner.setSelection(0,true); //默认选中第0个
products_nameAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, text);
products_nameSpinner.setAdapter(products_nameAdapter);
products_nameSpinner.setSelection(0, true);
products_noAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, text);
products_noSpinner.setAdapter(products_noAdapter);
products_noSpinner.setSelection(0, true);
functionAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, text);
functionSpinner.setAdapter(functionAdapter);
functionSpinner.setSelection(0, true);
//下拉框监听,单开始选中一个值的时候用,就分别设置每个数据适配器的值,因为有先后有顺序,所以要获取上一个的值,才能设置下一个的值
factorySpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
// 表示选项被改变的时候触发此方法,
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long arg3)
{
try {
typeAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, root.getString(factorySpinner.getItemAtPosition(position).toString()).split("\\$\\$"));
typeSpinner.setAdapter(typeAdapter);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
typeSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3)
{
try {
products_nameAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, root.getString(factorySpinner.getSelectedItem().toString()+
"$$"+typeSpinner.getItemAtPosition(position)).split("\\$\\$"));
products_nameSpinner.setAdapter(products_nameAdapter);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
products_nameSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3)
{
try {
products_noAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, root.getString(factorySpinner.getSelectedItem().toString()+
"$$"+typeSpinner.getSelectedItem().toString()+"$$"+
products_nameSpinner.getItemAtPosition(position).toString()).split("\\$\\$"));
products_noSpinner.setAdapter(products_noAdapter);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
products_noSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
{
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1,
int position, long arg3)
{
try {
functionAdapter = new ArrayAdapter<String>(Main2Activity.this,
android.R.layout.simple_spinner_item, root.getString(factorySpinner.getSelectedItem().toString()+
"$$"+typeSpinner.getSelectedItem().toString()+"$$"+
products_nameSpinner.getSelectedItem().toString()+"$$"+
products_noSpinner.getItemAtPosition(position).toString()).split("\\$\\$"));
functionSpinner.setAdapter(functionAdapter);
}catch (Exception e){
e.printStackTrace();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
}
public void readNet(String url) {
AsyncTask<String, Void, String> execute = new AsyncTask<String, Void, String>() {
@Override
protected String doInBackground(String... params) {
String urlString = params[0];
System.out.println(urlString);
HttpGet get = new HttpGet(urlString);
try {
HttpResponse response = client.execute(get);
String valueString = EntityUtils.toString(response.getEntity());
return valueString;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute (String s) {
try{
synchronized (this){
//最先开始获取顶层的数据,因为他的键值是固定的,在查询的时候不需要条件,我们设置定的为factory;
System.out.println(UrlUtil.getURLDecoderString(s));
root = new JSONObject(UrlUtil.getURLDecoderString(s));
String result = root.getString("result");
String[] string = root.getString("factory").split("\\$\\$");
factory_1 = new String[string.length+1];
factory_1[0] = "请选择";
for (int i = 1;i<string.length+1;i++){
factory_1[i] = string[i-1];
}
//不设置其它内容对会获取不到
super.onPostExecute(result);
}
}catch (Exception e){
e.printStackTrace();
}finally {
waitingDialog.dismiss();
setSpinner();
}
}
}.execute(url);
}
}
<?xml version="1.0" encoding="utf-8"?>
<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="600dp"
android:orientation="vertical"
android:padding="8dp">
<Spinner
android:id="@+id/spin_factory"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Spinner
android:id="@+id/spin_type"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Spinner
android:id="@+id/spin_products_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Spinner
android:id="@+id/spin_products_no"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
<Spinner
android:id="@+id/spin_function"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1" />
</LinearLayout>
</LinearLayout>
好了,就这么写内容,由于当时数据库的问题,就先只能这样获取数据了,在查询上效率会面一些,但是一般不会分类太多,多的话那就是大的项目了,可以事先就存在redis中,用Zset,键值还是键,值还是值就获取的更快了。,内容有点多,可以先运行试试,看看效果或许可以在必要的时候帮助你一点。 有好的解答和疑问可以在下方评论,也可以加我的QQ:1402876003.