記物流節(jié)點(diǎn)的實(shí)現(xiàn)

每做完一個(gè)需求我們是不是該留下點(diǎn)什么碎赢。??

需求

這次主要是做訂單這塊局义,然后物流的一個(gè)頁(yè)面平時(shí)買(mǎi)東西也會(huì)經(jīng)常見(jiàn)到,這次居然做到了,看著似乎挺簡(jiǎn)單的就斤,做的時(shí)候也花了我有些時(shí)間充边。
物流查詢(xún).png

實(shí)現(xiàn)

  • 方案一:最開(kāi)始的時(shí)候想著ListView+item布局應(yīng)該就能實(shí)現(xiàn)庸推,結(jié)果做出來(lái)的效果有點(diǎn)不如人意,因?yàn)槭褂靡韵伦鳛閕tem布局的話(huà)浇冰,要注意贬媒,點(diǎn)大概在一行文字的中間位置點(diǎn)和線(xiàn)之間有間隙肘习,如果點(diǎn)距離上面的距離很大际乘,那么下一個(gè)item顯示的時(shí)候,同樣會(huì)和上一個(gè)點(diǎn)有很大的間隙漂佩;

    item.png

  • 方案二:參考github上的一個(gè)實(shí)現(xiàn):將item添加到LinearLayout里面脖含,在onDraw方法中獲取到第一個(gè)和最后一個(gè)item的位置,從第一個(gè)到最后一個(gè)畫(huà)一條直線(xiàn)仅仆,最后中間分別畫(huà)點(diǎn)器赞,這樣的話(huà)點(diǎn)和線(xiàn)之間沒(méi)有間距。
    我參考了該種實(shí)現(xiàn)方案墓拜,記錄了每個(gè)item的起始位置港柜,并且每個(gè)畫(huà)線(xiàn)的開(kāi)始和結(jié)束點(diǎn)的位置(距離點(diǎn)有一定的距離),依次畫(huà)點(diǎn)咳榜,然后畫(huà)線(xiàn)夏醉。
    效果實(shí)現(xiàn),問(wèn)題:onDraw方法每次都會(huì)調(diào)用兩次涌韩,而且上下滑動(dòng)的時(shí)候都會(huì)去一直調(diào)用onDraw方法畔柔,沒(méi)找到原因,所以還是先放棄該種方案臣樱。

參考github的鏈接地址:https://github.com/razerdp/UnderLineLinearLayout

參考實(shí)現(xiàn):

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.BitmapDrawable;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.widget.LinearLayout;

import java.util.ArrayList;
import java.util.List;

public class LogisticsLinearLayout extends LinearLayout {

    private Context context;

    private int lineDynamicDimen;

    private Paint linePaint;
    private Paint pointPaint;

    // 存儲(chǔ)畫(huà)現(xiàn)的點(diǎn)
    private List<Point> points = new ArrayList<>();
    private Bitmap mIcon;
    private int halfIconWidth;
    private int iconHeight;
    // 圓的半徑
    private int circleRadius;
    private int lineMarginLeft;
    // 線(xiàn)距離上下點(diǎn)之間的距離
    private int lineMarginUPDown;

    // 設(shè)置完成的節(jié)點(diǎn)
    private int finishCodeCount;

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

