角材料进度微调器

时间:2018-09-12 06:04:45

标签: angular-material android-progressbar

当模式确定时,有人知道如何在材料进度微调器中显示不完整的部分。现在我变得像这样
image1

但是我想要这样 image2

1 个答案:

答案 0 :(得分:3)

这可以做到,但主要是黑客。这个想法是使用一个具有与微调框匹配的边框的div并将其放置在微调框后面。

Progress spinner with background

Example on StackBlitz

<div class="spinner-container">
    <div class="spinner-background">{{spinner.value}}%</div>
    <mat-progress-spinner #spinner
        color="primary"
        mode="determinate"
        value="75">
    </mat-progress-spinner>
</div>

技巧是div样式,该样式的大小和位置必须与您的微调框完全匹配:

.spinner-container {
    position: relative;
}
.spinner-background {
    position: absolute;
    width: 80px;
    height: 80px;
    line-height: 80px;
    text-align: center;
    overflow: hidden;
    border-color: rgba(103, 58, 183, 0.12);
    border-radius: 50%;
    border-style: solid;
    border-width: 10px;
}

编辑:

为此我构建了一个简单的包装器组件,该组件可以自动处理大小和主题着色:

StackBlitz

spinner-container.ts:

import { coerceNumberProperty } from '@angular/cdk/coercion';
import { AfterViewInit, Component, ElementRef, Input, SimpleChanges } from '@angular/core';
import { CanColor, mixinColor, ThemePalette } from '@angular/material/core';

const BASE_SIZE = 100;
const BASE_STROKE_WIDTH = 10;
export class SpinnerContainerBase {
  constructor(public _elementRef: ElementRef) { }
}
export const _SpinnerContainerMixinBase = mixinColor(SpinnerContainerBase, 'primary');

/**
 * @title Progress spinner container for spinner circle background and value display
 */
@Component({
  selector: 'spinner-container',
  templateUrl: 'spinner-container.html',
  styleUrls: ['spinner-container.scss'],
  host: {
    'class': 'spinner-container',
    '[style.width.px]': 'diameter',
    '[style.height.px]': 'diameter',
    '[style.line-height.px]': 'diameter'
  }
})
export class SpinnerContainer extends _SpinnerContainerMixinBase implements AfterViewInit, CanColor {

  constructor(public _elementRef: ElementRef) {
    super(_elementRef);
  }

  @Input() color: ThemePalette = 'primary';

  @Input()
  get diameter(): number { return this._diameter; }
  set diameter(size: number) {
    this._diameter = coerceNumberProperty(size);
  }
  private _diameter: number = BASE_SIZE;

  @Input() displayWith: (number) => string | number;

  @Input()
  get strokeWidth() { return this._strokeWidth; }
  set strokeWidth(newValue: number) {
    if (newValue) {
      this._strokeWidth = Math.min(this.diameter / 2, coerceNumberProperty(newValue));
      if (this._spinnerBackgroundElement) {
        this._spinnerBackgroundElement.style.borderWidth = this.strokeWidth + 'px';
      }
    }
  }
  private _strokeWidth: number = BASE_STROKE_WIDTH;

  @Input()
  get value(): number { return this._value; }
  set value(newValue: number) {
    this._value = Math.max(0, Math.min(100, coerceNumberProperty(newValue)));
  }
  private _value: number = 0;

  private _spinnerBackgroundElement: HTMLElement;

  ngAfterViewInit() {
    this._spinnerBackgroundElement = this._elementRef.nativeElement.querySelector('.spinner-background');
    this._spinnerBackgroundElement.style.borderWidth = this.strokeWidth + 'px';
  }
}

spinner-container.html

<div class="spinner-value" *ngIf="displayWith">{{displayWith(value)}}</div>
<div class="spinner-background"></div>
<mat-progress-spinner 
    [color]="color" 
    [diameter]="diameter" 
    mode="determinate" 
    [strokeWidth]="strokeWidth" 
    [value]="value">
</mat-progress-spinner>

spinner-container.scss

:host {
    display: block;
    position: relative;

    .spinner-value, .spinner-background {
        position: absolute;
        width: inherit;
        height: inherit;
    }

    .spinner-value {
        text-align: center;
        overflow: hidden;
    }

    .spinner-background {
        opacity: .12;
        box-sizing: border-box;
        border-radius: 50%;
        border-style: solid;
    }
}

_spinner-container-theme.scss

@mixin spinner-container-theme($theme) {

    $primary: map-get($theme, primary);
    $accent: map-get($theme, accent);
    $warn: map-get($theme, warn);

    .spinner-background {
        .spinner-container.mat-primary & {
            color: mat-color($primary);
        }
        .spinner-container.mat-accent & {
            color: mat-color($accent);
        }
        .spinner-container.mat-warn & {
            color: mat-color($warn);
        }
    }
}