国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android時光軸實現(xiàn)淘寶物流信息瀏覽效果

2019-12-12 04:49:41
字體:
供稿:網(wǎng)友

本文實例為大家分享了Android時光軸的制作方法,供大家參考,具體內(nèi)容如下

1. 效果

2.分析和實現(xiàn)

2.1效果實現(xiàn):

  之前想了一下這種效果,因為只需要用到自己的項目中所以采用圖片直接布局的形式去實現(xiàn)效果,雖然效果實現(xiàn)了,但是后來發(fā)現(xiàn)了出了很多問題:第一Android的分辨率太多了直接設(shè)置xxxdp難免有部分機(jī)型出現(xiàn)不適配的情況,第二我們與右邊這部分需要對齊的問題這個就比較頭大。   

所以目前的實現(xiàn)效果方式是這樣子的:   

1.自定義TimerLineMarker,根據(jù)自定義屬性獲取點(diǎn)和線的背景資源或是顏色以及寬度等等,在onMeasure中計算布局的寬度和高度;
2.在Item布居中我們給需要對齊那個View設(shè)置一個id為need_align_view,我們在onSizeChanged中去找到并計算對齊View距頭部的高度;
3.當(dāng)我們得到對齊View的高度后,我們計算上面Line,中間Marker以及下面Line需要繪制的矩形區(qū)域,調(diào)用invalidate()然后在onDraw方法中分別繪制這三個部分;
4.很顯然我們需要顯示的方式是有些不同的,比如第一個沒有上面的線其中心標(biāo)記顏色也不一樣,最后一個沒有下面的線,所以我們需要提供兩個方法:setStyle()設(shè)置顯示風(fēng)格;setMarker(int resouceId)設(shè)置中間標(biāo)記的資源   

2.2分步實現(xiàn): 

1.自定義TimerLineMarker,根據(jù)自定義屬性獲取點(diǎn)和線的背景資源或是顏色以及寬度等等,在onMeasure中計算布局的寬度和高度

public class TimerLineMarker extends View { // 3個部分的drawable private Drawable mBeginLine, mEndLine, mMarker; // 顯示大小 private int mMarkerSize = 26, mLineSize = 4; // 距離頭部的微調(diào) private int mMarkerMarginTop = 0; public TimerLineMarker(Context context) {  this(context, null); } public TimerLineMarker(Context context, AttributeSet attrs) {  this(context, attrs, 0); } public TimerLineMarker(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  initAttribute(attrs); } /**  * 初始化自定義屬性  */ private void initAttribute(AttributeSet attrs) {  final TypedArray typedArray = getContext().obtainStyledAttributes(    attrs, R.styleable.TimerLineMarker);  // 獲取size  mMarkerSize = typedArray.getDimensionPixelSize(    R.styleable.TimerLineMarker_markerSize, mMarkerSize);  mLineSize = typedArray.getDimensionPixelSize(    R.styleable.TimerLineMarker_lineSize, mLineSize);  // 獲取drawable  mBeginLine = typedArray    .getDrawable(R.styleable.TimerLineMarker_beginLine);  mEndLine = typedArray.getDrawable(R.styleable.TimerLineMarker_endLine);  mMarker = typedArray.getDrawable(R.styleable.TimerLineMarker_marker);  mMarkerMarginTop = typedArray.getDimensionPixelSize(    R.styleable.TimerLineMarker_markerMarginTop, mMarkerMarginTop);  typedArray.recycle(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  // 測量本View的寬高里面子控件的寬度  int with = mMarkerSize + getPaddingLeft() + getPaddingRight();  int height = mMarkerSize + getPaddingTop() + getPaddingBottom();  // 通過系統(tǒng)的一個方法做決策最終決定寬高  int withSize = resolveSizeAndState(with, widthMeasureSpec, 0);  int heightSize = resolveSizeAndState(height, heightMeasureSpec, 0);  // 設(shè)置寬高  setMeasuredDimension(withSize, heightSize); }}

2.在Item布居中我們給需要對齊那個View設(shè)置一個id為need_align_view,我們在onSizeChanged中去找到并計算對齊View距頭部的高度;

