利用ListView实现类似物流详情的进度显示

背景:点击产品单号列表中的进度查看按钮,跳转至进度页面,显示该产品单号的进度。

真实物流的信息当然是动态生成的,此处产品单号的数据是顺序且固定的,仿照的只是物流详情的UI。

实现效果图:

一、UI实现

页面布局文件:

<?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" >
    <include layout="@layout/titile_1"></include>
    
    <LinearLayout 
        android:orientation="horizontal"
        android:paddingTop="15dp"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:paddingLeft="20dp"
        android:background="@color/white">
        <TextView 
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:id="@+id/process_code"
            android:textSize="18dp"
            android:paddingLeft="5dp"
            android:textStyle="bold|italic"/>
        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/emblem"
            android:id="@+id/process_img"
            android:scaleType="fitXY"
            android:listSelector="@android:color/transparent"
            android:layout_marginRight="30dp"
            />
    </LinearLayout>
    
    <ListView
        android:layout_marginTop="8dp"
        android:paddingBottom="10dp"
        android:id="@+id/process_list"
        android:background="@color/white"
        android:clickable="false"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:divider="#00000000">    
    </ListView>

android:divider="#00000000"将ListView的分割线设为透明,并且设置无法获取焦点和无法点击

ListView的item布局:

<?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="horizontal"
    android:gravity="center_horizontal" >

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_weight="9"
        android:gravity="center_horizontal">

        <View
            android:id="@+id/item_driver1"
            android:layout_width="0.5dp"
            android:layout_height="20dp"
            android:background="@color/black"
            android:layout_marginLeft="7.3dp"/>

        <ImageView
            android:id="@+id/item_node"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@id/item_driver1"
            android:src="@drawable/node_pass"
            android:scaleType="fitXY"/>

        <View
            android:id="@+id/item_driver2"
            android:layout_width="0.5dp"
            android:layout_height="30dp"
            android:layout_below="@id/item_node"
            android:background="@color/black"
            android:layout_marginLeft="7.3dp"/>
    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_weight="2"
        android:background="@color/white"
        android:orientation="horizontal" 
        android:layout_gravity="center_vertical"
        android:gravity="center_vertical"
        android:paddingLeft="12dp"
        android:layout_marginRight="12dp">

        <TextView
            android:id="@+id/pro_date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/pro_status"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</LinearLayout>

左边图片部分,由两条View和一个ImageView实现,ImageView的两个图片:

ImageView图片默认是灰色,在代码中将最新的状态设置为绿色图片

二、数据实现

Java代码:

package com.example.cwapp.activity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.example.cwapp.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

public class ProcessActivity extends Activity {
    private ListView list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.process);
        Bundle bundle = getIntent().getExtras();
        String process = bundle.getString("pro");
        
        list = (ListView) findViewById(R.id.process_list);
       
        ArrayList<HashMap<String, Object>> all = new ArrayList<HashMap<String, Object>>();
        List<HashMap<String, Object>> array = new ArrayList<HashMap<String, Object>>();
        HashMap<String, Object> map0 = new HashMap<String, Object>();
        map0.put("pro_status", "您的订单开始处理");
        HashMap<String, Object> map1 = new HashMap<String, Object>();
        map1.put("pro_status", "您的订单待配货");
        HashMap<String, Object> map2 = new HashMap<String, Object>();
        map2.put("pro_status", "您的包裹已出库");
        HashMap<String, Object> map3 = new HashMap<String, Object>();
        map3.put("pro_status", "包裹正待等待揽收");
        HashMap<String, Object> map4 = new HashMap<String, Object>();
        map4.put("pro_status", "xx快递已揽件");
        all.add(map4);
        all.add(map3);
        all.add(map2);
        all.add(map1);
        all.add(map0);

        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("您的订单开始处理", 0);
        map.put("您的订单待配货", 1);
        map.put("您的包裹已出库", 2);
        map.put("包裹正待等待揽收", 3);
        map.put("xx快递已揽件", 4);
        switch (map.get(process)) {
        case 0:
            array = all.subList(4, 5);
            break;
        case 1:
            array = all.subList(3, 5);
            break;
        case 2:
            array = all.subList(2, 5);

            break;
        case 3:
            array = all.subList(1, 5);

            break;
        case 4:
            array = all.subList(0, 5);
            break;
        }
        mySimpleAdapter adapter = new mySimpleAdapter(ProcessActivity.this, array,
                R.layout.process_item, new String[] { "pro_status" },
                new int[] { R.id.pro_status });
        list.setAdapter(adapter);
        list.setOnTouchListener(new View.OnTouchListener() {
            
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });

    }

    class mySimpleAdapter extends SimpleAdapter {
        private ImageView node;
        private View view;
        private TextView status;
        @Override
        public int getCount() {
            return super.getCount();
        }

        public mySimpleAdapter(Context context,
                List<? extends Map<String, ?>> data, int resource,
                String[] from, int[] to) {
            super(context, data, resource, from, to);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("getView");
            convertView = getLayoutInflater()
                    .inflate(R.layout.process_item, null);
            
            if(position == 0){
                node = (ImageView)convertView.findViewById(R.id.item_node);
                node.setImageResource(R.drawable.node_now);
                view = convertView.findViewById(R.id.item_driver1);
                view.setVisibility(View.INVISIBLE);
                status = (TextView)convertView.findViewById(R.id.pro_status);
                status.setTextColor(Color.parseColor("#4FBA6F"));
            }
            return super.getView(position, convertView, parent);
        }
    }
}

用ArrayList变量all将一个产品单号的全部状态按顺序存储起来,String变量process是传来的产品单号最新的进度状态,由于状态顺序是固定的,每个状态所处的位置已知,此时只许根据process的值来分割all,得到的的子集作为适配器的数据源。(注意为实现从上往下时间降序的效果,all按时间降序存储,分割子集时则需要从尾部进行分割)

分割技巧:如果使用 if 语句依次判断process的值来进行分割,代码冗余。这里用Map和switch-case将字符串转换成数值(解决switch case无法匹配字符串的问题):事先用HashMap<String,Integer> map把字符串作为key,为其设置一个数值value存储;在对str字符串进行匹配时,根据map.get(str)获得其对应的数值,最后通过switch-case判断数值转到对应项。此处利用上述技巧:为每个状态设置一个数值,map.get(process)获得process的对用数值,switch case匹配跳转实现分割。

设置ListView监听器重写onTouch返回true,去除ListView的点击效果。参考View的事件分发机制。

list.setOnTouchListener(new View.OnTouchListener() {
            
            public boolean onTouch(View v, MotionEvent event) {
                return true;
            }
        });

自定义SimpleAdapter,重写getView绘图。把最新状态的文字变为绿色,其所在item的ImageView图片变为绿色图片,保留ImageView下面的View,隐藏上面的View,需要注意的是array把正常进度顺序反向存储,最底层是最新状态,所以getView中的判断条件是position == 0。



 

posted on 2017-07-03 18:17  WitchMariana  阅读(320)  评论(0编辑  收藏  举报

导航