花式實現時間軸,樣式由你來定!

前言

由於公司業務常常會涉及到流程,因此使用相似時間軸的控件是不可避免。而且公司一直是使用的平板,單列時間軸已不足以勝任,故一直使用雙列的時間軸TimeLine,這是一個藉助2列的瀑布流佈局的RecyclerView完成的時間軸,已知足我司平常的需求,不過,使用瀑布流帶來的煩惱是:java

  • 位置很差控制:時間軸的每一個點的距離不可以均勻分佈(不過這也是瀑布流的優勢,充分利用空間)
  • 選擇單一:若是你的項目既有單列時間軸,又想集成雙列時間軸,這種狀況下就須要集成兩個第三方庫
  • 樣式單一:多數時間軸庫的樣式選擇過於單一,不可以本身定製

爲了解決以上的痛點,我提供了一種仍基於RecyclerView的新解決方案,該方案已被我集成在Orient-Ui中,如下是我基於此方案自定義實現的幾個例子:git

兩列時間軸 單列時間軸-左側標題 單列時間軸-頂部標題
WeekPlanDTL
NoteInfoSTL
StepSTL
DateInfoDTL
DateInfoSTL
SocialMediaSTL

1、介紹

爲何說Orient-Ui中的TimeLine靈活呢?由於該方案具備以下特色:github

  • 主體樣式包括單列時間軸雙列時間軸:單列時間軸使用的RecyclerView中的LinearLayoutManager(線性佈局),雙列時間軸則使用的Orient-Ui中的DoubleSideLayoutManager(兩側佈局)
  • 內容樣式可控性強:能夠輕鬆控制時間軸的點繪製方式、時間軸中的標題位置和內容、以及時間軸中的時間線等
  • 樣式高度的自定義:須要本身在給定的區域內繪製時間標題時間點,這也是該方案靈活的緣由

上述的特色的描述可能不是特別清晰,咱們藉助兩張圖加以說明:canvas

圖片 圖片
雙列時間軸
單列時間軸

左右兩邊分別表明着雙列時間軸單列時間軸,其中dot areatitle area是須要實現繪製的區域,其餘的例如標題放在RecyclerView子視圖的上側仍是仍是左側、標題的顏色、時間點採用的資源文件繪製仍是自繪製、時間線的風格及佔用大小等須要建立的時候進行設置。bash

2、使用

我會以上述圖片爲例,分別介紹單例時間軸雙列時間軸。不過在此以前,你須要在build.gradle添加依賴:ide

implementation 'com.orient:Orient-Ui:1.0.0'
複製代碼

1. 單列時間軸

第一步 繼承SingleTimeLineDecoration函數

咱們須要實現抽象方法SingleTimeLineDecoration#onDrawTitleItem,以及針對當前時間點的風格選擇複寫合適的方法,若是時間點採用的是FLAG_DOT_DRAW(繪製風格),須要複寫SingleTimeLineDecoration#onDrawDotItem方法,若是時間點採用的是FLAG_DOT_RES(繪製資源文件),則須要複寫SingleTimeLineDecoration#onDrawDotResItem方法:佈局

public class StepSTL extends SingleTimeLineDecoration {

    private Paint mRectPaint;

    public StepSTL(SingleTimeLineDecoration.Config config) {
        super(config);

        mRectPaint = new Paint();
        mRectPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID));
        mDotPaint.setMaskFilter(new BlurMaskFilter(6, BlurMaskFilter.Blur.SOLID));
    }

    @Override
    protected void onDrawTitleItem(Canvas canvas, int left, int top, int right, int bottom, int pos) {
        ITimeItem item = timeItems.get(pos);

        int rectWidth = UIUtils.dip2px(120);
        int height = bottom - top;
        int paddingLeft = UIUtils.dip2px(10);
        mRectPaint.setColor(item.getColor());
        canvas.drawRoundRect(left+paddingLeft,top,left+rectWidth,bottom,UIUtils.dip2px(6),UIUtils.dip2px(6),mRectPaint);


        String title = item.getTitle();
        if(TextUtils.isEmpty(title))
            return;
        Rect mRect = new Rect();

        mTextPaint.getTextBounds(title,0,title.length(),mRect);
        int x = left + (rectWidth - mRect.width())/2;
        //int x = left + UIUtils.dip2px(20);
        int y = bottom - (height - mRect.height())/2;
        canvas.drawText(title,x,y,mTextPaint);
    }

    @Override
    protected void onDrawDotItem(Canvas canvas, int cx, int cy, int radius, int pos) {
        ITimeItem item = timeItems.get(pos);
        mDotPaint.setColor(item.getColor());
        canvas.drawCircle(cx,cy,UIUtils.dip2px(6),mDotPaint);
    }
}
複製代碼

