android 仿淘宝物流时间轴控件

Android 仿淘宝物流时间轴控件

在这里感谢一片作者的demo,我在他的基础上做了写修改 ,改成我们项目所用的样式!还是那句话没有实现不了的需求,只有想不到的。首先看我们项目的设计图。 
这里写图片描述

首先看一下别人的自定义时间轴控件,是通过画布的方法自己写的一个view.

`public class TimeLineView extends View {

private Paint mPaint;
/**
 * 第一个节点的外半径
 */
private float timelineHeadRadius;
/**
 * 第一个节点的颜色值
 */
// private int timelineHeadColor;
/**
 * 第二个节点的颜色值
 */
private int timelineOtherColor;
/**
 * 时间线的节点数
 */
private int timelineCount;
/**
 * 时间轴的位置
 */
private int viewWidth;
/**
 * 时间轴到距离顶部的距离
 */
private int marginTop;
/**
 * 时间轴的节点的半径
 */
private int timelineRadius;
/**
 * 时间轴节点之间的距离
 */
private int timelineRadiusDistance;
/**
 * 时间轴的宽度
 */
private int timelineWidth;
/**
 * 时间轴的高度
 */
private float timeLineViewHeight;

/**
 * 自己需求第一个显示的颜色图片
 * */

private Bitmap bitmapHead;

public TimeLineView(Context context) {
    this(context, null);
}

public TimeLineView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}

public TimeLineView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init(context, attrs, defStyle);
}

/**
 * 初始化
 *
 * @param context
 * @param attrs
 * @param defStyle
 */
private void init(Context context, AttributeSet attrs, int defStyle) {

    final TypedArray a = getContext().obtainStyledAttributes(attrs,
            R.styleable.TimeLineView, defStyle, 0);
    timelineRadiusDistance = (int) a.getDimension(
            R.styleable.TimeLineView_timelineRadiusDistance,
            convertDIP2PX(context, 20));
    // timelineHeadRadius =
    // a.getDimension(R.styleable.TimeLineView_timelineHeadRadius,
    // convertDIP2PX(context, 10));
    timelineRadius = (int) a.getDimension(
            R.styleable.TimeLineView_timelineRadius,
            convertDIP2PX(context, 5));
    // timelineHeadColor =
    // a.getColor(R.styleable.TimeLineView_timelineHeadColor,
    // Color.parseColor("#F15719"));
    timelineOtherColor = a.getColor(
            R.styleable.TimeLineView_timelineOtherColor,
            Color.parseColor("#A8A8A8"));
    timelineCount = a.getInteger(R.styleable.TimeLineView_timelineCount, 0);
    timelineWidth = (int) a.getDimension(
            R.styleable.TimeLineView_timelineWidth,
            convertDIP2PX(context, 1));
    marginTop = (int) a.getDimension(
            R.styleable.TimeLineView_timelineMarginTop,
            convertDIP2PX(context, 50));
    a.recycle();

    mPaint = new Paint();
    mPaint.setAntiAlias(true);

    Resources res = getResources();
    bitmapHead = BitmapFactory.decodeResource(res,
            R.drawable.icon_logistics);

}

/**
 * 画出Bitmap
 * 
 * @param canvas
 * @param src
 * @param dst
 * @param bitmap
 */
private void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap) {
    dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(),
            bitmap.getHeight()) : dst);
    Paint paint = new Paint();
    // canvas.drawBitmap(bitmap, src, dst, paint);
    canvas.drawBitmap(bitmap, viewWidth - (bitmap.getWidth() / 2),
            timelineHeadRadius + marginTop - (bitmap.getHeight() / 2) - 10,
            paint);
}

@Override
protected void onDraw(Canvas canvas) {
    // 默认设置时间轴的位置位于view的中间
    viewWidth = getMeasuredWidth() / 2;
    // 设置第一个节点的颜色
    // mPaint.setColor(timelineHeadColor);
    /**
     * 根据时间轴的节点数目,画对应的节点和轴
     */
    for (int j = 1; j <= timelineCount; j++) {

        /**
         * 当j==1,画第一个节点的时候,有点特殊,我们需要在节点的外面再换一个圆环
         */
        if (j == 1) {
            Rect dstRect = new Rect();
            drawBitmap(canvas, null, null, bitmapHead);

            // 画笔设置为空心
            // canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop,
            // timelineRadius, mPaint);
            // mPaint.setStyle(Paint.Style.STROKE);
            // mPaint.setStrokeWidth(5.0f);
            // //画第一个节点外围的圆环
            // canvas.drawCircle(viewWidth, timelineHeadRadius + marginTop,
            // timelineHeadRadius, mPaint);
            // 设置画笔颜色,画其他时间节点的颜色
            mPaint.setColor(timelineOtherColor);
            // 画笔设置为实心
            mPaint.setStyle(Paint.Style.FILL);
            /**
             * 画第一个节点下面的轴
             */
            canvas.drawRect(new Rect(viewWidth - timelineWidth / 2,
                    (int) (2 * timelineHeadRadius + marginTop) + 5,
                    viewWidth + timelineWidth / 2, (int) (2
                            * timelineHeadRadius + timelineRadiusDistance
                            + marginTop + 5)), mPaint);
            continue;
        }
        /**
         * 画时间轴的节点,即画圆形 圆心的x都是一样的,view的中间
         * 圆心的y的计算是根据节点的位置来计算的,例如:第一个节点的y是根据第一个节点距离上面的距离加上第一个节点的半径
         * :timelineHeadRadius + marginTop
         * 其余的节点就是在一个节点的y的基础上,加上两倍半径和节点之间的轴的长度*节点数:(2 * timelineRadius +
         * timelineRadiusDistance) * (j - 1) + timelineHeadRadius -
         * timelineRadius + marginTop
         *
         */
        canvas.drawCircle(viewWidth,
                (2 * timelineRadius + timelineRadiusDistance) * (j - 1) + 2
                        * timelineHeadRadius - timelineRadius + marginTop,
                timelineRadius, mPaint);
        /**
         *   画其余的轴 left:每个轴距离左边距离都是一样的   时间轴的中心位置-1/2的时间轴的宽度 viewWidth -
         * timelineWidth / 2 top: (int) (j * (2 * timelineRadius +
         * timelineRadiusDistance) - timelineRadiusDistance + 2 *
         * (timelineHeadRadius-timelineRadius)+ marginTop) 
         * right:每个轴距离右边距离都是一样的   时间轴的中心位置+1/2的时间轴的宽度 viewWidth +
         * timelineWidth / 2 bottom: (int) (j * (2 * timelineRadius +
         * timelineRadiusDistance) + 2 *
         * (timelineHeadRadius-timelineRadius)+ marginTop)
         */

        if (j < timelineCount) {
            canvas.drawRect(
                    new Rect(
                            viewWidth - timelineWidth / 2,
                            (int) (j
                                    * (2 * timelineRadius + timelineRadiusDistance)
                                    - timelineRadiusDistance + 2
                                    * (timelineHeadRadius - timelineRadius) + marginTop),
                            viewWidth + timelineWidth / 2,
                            (int) (j
                                    * (2 * timelineRadius + timelineRadiusDistance)
                                    + 2
                                    * (timelineHeadRadius - timelineRadius) + marginTop)),
                    mPaint);
        }

    }
}

public float getTimelineHeadRadius() {
    return timelineHeadRadius;
}

public void setTimelineHeadRadius(float timelineHeadRadius) {

    this.timelineHeadRadius = timelineHeadRadius;
    invalidate();
}

// public int getTimelineHeadColor() {
// return timelineHeadColor;
// }
//
// public void setTimelineHeadColor(int timelineHeadColor) {
//
// this.timelineHeadColor = timelineHeadColor;
// invalidate();
// }

public int getTimelineOtherColor() {
    return timelineOtherColor;
}

public void setTimelineOtherColor(int timelineOtherColor) {
    this.timelineOtherColor = timelineOtherColor;
    invalidate();
}

public int getTimelineCount() {
    return timelineCount;
}

public void setTimelineCount(int timelineCount) {
    this.timelineCount = timelineCount;
    invalidate();
}

public int getMarginTop() {
    return marginTop;
}

public void setMarginTop(int marginTop) {

    this.marginTop = marginTop;
    invalidate();
}

public int getTimelineRadius() {
    return timelineRadius;
}

public void setTimelineRadius(int timelineRadius) {

    this.timelineRadius = timelineRadius;
    invalidate();
}

public int getTimelineRadiusDistance() {
    return timelineRadiusDistance;
}

public void setTimelineRadiusDistance(int timelineRadiusDistance) {

    this.timelineRadiusDistance = timelineRadiusDistance;
    invalidate();
}

public int getTimelineWidth() {
    return timelineWidth;
}

public void setTimelineWidth(int timelineWidth) {
    this.timelineWidth = timelineWidth;
}

public float getTimeLineViewHeight() {
    this.timeLineViewHeight = getMarginTop() + getTimelineCount()
            * (2 * getTimelineRadius() + getTimelineRadiusDistance());
    return timeLineViewHeight;
}

public void setTimeLineViewHeight(float timeLineViewHeight) {
    this.timeLineViewHeight = timeLineViewHeight;
    invalidate();

}

public int getViewWidth() {
    return viewWidth;
}

public void setViewWidth(int viewWidth) {
    this.viewWidth = viewWidth;
    invalidate();
}

/**
 * 转换dip为px
 */
public static int convertDIP2PX(Context context, int dip) {
    float scale = context.getResources().getDisplayMetrics().density;
    return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));
}

}`

