接下来实现物流查询。
根据快递公司缩写和相应的快递单号即可查询,通过listView显示,是一个时间轴的效果。
常见快递公司缩写:
顺丰: sf
圆通: yt
申通: sto
韵达: yd
天天: tt
因为涉及json解析,所以需要api接口,这里我们使用聚合数据提供的物流查询接口,使用Rxvolly解析json数据,添加依赖:
compile 'com.kymjs.rxvolley:rxvolley:1.1.4'
注意,因为之前添加了bmob依赖,二者有冲突的地方,所以我们要进行过滤,添加依赖时加上过滤的语句,包括bmob也要添加,如下:
compile ('cn.bmob.android:bmob-sdk:3.6.3'){
exclude group:"io.reactivex"
}
compile ('com.kymjs.rxvolley:rxvolley:1.1.4'){
exclude group:"io.reactivex"
}
在个人中心界面,点击物流查询即可跳转界面到物流查询的界面,下面是xml布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="快递公司"
android:id="@+id/et_name"
/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="快递单号"
android:id="@+id/et_number"
/>
<Button
android:id="@+id/btn_get_courier"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/button_bg"
android:text="查询"
android:textColor="@android:color/white"/>
<ListView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:id="@+id/mlistView">
</ListView>
</LinearLayout>
初始化控件:
private EditText et_name;
private EditText et_number;
private Button btn_get_courier;
private ListView mListView;
private void initView() {
et_name = (EditText) findViewById(R.id.et_name);
et_number = (EditText) findViewById(R.id.et_number);
btn_get_courier = (Button) findViewById(R.id.btn_get_courier);
btn_get_courier.setOnClickListener(this);
mListView = (ListView) findViewById(R.id.mlistView);
}
接下来是解析数据,点击查询后获取数据,并传递给Rxvolly,
/**
* 1.获取输入框的内容
* 2.判断是否为空
* 3.拿到数据去请求数据(Json)
* 4.解析Json
* 5.listview适配器
* 6.实体类(item)
* 7.设置数据/显示效果
*/
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_get_courier:
//获取输入框的内容
String name=et_name.getText().toString().trim();
String number=et_number.getText().toString().trim();
//json解析的url
String url="http://v.juhe.cn/exp/index?key="+ StaticClass.COURIER_KEY+"&com="+name+"&no="+number;
//输入框内容不为空
if(!TextUtils.isEmpty(name)&&!TextUtils.isEmpty(number)){
//解析
RxVolley.get(url, new HttpCallback() {
@Override
public void onSuccess(String t) {
//解析数据
parsingJson(t);
}
});
}else{
Toast.makeText(this, "输入框内容不能为空!", Toast.LENGTH_SHORT).show();
}
}
}
下面是api提供的json数据样例:
"result": {
"company": "EMS", /* 快递公司名字 */
"com": "ems",
"no": "1186465887499", /* 快递单号 */
"status": "1", /* 1表示此快递单的物流信息不会发生变化,此时您可缓存下来;0表示有变化的可能性 */
"list": [
{
"datetime": "2016-06-15 21:44:04", /* 物流事件发生的时间 */
"remark": "离开郴州市 发往长沙市【郴州市】", /* 物流事件的描述 */
"zone": "" /* 快件当时所在区域,由于快递公司升级,现大多数快递不提供此信息 */
},
{
"datetime": "2016-06-15 21:46:45",
"remark": "郴州市邮政速递物流公司国际快件监管中心已收件(揽投员姓名:侯云,联系电话:)【郴州市】",
"zone": ""
},
{
"datetime": "2016-06-16 12:04:00",
"remark": "离开长沙市 发往贵阳市(经转)【长沙市】",
"zone": ""
},
{
可以看到我们要先获取result 的内容,然后获取result里面的list数组里面的内容,list里面的内容是我们要显示在界面上的,所以我们要创建实体类保存内容。
实体类
public class CourierData {
private String datetime;
private String remark;
private String zone;
public String getDatetime() {
return datetime;
}
public void setDatetime(String datetime) {
this.datetime = datetime;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
}
listviewitem的布局文件为:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal">
<LinearLayout
android:layout_width="60dp"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical">
<View
android:layout_width="2dp"
android:layout_height="30dp"
android:background="@color/colorPrimary"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/timeline_green"/>
<View
android:layout_width="2dp"
android:layout_height="100dp"
android:background="@color/colorPrimary"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:layout_weight="1"
android:background="@drawable/timeline_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/tv_remark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:text="你的快件已经到达北京"
android:textColor="@color/colorPrimary"
android:textSize="18sp"/>
<TextView
android:id="@+id/tv_zone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:paddingLeft="10dp"
android:text="北京"
android:textColor="@color/colorAccent"
android:textSize="15sp"/>
<TextView
android:id="@+id/tv_datetime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:text="2016-11-12"/>
</LinearLayout>
</LinearLayout>
要让listview里面有数据,就需要适配器,适配器是连接数据和view的桥梁
public class CourierAdapter extends BaseAdapter {
/*
适配器实现步骤:
1. 继承自BaseAdapter
2. 实现其抽象方法
3. 创建构造方法(上下文,数据)
4. 布局加载器LayoutInflater,并获取系统服务
5. ViewHolder
*/
private Context mContext;
private List<CourierData> mList;
//布局加载器
private LayoutInflater inflater;
private CourierData data;
public CourierAdapter(Context mContext, List<CourierData> mList) {
this.mContext = mContext;
this.mList = mList;
//获取系统服务
inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = null;
//为null则是第一次加载,加载到缓存中
if(convertView == null){
viewHolder = new ViewHolder();
//加载布局
convertView = inflater.inflate(R.layout.layout_courier_item,null);
viewHolder.tv_remark = (TextView) convertView.findViewById(R.id.tv_remark);
viewHolder.tv_zone = (TextView) convertView.findViewById(R.id.tv_zone);
viewHolder.tv_datetime = (TextView) convertView.findViewById(R.id.tv_datetime);
//设置缓存
convertView.setTag(viewHolder);
}else{
//不是第一次加载
viewHolder = (ViewHolder) convertView.getTag();
}
//设置数据
data = mList.get(position);
viewHolder.tv_remark.setText(data.getRemark());
viewHolder.tv_zone.setText(data.getZone());
viewHolder.tv_datetime.setText(data.getDatetime());
return convertView;
}
//listitem里面的空间
class ViewHolder{
private TextView tv_remark;
private TextView tv_zone;
private TextView tv_datetime;
}
}
CourierActivity:
public class CourierActivity extends BaseActivity implements View.OnClickListener {
private EditText et_name;
private EditText et_number;
private Button btn_get_courier;
private ListView mListView;
private List<CourierData> mList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_courier);
initView();
}
//初始化View
private void initView() {
et_name = (EditText) findViewById(R.id.et_name);
et_number = (EditText) findViewById(R.id.et_number);
btn_get_courier = (Button) findViewById(R.id.btn_get_courier);
btn_get_courier.setOnClickListener(this);
mListView = (ListView) findViewById(R.id.mListView);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_get_courier:
/**
* 1.获取输入框的内容
* 2.判断是否为空
* 3.拿到数据去请求数据(Json)
* 4.解析Json
* 5.listview适配器
* 6.实体类(item)
* 7.设置数据/显示效果
*/
//1.获取输入框的内容
String name = et_name.getText().toString().trim();
String number = et_number.getText().toString().trim();
//拼接我们的url
String url = "http://v.juhe.cn/exp/index?key=" + StaticClass.COURIER_KEY
+ "&com=" + name + "&no=" + number;
//2.判断是否为空
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(number)) {
//3.拿到数据去请求数据(Json)
RxVolley.get(url, new HttpCallback() {
@Override
public void onSuccess(String t) {
//Toast.makeText(CourierActivity.this, t, Toast.LENGTH_SHORT).show();
L.i("Courier:" + t);
//4.解析Json
parsingJson(t);
}
});
} else {
Toast.makeText(this, getString(R.string.text_tost_empty), Toast.LENGTH_SHORT).show();
}
break;
}
}
//解析数据
private void parsingJson(String t) {
try {
JSONObject jsonObject = new JSONObject(t);
JSONObject jsonResult = jsonObject.getJSONObject("result");
JSONArray jsonArray = jsonResult.getJSONArray("list");
//遍历arrayList
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = (JSONObject) jsonArray.get(i);
CourierData data = new CourierData();
data.setRemark(json.getString("remark"));
data.setZone(json.getString("zone"));
data.setDatetime(json.getString("datetime"));
//加载到list中
mList.add(data);
}
//倒序(列表倒叙,最高是已签收)
Collections.reverse(mList);
CourierAdapter adapter = new CourierAdapter(this,mList);
mListView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}