第二步 建立數據post

建立數據類型的時候須要實現ITimeItem接口:gradle

public class TimeItem implements ITimeItem {
	private String name;
	private String title;
	private String detail;
	private int color;
	private int res;
	// 構造方法省略
	// ... 省略get 和 set 方法
  	// 獲得當前的標題
	@Override
	public String getTitle() {
		return title;
	}
  	// 時間點的顏色
	@Override
	public int getColor() {
		return color;
	}
  	// 時間點的資源文件
  	// 若是採用的是繪製資源文件
	@Override
	public int getResource() {
		return res;
	}
	// ... 
}
複製代碼

第三步 初始化RecyclerView

構建RecyclerView對象,並設置佈局方式爲LinearLayoutManager以及初始化適配器,這是使用RecyclerView的必備知識,相信你早就爛熟於心了。

第四步 建立時間軸

// 初始化數據 
// 僅須要知道該行代碼做用便可
List<TimeItem> timeItems = TimeItem.initStepInfo();
// 適配器更新數據 
// 適配器已經被我封裝過
mAdapter.addAllData(timeItems);
// 構建時間軸
TimeLine decoration = new SingleTimeLineDecoration.Builder(getContext(), timeItems) // 添加數據
				// 標題顏色 和 標題文本的大小爲20sp
                .setTitle(Color.parseColor("#ffffff"), 20)	
				// 標題位置設置爲子視圖上邊,所佔高度爲40dp
                .setTitleStyle(SingleTimeLineDecoration.FLAG_TITLE_TYPE_TOP, 40) 
				// 時間線風格 繪製時間線區域的寬度(非時間線寬度)爲50dp
                .setLine(SingleTimeLineDecoration.FLAG_LINE_DIVIDE, 50, Color.parseColor("#8d9ca9")) 
				// 時間點的樣式 此處爲自繪製
                .setDot(SingleTimeLineDecoration.FLAG_DOT_DRAW)
				// 相同的標題隱藏
                .setSameTitleHide()
				// 設置實現的時間軸
                .build(StepSTL.class);
mRecyclerView.addItemDecoration(decoration);
複製代碼

這步完成以後就能夠正常顯示了,效果就是上述的活動步驟的那張圖:

單例時間軸

第五步 更新、刪除、添加

若是須要對數據進行增刪查改,那麼在進行這些操做以後,你須要對TimeLine中的數據進行更新操做,它一樣支持增刪改

函數 解釋
addItems 增長數據
replace 替換數據
remove 清除數據

2. 雙列時間軸

雙列時間軸與單列時間軸的區別仍是很大的,我會一一說明。

第一步 繼承DoubleTimeLineDecoration

這裏你須要注意的是當前繪製標題是在兩列布局中的左列仍是右列,須要處理的方法基本同SingleTimeLineDecoration,不過處理的方法來自DoubleTimeLineDecoration

第二步 建立數據

SingleTimeLineDecoration

第三步 初始化RecyclerView

這裏再用線性佈局顯然是行不通的,須要改成我寫的DoubleSideLayoutManager(兩側佈局)

mRecyclerView.setLayoutManager(new DoubleSideLayoutManager(DoubleSideLayoutManager.START_LEFT));
複製代碼

其餘同SingleTimeLineDecoration

第四步 建立時間軸

設置方法同SingleTimeLineDecoration。不過須要注意的是兩列時間軸不支持

  • 將標題放置在子視圖上側
  • 相同標題隱藏
  • FLAG_LINE_DIVIDE風格的時間線

第五步 更新、刪除、添加

SingleTimeLineDecoration

以上就是單列時間軸和雙列時間軸的配置了。

3、更多信息

通過上面瞭解,我相信你已經認識到,TimeLine能作的不只僅是一個時間軸,與流程、步驟相關的它同樣能夠勝任。不過須要指出的是,TimeLine作的只是爲你提供時間軸的佈局邏輯,具體時間點和標題的繪製仍需你本身實現,更多的繪製方案以及配置信息還需查看項目地址: github.com/mCyp/Orient…

除此之外,該項目中還集成了一些其餘有趣的控件,歡迎使用。

若是你對DoubleSideLayoutManager(兩側佈局)感興趣,還能夠查看:

《抽絲剝繭RecyclerView - LayoutManager》

最後,感謝你的閱讀~

相關文章
相關標籤/搜索