里面写了一些详细的方法等很好用的,其中的bitmapHead是我们项目需求需要的一个头结点,这些是我在原来的基础上自己添加的,通过 
private void drawBitmap(Canvas canvas, Rect src, Rect dst, Bitmap bitmap) { 
dst = (dst == null ? new Rect(0, 0, bitmap.getWidth(), 
bitmap.getHeight()) : dst); 
Paint paint = new Paint(); 
// canvas.drawBitmap(bitmap, src, dst, paint); 
canvas.drawBitmap(bitmap, viewWidth - (bitmap.getWidth() / 2), 
timelineHeadRadius + marginTop - (bitmap.getHeight() / 2) - 10, 
paint); 
}
 
画自己的头结点,也就是第一个点。

实现我们的需求需要左边布局是自定义的View,右边用一个listview。

http://download.csdn.net/detail/u014007519/9454830这是我的demo地址可以下载下看一看,如果有什么问题可以联系

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React Native 是一款跨平台移动应用开发框架,可以使用 JavaScript 和 React 编写原生移动应用。如果你想要实现天猫物流跟踪时间轴的功能,可以考虑使用 React Native 开发。 下面是一个简单的实现流程: 1. 安装 React Native 开发环境,可以参考官方文档进行安装。 2. 创建一个新的 React Native 项目,使用 `react-native init` 命令可以快速创建一个新项目。 3. 在项目中安装 `react-native-timeline-flatlist` 组件,这个组件可以帮助我们实现时间轴的效果。 ``` npm install react-native-timeline-flatlist --save ``` 4. 在项目中创建一个新的组件,例如 `TimeLine` 组件。 5. 在 `TimeLine` 组件中引入 `react-native-timeline-flatlist` 组件,并使用数据来渲染时间轴。 ```javascript import Timeline from 'react-native-timeline-flatlist'; const data = [ { time: '09:00', title: '快递已揽收', description: '您的快递已经被揽收' }, { time: '12:00', title: '到达深圳', description: '您的快递已经到达深圳' }, { time: '15:00', title: '派送中', description: '您的快递正在派送中' }, { time: '18:00', title: '已签收', description: '您的快递已经被签收' }, ]; const TimeLine = () => { return ( <Timeline data={data} circleSize={20} circleColor="#007aff" lineColor="#007aff" timeContainerStyle={{ minWidth: 52, marginTop: -5 }} timeStyle={{ textAlign: 'center', backgroundColor: '#ff9797', color: 'white', padding: 5, borderRadius: 13 }} descriptionStyle={{ color: 'gray' }} options={{ style: { paddingTop: 5 }, }} /> ); }; export default TimeLine; ``` 6. 在主界面中使用 `TimeLine` 组件,并传递数据来展示时间轴。 ```javascript import React from 'react'; import { View, StyleSheet } from 'react-native'; import TimeLine from './TimeLine'; const App = () => { return ( <View style={styles.container}> <TimeLine /> </View> ); }; const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', }, }); export default App; ``` 通过以上步骤,我们就可以实现一个简单的天猫物流跟踪时间轴功能。当然,如果你想要更加复杂的效果,可以根据自己的需求对组件进行自定义。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值