
该效果完全是使用ListView来实现了,下面我们来看一下是如何实现的
(一):布局ListView并编写Item布局
首先需要在布局上面编写ListView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.bobo.trace.MainActivity" ><ListView android:id="@+id/lv_trace"android:layout_width="match_parent"android:layout_height="match_parent"android:divider="@drawable/trace_divider"android:dividerHeight="1dp"></ListView></RelativeLayout>
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent" ><RelativeLayout android:id="@+id/rl_trace_item"android:layout_width="match_parent"android:layout_height="wrap_content"><Viewandroid:id="@+id/v_up_line"android:layout_width="2.5dp"android:layout_height="10dp"android:background="@color/mgrey"android:layout_marginLeft="22dp"></View><ImageView android:id="@+id/iv_state"android:layout_width="16dp"android:layout_height="16dp"android:src="@drawable/circle"android:layout_marginTop="10dp"android:layout_marginLeft="15dp"/><TextView android:id="@+id/tv_trace_info"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:layout_toRightOf="@id/iv_state"android:layout_marginLeft="20dp"android:text="@string/test_trace_info"android:textColor="@android:color/black"android:textSize="13sp"/><LinearLayout android:id="@+id/ll_trace_phone"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="3dp"android:layout_toRightOf="@id/iv_state"android:layout_marginLeft="20dp"android:orientation="horizontal"android:layout_below="@id/tv_trace_info"><TextView android:id="@+id/tv_phone_label"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/phone_label"android:textColor="@android:color/black"android:textSize="13sp"/><TextView android:id="@+id/tv_phone"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="5dp"android:text="@string/test_phone"android:textColor="@android:color/black"android:textSize="13sp"/></LinearLayout><TextView android:id="@+id/tv_trace_time"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="3dp"android:layout_toRightOf="@id/iv_state"android:layout_marginLeft="20dp"android:text="@string/test_trace_info"android:textColor="@android:color/black"android:textSize="13sp"android:layout_below="@id/ll_trace_phone"/><Viewandroid:id="@+id/v_down_line"android:layout_width="2.5dp"android:layout_height="45dp"android:background="@color/mgrey"android:layout_below="@id/iv_state"android:layout_marginLeft="22dp"></View></RelativeLayout></RelativeLayout>下面我们来看一下item效果:

在上面的效果图中,我们就可以看出,在这个item布局中,左边是”线-图片-线“的布局,显示一个时间轴,右边显示相应的信息,包括物流信息,联系电话和时间;我们知道,在时间轴中,第一个点是不需要上面那个线的,最后一个点是不需要下面那个线的,所以,这个的处理就需要我们在Adapter中进行相应的处理。
(二):自定义Adapter
下面我们就需要自定义Adapter来填充数据和进行View处理。
当然,在编写Adapter之前,我们需要一个javabean来保存相应的信息。
Trace.java:
package com.bobo.beans;public class Trace {private boolean isHead;private String info;private String phone;private String time;public Trace(boolean isHead, String info, String phone, String time) {super();this.isHead = isHead;this.info = info;this.phone = phone;this.time = time;}public boolean isHead() {return isHead;}public void setHead(boolean isHead) {this.isHead = isHead;}public String getInfo() {return info;}public void setInfo(String info) {this.info = info;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getTime() {return time;}public void setTime(String time) {this.time = time;}}下面我们就可以愉快的编写Adapter类了:package com.bobo.adapters;import java.util.ArrayList;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.LinearLayout;import android.widget.TextView;import com.bobo.beans.Trace;import com.bobo.trace.R;public class TraceAdapter extends BaseAdapter {private ArrayList<Trace> tradeLists = null;private LayoutInflater inflater;private Context context;public TraceAdapter(ArrayList<Trace> tradeLists,Context context){this.tradeLists = tradeLists;this.context = context;this.inflater = LayoutInflater.from(context);}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn tradeLists == null ? 0 : tradeLists.size();}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn tradeLists.get(position);}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Holder holder;if(convertView == null){convertView = inflater.inflate(R.layout.trace_item, null);holder = new Holder();holder.v_up_line = (View)convertView.findViewById(R.id.v_up_line);holder.iv_state = (ImageView)convertView.findViewById(R.id.iv_state);holder.tv_trace_info = (TextView)convertView.findViewById(R.id.tv_trace_info);holder.ll_trace_phone = (LinearLayout)convertView.findViewById(R.id.ll_trace_phone);holder.tv_phone = (TextView)convertView.findViewById(R.id.tv_phone);holder.tv_trace_time = (TextView)convertView.findViewById(R.id.tv_trace_time);holder.v_down_line = (View)convertView.findViewById(R.id.v_down_line);convertView.setTag(holder);}else{holder = (Holder)convertView.getTag();}if(tradeLists.get(position).isHead()){holder.v_up_line.setVisibility(View.GONE);//holder.iv_state = (ImageView)convertView.findViewById(R.id.iv_state);holder.tv_trace_info.setText(tradeLists.get(position).getInfo());holder.tv_phone.setText(tradeLists.get(position).getPhone());holder.tv_trace_time.setText(tradeLists.get(position).getTime());holder.v_down_line.setVisibility(View.VISIBLE);}else if(tradeLists.size() == (position+1)){holder.tv_trace_info.setText(tradeLists.get(position).getInfo());holder.ll_trace_phone.setVisibility(View.GONE);holder.tv_trace_time.setText(tradeLists.get(position).getTime());holder.v_down_line.setVisibility(View.GONE);}else{holder.tv_trace_info.setText(tradeLists.get(position).getInfo());holder.ll_trace_phone.setVisibility(View.GONE);holder.tv_trace_time.setText(tradeLists.get(position).getTime());holder.v_down_line.setVisibility(View.VISIBLE);}return convertView;}class Holder{View v_up_line;ImageView iv_state;TextView tv_trace_info;LinearLayout ll_trace_phone;TextView tv_phone;TextView tv_trace_time;View v_down_line;}}这样,我们的Adapter就已经适配完成,下面我们在Activity中实验一下。package com.bobo.trace;import java.util.ArrayList;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.widget.ListView;import com.bobo.adapters.TraceAdapter;import com.bobo.beans.Trace;public class MainActivity extends Activity {private ListView lv_trace;private ArrayList<Trace> tradeLists = new ArrayList<Trace>();private TraceAdapter ta;private Context context;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);context = MainActivity.this;initView();}private void initView(){lv_trace = (ListView)findViewById(R.id.lv_trace);initData();ta = new TraceAdapter(tradeLists, context);lv_trace.setAdapter(ta);}private void initData(){tradeLists.add(new Trace(true, "商家已从广东发货", "15253157943", "2016-03-16 13:30:43"));tradeLists.add(new Trace(false, "货物正在配送", "", "2016-03-16 18:30:43"));tradeLists.add(new Trace(false, "货物已到达天津转运中心", "", "2016-03-17 13:30:43"));tradeLists.add(new Trace(false, "货品已到济南货运站", "", "2016-03-18 13:30:43"));tradeLists.add(new Trace(false, "货物已送达济南高新区站点", "", "2016-03-19 13:30:43"));}}这样运行之后,我们就会发现,ListView的selector宽度是占满全屏的,这样,我们就需要编写一个inset来调整ListView的selector。<?xml version="1.0" encoding="utf-8"?><inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="50dp"android:drawable="@color/mgrey"></inset>这样,我们的物流追踪界面就算是完成了,很简单。