Android自定义指示器时间轴

指示器时间轴 在外卖、购物类的APP里会经常用到 ,效果大概就像下面这样,看了网上很多文章,大都是自己绘制,太麻烦,其实通过ListView就可以实现。
 
在Activity关联的布局文件activity_main.xml中放置一个ListView,代码如下。由于这个列表只是用于展示信息,并不需要用户去点击,所以将其 clickable属性置为false;为了消除ListView点击产生的波纹效果,我们设置其listSelector属性的值为透明;我们不需要列表项之间的分割线,所以设置 其divider属性的值为null。
activity_main
<ListView
     android:id= "@+id/lvTrace"
     android:layout_width= "match_parent"
     android:layout_height= "wrap_content"
     android:clickable= "false"
     android:divider= "@null"
     android:dividerHeight= "0dp"
     android:listSelector= "@android:color/transparent" />
 
每个列表项的布局stepview_adapter.xml,代码如下。由于时间轴的点和线都位于item布局中,为了使线是连续的,所以设置上面ListView的 dividerHeight 属性值为0dp,即垂直方向每个列表项都是紧挨着的。在item的布局中,我们先使用LinearLayout将布局分成左右两个部分,左边就是时间 轴的布局,右边是 内容 的布局。

内容的布局,物流信息是一个RelativeLayout,为了不使两个列表项的文本靠得太近,在RelativeLayout中设置其paddingBottom和paddingTop属性。

时间轴的布局,时间轴的布局也是一个RelativeLayout,为了使时间轴的圆点和显示时间的文本对齐,我们需要在圆点之上再放置一条竖线,所以整体的布局就是 线 - 点 - 线。为了让线可以正好对准圆点的中心,我们让线和点都水平居中,即android:layout_centerHorizontal="true"

stepview_adapter
<?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"
     android:orientation= "horizontal" >
 
     <RelativeLayout
         android:id= "@+id/rlTimeline"
         android:layout_width= "wrap_content"
         android:layout_marginLeft= "15dp"
         android:layout_height= "match_parent" >
 
         <TextView
             android:id= "@+id/tvTopLine"
             android:layout_width= "1.2dp"
             android:layout_height= "12dp"
             android:layout_centerHorizontal= "true"
             android:background= "#999" />
 
         <TextView
             android:id= "@+id/tvDot"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_below= "@id/tvTopLine"
             android:layout_centerHorizontal= "true"
             android:background= "@drawable/state_get_huankuan" />
 
         <TextView
             android:layout_width= "1.2dp"
             android:id= "@+id/tvLine"
             android:layout_height= "match_parent"
             android:layout_below= "@id/tvDot"
             android:layout_centerHorizontal= "true"
             android:background= "#999" />
     </RelativeLayout>
 
     <RelativeLayout
         android:id= "@+id/rlCenter"
         android:layout_width= "match_parent"
         android:layout_height= "match_parent"
         android:paddingBottom= "6dp"
         android:paddingRight= "10dp"
         android:layout_marginLeft= "20dp"
         android:paddingTop= "12dp" >
 
         <TextView
             android:id= "@+id/step_tv_time"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_alignParentRight= "true"
             android:layout_marginRight= "6dp"
             android:text= "10-20 22:22"
             android:textColor= "#cccccc"
             android:textSize= "12sp" />
 
         <TextView
             android:id= "@+id/step_tv_des"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_alignParentLeft= "true"
             android:layout_marginRight= "15dp"
             android:textStyle= "bold"
             android:layout_toLeftOf= "@+id/step_tv_time"
             android:text= "fffffff" />
 
         <TextView
             android:id= "@+id/step_tv_des_below"
             android:layout_width= "wrap_content"
             android:layout_height= "wrap_content"
             android:layout_alignParentLeft= "true"
             android:layout_below= "@+id/step_tv_des"
             android:layout_marginTop= "5dp"
             android:text= ""
             android:textColor= "#999999" />
     </RelativeLayout>
</LinearLayout><br><br><br>
定义一个Adapter,代码如下。由于第一行的物流信息的显示形式和其他的不一样,所以要注意 第一行的item的时间轴布局中最上面的线不显示
public class StepViewAdapter extends BaseAdapter {
     private Context context;
     private List<StepViewBean> traceList = new ArrayList<>();
     private static final int TYPE_FINISH = 101;
     private static final int TYPE_UNFINISH = 102;
     private static final int TYPE_ERROR = 103;
 
     public StepViewAdapter(Context context, List<StepViewBean> traceList) {
         this .context = context;
         this .traceList = traceList;
     }
 
     @Override
     public int getCount() {
         return traceList.size();
     }
 
     @Override
     public StepViewBean getItem( int position) {
         return traceList. get (position);
     }
 
     @Override
     public long getItemId( int position) {
         return position;
     }
 
