最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2016年11月02日 11:24:16   作者:z240336124  
這篇文章主要為大家詳細(xì)介紹了Android時(shí)光軸實(shí)現(xiàn)淘寶物流信息瀏覽效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

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

1. 效果

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

2.1效果實(shí)現(xiàn):

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

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

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

2.2分步實(shí)現(xiàn): 

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

public class TimerLineMarker extends View {
 // 3個(gè)部分的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)的一個(gè)方法做決策最終決定寬高
  int withSize = resolveSizeAndState(with, widthMeasureSpec, 0);
  int heightSize = resolveSizeAndState(height, heightMeasureSpec, 0);
  // 設(shè)置寬高
  setMeasuredDimension(withSize, heightSize);
 }
}

2.在Item布居中我們給需要對齊那個(gè)View設(shè)置一個(gè)id為need_align_view,我們在onSizeChanged中去找到并計(jì)算對齊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顯示的時(shí)候回調(diào)
  // 定位到當(dāng)前幾個(gè)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的高度后,我們計(jì)算上面Line,中間Marker以及下面Line需要繪制的矩形區(qū)域,調(diào)用invalidate()然后在onDraw方法中分別繪制這三個(gè)部分;

 /**
  * 初始化Draw able
  */
 private void initDrawable() {
  initMarkerBounds();
  initLineBounds();
  postInvalidate();
 }

 /**
  * 初始化時(shí)光線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.很顯然我們需要顯示的方式是有些不同的,比如第一個(gè)沒有上面的線其中心標(biāo)記顏色也不一樣,最后一個(gè)沒有下面的線,所以我們需要提供兩個(gè)方法: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();
 }

 /**
  * 時(shí)光軸顯示風(fēng)格
  */
 public enum MarkerStyle {
  // 開始第一個(gè)
  START_STYLE,
  // 中間位置
  CENTER_STYLE,
  // 最后一個(gè)
  END_STYLE
 }

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

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

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

相關(guān)文章

最新評論

尤溪县| 新竹市| 甘肃省| 韶山市| 集贤县| 长岭县| 沅陵县| 胶南市| 资中县| 阳高县| 教育| 盐津县| 黔西县| 沈阳市| 江安县| 志丹县| 朔州市| 广饶县| 隆昌县| 景德镇市| 册亨县| 新竹县| 宜都市| 安徽省| 湖州市| 清水河县| 铜梁县| 迭部县| 电白县| 中卫市| 峡江县| 双桥区| 永济市| 金坛市| 儋州市| 太白县| 兴国县| 澄江县| 会理县| 遂溪县| 紫金县|