 // 標(biāo)記距離頭部的位置 private int mMarkerTopDistance; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) {  super.onSizeChanged(w, h, oldw, oldh);  initAlignViewHeight();  // 當(dāng)View顯示的時候回調(diào)  // 定位到當(dāng)前幾個draw able的坐標(biāo),然后繪制  initDrawable(); } /**  * 初始化獲取需要對齊的View高度  */ private void initAlignViewHeight() {  // 獲取需要對齊的View  ViewGroup parent = (ViewGroup) this.getParent();  mNeedAlignView = findNeedAlignView(parent);  // 獲取需要對齊的View距離頂部的高度  if (mNeedAlignView != null) {   mMarkerTopDistance = 0;   // 與需要對齊View的中心點(diǎn)對齊   mMarkerTopDistance += calcViewTop(mNeedAlignView)     + mNeedAlignView.getMeasuredHeight() / 2;  } } /**  * 循環(huán)獲取距頂部的距離  */ private int calcViewTop(View view) {  final ViewGroup parentView = (ViewGroup) view.getParent();  final int childCount = parentView.getChildCount();  // 先加上paddingTop  int topDistance = parentView.getPaddingTop();  for (int i = 0; i < childCount; i++) {   final View childView = parentView.getChildAt(i);   final ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) childView     .getLayoutParams();   topDistance = addTopMargin(topDistance, params);   if (childView == view) {    return topDistance;   }   topDistance = addBottomMargin(topDistance, params);   topDistance += childView.getMeasuredHeight();  }  return topDistance; } /**  * 累加底部的margin高度  */ private int addBottomMargin(int topDistance, ViewGroup.LayoutParams params) {  if (params instanceof RelativeLayout.LayoutParams) {   RelativeLayout.LayoutParams param = (RelativeLayout.LayoutParams) params;   topDistance += param.bottomMargin;  }  if (params instanceof LinearLayout.LayoutParams) {   LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) params;   topDistance += param.bottomMargin;  }  if (params instanceof FrameLayout.LayoutParams) {   FrameLayout.LayoutParams param = (FrameLayout.LayoutParams) params;   topDistance += param.bottomMargin;  }  if (params instanceof TableLayout.LayoutParams) {   TableLayout.LayoutParams param = (TableLayout.LayoutParams) params;   topDistance += param.bottomMargin;  }  return topDistance; } /**  * 累加頭部margin高度  */ private int addTopMargin(int topDistance, ViewGroup.LayoutParams params) {  if (params instanceof RelativeLayout.LayoutParams) {   RelativeLayout.LayoutParams param = (RelativeLayout.LayoutParams) params;   topDistance += param.topMargin;  }  if (params instanceof LinearLayout.LayoutParams) {   LinearLayout.LayoutParams param = (LinearLayout.LayoutParams) params;   topDistance += param.topMargin;  }  if (params instanceof FrameLayout.LayoutParams) {   FrameLayout.LayoutParams param = (FrameLayout.LayoutParams) params;   topDistance += param.topMargin;  }  if (params instanceof TableLayout.LayoutParams) {   TableLayout.LayoutParams param = (TableLayout.LayoutParams) params;   topDistance += param.topMargin;  }  return topDistance; }

3.當(dāng)我們得到對齊View的高度后,我們計算上面Line,中間Marker以及下面Line需要繪制的矩形區(qū)域,調(diào)用invalidate()然后在onDraw方法中分別繪制這三個部分;