    public LogisticsLinearLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LogisticsLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        this.context = context;
        setWillNotDraw(false);
        init();
    }

    private void init() {
        setOrientation(VERTICAL);
        
        // 這里是工具類(lèi)靶擦,dp->px
        circleRadius = DisplayUtil.dip2px(context, 3);
        lineMarginLeft = DisplayUtil.dip2px(context, 20);
        lineMarginUPDown = DisplayUtil.dip2px(context, 3);
        lineDynamicDimen = DisplayUtil.dip2px(context, 8);

        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setDither(true);
        linePaint.setColor(context.getResources().getColor(R.color.gh_cm_line_bg));
        linePaint.setStrokeWidth(DisplayUtil.dip2px(context, 1));
        linePaint.setStyle(Paint.Style.FILL_AND_STROKE);

        pointPaint = new Paint();
        pointPaint.setAntiAlias(true);
        pointPaint.setDither(true);
        pointPaint.setColor(context.getResources().getColor(R.color.m_consult_custom_service_text_gray_deep));
        pointPaint.setStyle(Paint.Style.FILL);

        BitmapDrawable temp = (BitmapDrawable) context.getResources().getDrawable(R.drawable.m_consult_icon_strict_logistics_point);
        if (temp != null) mIcon = temp.getBitmap();

        halfIconWidth = mIcon.getWidth() >> 1;
        iconHeight = mIcon.getHeight();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int childCount = getChildCount();
      
        points.clear();
        drawAllView(canvas);
    }

    // 肯定只有最后一個(gè)是未完成的腮考,前面應(yīng)該都是已經(jīng)完成的節(jié)點(diǎn)
    private void drawAllView(Canvas canvas) {
        for (int i = 0; i < getChildCount(); i++) {
            // 0, 1, 2   finishCodeCount=2

            if (i < finishCodeCount) { // 0,1
                drawImageChildViewVertical(i, canvas);
            } else {
                drawCircleChildViewVertical(i, canvas);
            }
        }

        float[] pts = new float[points.size()*2];
        for (int j = 0; j < points.size()*2; j=j+2) {
            Point p = points.get(j/2);
            pts[j] = p.x;
            pts[j+1] = p.y;
        }
        canvas.drawLines(pts, linePaint);
    }

    /**
     * 畫(huà)圓點(diǎn)view
     * @param i
     * @param canvas
     */
    private void drawCircleChildViewVertical(int i, Canvas canvas) {
        if (getChildAt(i) != null) {

            //記錄值: getLeft() + lineMarginLeft
            int posX = getLeft() + lineMarginLeft;
            // y = top + getChildAt(0).getPaddingTop() + lineDynamicDimen(可以理解為距離頂部的動(dòng)態(tài)值);
            int posY = getChildAt(i).getTop() + getChildAt(i).getPaddingTop() + lineDynamicDimen;

            //畫(huà)一個(gè)圓
            canvas.drawCircle(posX, posY, circleRadius, pointPaint);

            if (i == 0) {
                points.add(new Point(posX, posY+circleRadius+lineMarginUPDown));
            } else if (i == getChildCount()-1) {
                points.add(new Point(posX, posY-circleRadius-lineMarginUPDown));
            } else {
                points.add(new Point(posX, posY-circleRadius-lineMarginUPDown));
                points.add(new Point(posX, posY + circleRadius + lineMarginUPDown));
            }
        }
    }

    /**
     * 畫(huà)圖片view
     * @param i
     * @param canvas
     */
    private void drawImageChildViewVertical(int i, Canvas canvas) {
        if (getChildAt(i) != null) {
//            int halfIconWidth = mIcon.getWidth() >> 1;
//            int iconHeight = mIcon.getHeight();

            //記錄值: getLeft() + lineMarginLeft
            int posX = (getLeft() + lineMarginLeft) - halfIconWidth;
            // y = top + getChildAt(0).getPaddingTop() + lineDynamicDimen(可以理解為距離頂部的動(dòng)態(tài)值);
            int posY = getChildAt(i).getTop() + getChildAt(i).getPaddingTop() + lineDynamicDimen;

            canvas.drawBitmap(mIcon, posX, posY, null);

            if (i == 0) {
                points.add(new Point(posX+halfIconWidth, posY + iconHeight + lineMarginUPDown));
            } else if (i == getChildCount() - 1) {
                // i進(jìn)入這個(gè)判斷,說(shuō)明節(jié)點(diǎn)全部都已經(jīng)完成
                points.add(new Point(posX+halfIconWidth, posY - lineMarginUPDown));
            } else {
                points.add(new Point(posX+halfIconWidth, posY - lineMarginUPDown));
                points.add(new Point(posX+halfIconWidth, posY + iconHeight + lineMarginUPDown));
            }
        }
    }

    public void setNodeFinish(int count) {
        finishCodeCount = count;
    }
}
  • 方案三:就是完全自定義嘍玄捕,但是我不想做的這么麻煩踩蔚,這種方案放棄。
思考最初

回到最初的開(kāi)始枚粘,覺(jué)著應(yīng)該可以做出這種效果馅闽,重新嘗試ListView+item布局,這次換種布局方式馍迄,做出來(lái)的效果還是過(guò)的去福也。??

布局文件:

