1. 程式人生 > 實用技巧 >android spinner非同步載入資料並顯示

android spinner非同步載入資料並顯示

一開始直接繫結介面卡發現點選後並不能顯示選中的值。
解決辦法:利用handle來更新UI。
我利用介面和okhttp的get方法從資料庫拿到所有省份資訊的json資料,在android中定義了一個province實體類來接收list。
province類
package com.example.demo.entity;

public class Province {
    private String province;

    private Province(){}

    public String getProvince() {
        return province;
    }

    
public Province(String province) { this.province = province; } public void setProvince(String province) { this.province = province; } }
重寫adapter類實現該方法
package com.example.demo.entity;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.TextView; import com.example.demo.R; import java.util.List; public class MapAdapter extends BaseAdapter { private Context context; private List<Province> mData;
public MapAdapter(List<Province> mData, Context context) { this.mData = mData; this.context = context; } @Override public int getCount() { return mData != null ? mData.size() : 0; } @Override public Object getItem(int position) { return mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { holder = new ViewHolder(); convertView = LayoutInflater.from(context).inflate(R.layout.item_spin_map , parent , false); holder.name = (TextView) convertView.findViewById(R.id.map_name); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.name.setText(mData.get(position).getProvince()); return convertView; } static class ViewHolder { private TextView name; } }
View Code
重點:在activity的onCreate方法中先使用okhttp的get方法獲得spinner要顯示的物件,此時,
介面卡的set語句(下面三句)不能與get方法一起放在onCreate方法中。因為資料是非同步載入的。
                mapAdapter = new MapAdapter(provinceData,context);
                spin_Province.setAdapter(mapAdapter);
                spin_Province.setOnItemSelectedListener(MapPageActivity.this);
利用handle類來完成適配
private Handler myHandler = new Handler() {
        @Override
        //重寫handleMessage方法,根據msg中what的值判斷是否執行後續操作
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                mapAdapter = new MapAdapter(provinceData,context);
                spin_Province.setAdapter(mapAdapter);
                spin_Province.setOnItemSelectedListener(MapPageActivity.this);
            }
        }
    };
啟動這個類的語句放在上面get方法的末尾,確保資料全部拿到了,再適配
myHandler.sendEmptyMessage(0);
總體activity類如下:
package com.example.demo.activity;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.Toast;

import com.example.demo.ActivityCollector;
import com.example.demo.R;
import com.example.demo.entity.Province;
import com.example.demo.entity.MapAdapter;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.json.JSONArray;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class MapPageActivity extends Activity implements AdapterView.OnItemSelectedListener{
    private Button btnCity,btnCounty;
    private Spinner spin_Province;
    private Context context;
    private List<Province> provinceData;
    private MapAdapter mapAdapter = null;
    //判斷是否為剛進去時觸發onItemSelected的標誌
    private boolean one_selected = false;
    private boolean two_selected = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        context = this;
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_page);
        provinceData = new ArrayList<>();
        ActivityCollector.addActivity(this);
        spin_Province = (Spinner)findViewById(R.id.spin_province);
        btnCity = (Button)findViewById(R.id.btncity);
        btnCounty = (Button)findViewById(R.id.btncounty);
        getProvince();

    }

    private void init(){

    }

    private void getProvince() {
        //第一步獲取okHttpClient物件
        OkHttpClient client = new OkHttpClient.Builder()
                .build();
        //第二步構建Request物件
        String url = "http://192.168.236.1:8181/sewagePlant/province";
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();
        //第三步構建Call物件
        Call call = client.newCall(request);
        //第四步:非同步get請求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.i("ttit", e.getMessage());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                //得到的子執行緒
                String result = response.body().string();
                Gson gson = new Gson();
//                Type type = new TypeToken<List<Province>>(){}.getType();
                List<Province> provinces = gson.fromJson(result, new TypeToken<List<Province>>() {}.getType());
                for (int i = 0; i <provinces.size() ; i++) {
                    Province p = provinces.get(i);
                    provinceData.add(p);
                    Log.i("ttit",p.getProvince());
                }
                myHandler.sendEmptyMessage(0);
            }
        });
    }


    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long l) {
        switch (parent.getId()){
            case R.id.spin_province:
                if (one_selected){

                    Toast.makeText(MapPageActivity.this,"選擇了"+parent.getItemAtPosition(position).toString(),Toast.LENGTH_SHORT).show();
                }else {
                    one_selected = true;
                }
                break;
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }

    private Handler myHandler = new Handler() {
        @Override
        //重寫handleMessage方法,根據msg中what的值判斷是否執行後續操作
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                mapAdapter = new MapAdapter(provinceData,context);
                spin_Province.setAdapter(mapAdapter);
                spin_Province.setOnItemSelectedListener(MapPageActivity.this);
            }
        }
    };
}
View Code