 /**  * 初始化Draw able  */ private void initDrawable() {  initMarkerBounds();  initLineBounds();  postInvalidate(); } /**  * 初始化時光線Bounds  */ private void initLineBounds() {  int height = getHeight();  Rect bounds = mMarker.getBounds();  int lineLeft = bounds.centerX() - (mLineSize >> 1);  if (mBeginLine != null)   mBeginLine.setBounds(lineLeft, 0, lineLeft + mLineSize, bounds.top);  if (mEndLine != null)   mEndLine.setBounds(lineLeft, bounds.bottom, lineLeft + mLineSize,     height); } /**  * 初始化標(biāo)記Bounds  */ private void initMarkerBounds() {  int pLeft = getPaddingLeft();  int pRight = getPaddingRight();  int pBottom = getPaddingBottom();  int pTop = getPaddingTop();  int width = getWidth();  int height = getHeight();  int cWidth = width - pLeft - pRight;  int cHeight = height - pTop - pBottom;  mMarkerSize = Math.min(mMarkerSize, Math.min(cWidth, cHeight));  mMarkerTopDistance = mMarkerTopDistance - mMarkerSize / 2;  if (mMarkerMarginTop < 0) {   mMarkerMarginTop = 0;  }  mMarker.setBounds(pLeft, mMarkerTopDistance + mMarkerMarginTop, pLeft    + mMarkerSize, mMarkerTopDistance + mMarkerMarginTop    + mMarkerSize); } @Override protected void onDraw(Canvas canvas) {  if (mMarker.getBounds().right <= 0) {   // 如果bounds被弄丟了   assignValue();  }  if (mMarkerStyle != MarkerStyle.START_STYLE) {   if (mBeginLine != null)    mBeginLine.draw(canvas);  }  mMarker.draw(canvas);  if (mMarkerStyle != MarkerStyle.END_STYLE) {   if (mEndLine != null)    mEndLine.draw(canvas);  } } /**  * 從新賦值  */ private void assignValue() {  initAlignViewHeight();  initMarkerBounds();  initLineBounds(); }

4.很顯然我們需要顯示的方式是有些不同的,比如第一個沒有上面的線其中心標(biāo)記顏色也不一樣,最后一個沒有下面的線,所以我們需要提供兩個方法:setStyle()設(shè)置顯示風(fēng)格;setMarker(int resouceId)設(shè)置中間標(biāo)記的資源。

 /**  * 設(shè)置顯示的分隔  */ public void setStyle(MarkerStyle markerStyle) {  this.mMarkerStyle = markerStyle;  invalidate(); } /**  * 設(shè)置標(biāo)記的Draw able  */ public void setMarker(Drawable marker) {  this.mMarker = marker;  postInvalidate(); } /**  * 設(shè)置標(biāo)記資源  *   * @param resouceId  *   資源id  */ public void setMarker(int resouceId) {  this.mMarker = getResources().getDrawable(resouceId);  postInvalidate(); } /**  * 時光軸顯示風(fēng)格  */ public enum MarkerStyle {  // 開始第一個  START_STYLE,  // 中間位置  CENTER_STYLE,  // 最后一個  END_STYLE }

以后希望自己有點(diǎn)空,就把自己做的一些東西寫下來. 一方面鍛煉一下自己的寫文檔的能力,另一方面分享代碼的同時也希望能與大家交流一下技術(shù),共同學(xué)習(xí),共同進(jìn)步。因為開發(fā)過程中遇到一些問題我總會先在網(wǎng)上找一些例子參考一下,類似的代碼,可能有些達(dá)不到效果或是用不上,沒辦法也只能自己造輪子。

源碼下載地址:http://xiazai.VeVB.COm/201611/yuanma/AndroidTimeLine(VeVB.COm).rar

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 承德县| 涿州市| 贡山| 高碑店市| 通辽市| 阿城市| 行唐县| 囊谦县| 平利县| 亳州市| 武强县| 黄梅县| 广饶县| 石柱| 柳林县| 建始县| 鹤峰县| 辽宁省| 英超| 凤翔县| 浠水县| 德钦县| 姜堰市| 连州市| 北票市| 雷波县| 开原市| 桦川县| 枣阳市| 年辖:市辖区| 舞钢市| 海宁市| 潜山县| 修水县| 盐边县| 德州市| 迭部县| 丽水市| 望谟县| 博湖县| 额济纳旗|