     @Override
     public View getView( int position, View convertView, ViewGroup parent) {
         ViewHolder holder;
         final StepViewBean trace = getItem(position);
         if (convertView != null ) {
             holder = (ViewHolder) convertView.getTag();
         } else {
             holder = new ViewHolder();
             convertView = LayoutInflater. from (context).inflate(R.layout.stepview_adapter, parent, false );
             holder.tvTopLine = (TextView) convertView.findViewById(R.id.tvTopLine);
             holder.tvDot = (TextView) convertView.findViewById(R.id.tvDot);
             holder.tvLine = (TextView) convertView.findViewById(R.id.tvLine);
             holder.tvAcceptStation = (TextView) convertView.findViewById(R.id.step_tv_des);
             holder.tvAcceptTime = (TextView) convertView.findViewById(R.id.step_tv_time);
             holder.tvAcceptStationBelow = (TextView) convertView.findViewById(R.id.step_tv_des_below);
             holder.rlTimeline = (RelativeLayout) convertView.findViewById(rlTimeline);
 
             convertView.setTag(holder);
         }
         if (position == 0) {
             holder.tvTopLine.setVisibility(View.INVISIBLE);
         }
         if (position == traceList.size() - 1) {
             holder.tvLine.setVisibility(View.GONE);
         } else {
             holder.tvLine.setVisibility(View.VISIBLE);
         }
         switch (getItemViewType(position)) {
             case TYPE_FINISH:
                 holder.tvAcceptStation.setTextColor(context.getResources().getColor(R.color.crt_completed));
                 holder.tvDot.setBackgroundResource(R.drawable.state_get_huankuan);
                 holder.tvLine.setBackgroundColor(context.getResources().getColor(R.color.crt_completed));
                 holder.tvTopLine.setBackgroundColor(context.getResources().getColor(R.color.crt_completed));
                 break ;
             case TYPE_UNFINISH:
                 holder.tvAcceptStation.setTextColor(context.getResources().getColor(R.color.crt_uncompleted_text));
                 holder.tvDot.setBackgroundResource(R.drawable.state_normal_huankuan);
                 holder.tvLine.setBackgroundColor(context.getResources().getColor(R.color.crt_text_hint_color));
                 break ;
             case TYPE_ERROR:
                 holder.tvTopLine.setVisibility(View.VISIBLE);
                 holder.tvAcceptStation.setTextColor(context.getResources().getColor(R.color.crt_error_text));
                 holder.tvDot.setBackgroundResource(R.drawable.state_lose_huankuan);
                 break ;
         }
 
         holder.tvAcceptTime.setText(trace.getAcceptTime());
         holder.tvAcceptStation.setText(trace.getAcceptStation());
         if (!TextUtils.isEmpty(trace.getAcceptStation())) {
             holder.tvAcceptStationBelow.setText(trace.getAcceptStationBelow());
         }
         return convertView;
     }
 
     @Override
     public int getItemViewType( int id) {
           if (id==(traceList.size()-2)){
               return TYPE_ERROR;
           }
           if (id==(traceList.size()-1)){
               return TYPE_UNFINISH;
           }
           return TYPE_FINISH;
     }
 
 
     static class ViewHolder {
         public TextView tvAcceptTime, tvAcceptStation, tvLine, tvAcceptStationBelow;
         public TextView tvTopLine, tvDot;
         public RelativeLayout rlTimeline;
 
     }
}
 
为了可以看到布局的效果,在 Activity 中模拟一些假数据。需要定义一个实体类 Trace ,它有两个属性, acceptTime acceptStation ,代码如下:
StepViewBean
public class StepViewBean {
     /** 时间 */
     private String acceptTime;
     /** 描述 */
     private String acceptStation;
     /** 描述下方*/
     private String acceptStationBelow;
 
     public String getAcceptStationBelow() {
         return acceptStationBelow;
     }
 
     public void setAcceptStationBelow(String acceptStationBelow) {
         this .acceptStationBelow = acceptStationBelow;
     }
 
 
 
     public StepViewBean() {
     }
 
     public StepViewBean(String acceptTime, String acceptStation) {
         this .acceptTime = acceptTime;
         this .acceptStation = acceptStation;
     }
 
     public StepViewBean(String acceptTime, String acceptStation, String acceptStationBelow) {
         this .acceptTime = acceptTime;
         this .acceptStation = acceptStation;
         this .acceptStationBelow = acceptStationBelow;
 
     }
 
     public String getAcceptTime() {
         return acceptTime;
     }
 
     public void setAcceptTime(String acceptTime) {
         this .acceptTime = acceptTime;
     }
 
     public String getAcceptStation() {
         return acceptStation;
     }
 
     public void setAcceptStation(String acceptStation) {
         this .acceptStation = acceptStation;
     }
}

  

MainActivity
public class MainActivity extends AppCompatActivity {
     private List<StepViewBean> traceList = new ArrayList<>();
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
         ListView lvTrace= (ListView) findViewById(R.id.lvTrace);
         traceList.add( new StepViewBean( "10-20 22: 22" , "您的订单已打印完毕" , "招商银行(9979) 小明\n支付金额   100000" ));
         traceList.add( new StepViewBean( "10-20 22:22" , "您已提交定单,等待系统确认" ));
         traceList.add( new StepViewBean( "10-20 22:24" , "您的订单已拣货完成" ));
         traceList.add( new StepViewBean( "10-20 22:24" , "扫描员已经扫描" ));
         traceList.add( new StepViewBean( "10-20 22:24" , "您的订单已拣货完成" ));
         traceList.add( new StepViewBean( "10-20 22:24" , "感谢你在京东购物,欢迎你下次光临!" ));
         StepViewAdapter adapter = new StepViewAdapter( this , traceList);
         lvTrace.setAdapter(adapter);
     }
}

   

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值