<?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"
    android:background="@color/white"
    android:paddingLeft="12dp"
    android:paddingRight="12dp">

    <!-- 每個(gè)點(diǎn)距離頂部3dp,即可以看起來(lái)在右邊文字的中間攀圈,又可以和線(xiàn)之間有一定距離 -->
    <ImageView
        android:id="@+id/logistics_point_iv"
        android:layout_width="12dip"
        android:layout_height="12dip"
        android:layout_marginTop="3dip"
        android:scaleType="center"
        android:src="@drawable/icon_logistics_point" />

    <!-- 為了能讓線(xiàn)在點(diǎn)的中間下方位置暴凑,只能固定圖片點(diǎn)的大小量承,算好距離左邊的位置是圖片寬度的一半搬设;
         必須要和右邊文字的最底部對(duì)齊撕捍,不然線(xiàn)顯示不出來(lái) -->
    <View
        android:id="@+id/logistics_line"
        android:layout_width="1dp"
        android:layout_marginTop="3dip"
        android:layout_height="match_parent"
        android:layout_marginLeft="6dip"
        android:layout_alignBottom="@+id/logistics_info_ll"
        android:layout_below="@id/logistics_point_iv"
        android:background="#EBECF1" />

    <LinearLayout
        android:id="@+id/logistics_info_ll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@+id/logistics_point_iv"
        android:paddingLeft="10dp"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/logistics_content_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="需求提交成功需求提交成功需求提交成功需求提交成功需求提交成功需求提交成功需求提交"
            android:textSize="16sp"
            android:textColor="#28354c"/>

        <TextView
            android:id="@+id/m_consult_item_strict_order_logistics_time_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingTop="8dp"
            android:paddingBottom="40dip"
            android:text="2015-9-28"
            android:textSize="12sp"
            android:textColor="#c4c6cf"/>

    </LinearLayout>

</RelativeLayout>

效果圖:

效果圖.png

看著還行吧泣洞,點(diǎn)到右邊第一行文字的距離稍微有點(diǎn)偏差忧风,但還算過(guò)得去掺冠,實(shí)現(xiàn)起來(lái)也方便。??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末呕诉,一起剝皮案震驚了整個(gè)濱河市缘厢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌甩挫,老刑警劉巖贴硫,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件伊者,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡亦渗,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)多律,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人狼荞,你說(shuō)我怎么就攤上這事≌掣眩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵殷勘,是天一觀的道長(zhǎng)昔搂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)贤斜,這世上最難降的妖魔是什么逛裤? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮锁荔,結(jié)果婚禮上蝙砌,老公的妹妹穿的比我還像新娘阳堕。我一直安慰自己,他們只是感情好恬总,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布肚邢。 她就那樣靜靜地躺著,像睡著了一般缀旁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勺鸦,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音懊渡,去河邊找鬼。 笑死剃执,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的摹恰。 我是一名探鬼主播怒见,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼闺阱!你這毒婦竟也來(lái)了舵变?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赊豌,失蹤者是張志新(化名)和其女友劉穎瘫拣,沒(méi)想到半個(gè)月后告喊,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拢切,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年秆吵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纳寂。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡毙芜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出腋粥,到底是詐尸還是另有隱情架曹,我是刑警寧澤闹瞧,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站万牺,受9級(jí)特大地震影響洽腺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜已脓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一度液、第九天 我趴在偏房一處隱蔽的房頂上張望厕宗。 院中可真熱鬧堕担,春花似錦、人聲如沸佑惠。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)贞奋。三九已至,卻和暖如春特愿,著一層夾襖步出監(jiān)牢的瞬間勾缭,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工毒嫡, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留采驻,地道東北人审胚。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓膳叨,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親菲嘴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,756評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,409評(píng)論 2 45
  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案烛卧? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 13,737評(píng)論 1 92
  • 每個(gè)人都是由于過(guò)往的不完美也可以說(shuō)是過(guò)往的業(yè)妓局,才來(lái)到這個(gè)世間修行的,西方的理論是我們都是帶著原罪來(lái)到世界上的好爬,東西...
    閭閻良善閱讀 323評(píng)論 0 0
  • 年少離家多飄零存炮,鄉(xiāng)愁此時(shí)又更濃。 慈母可知游子意穆桂,萬(wàn)千思念付歸鴻。
    林夕敬閱讀 354評(píng)論 5 1