如何启用滑动手势以移动到Angular Material中标签模块的下一个标签? (寻找适用于2个以上标签的解决方案)

时间:2017-05-03 04:39:31

标签: angular angular-material

我正在使用角度材质中的标签组件:https://material.angular.io/components/component/tabs

有没有办法让我可以在选项卡的内容区域上滑动以触发移动到下一个标签?

我当前的模板html:

<md-tab-group>
  <md-tab label="Tab 1">Content 1</md-tab>
  <md-tab label="Tab 2">Content 2</md-tab>
</md-tab-group>

我已经导入了hammerjs,并且文档似乎没有提及任何关于这一点,即使我可以发誓我之前已经看过这样的事情......

具体来说,我希望能够向左单击并向左拖动鼠标,让它向左滑动到左侧标签。然后单击并向右拖动鼠标,使其向右滑动右侧选项卡。

4 个答案:

答案 0 :(得分:5)

这是一种简单的方法:

  

work plunker:https://plnkr.co/edit/uJ3n8XedvCCdeUHXKpwX?p=preview

首先,将hammerjs添加到您的模块中:

import { HammerGestureConfig, HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';

providers

中提供
  providers: [{ 
                    provide: HAMMER_GESTURE_CONFIG, 
                    useClass: HammerGestureConfig 
                }]

示例模块:

@NgModule({

  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    FormsModule,
    ReactiveFormsModule,
    MaterialModule,
  ],

  declarations: [TabsOverviewExample],
  bootstrap: [TabsOverviewExample],
  providers: [{ 
                    provide: HAMMER_GESTURE_CONFIG, 
                    useClass: HammerGestureConfig 
                }]
})
export class PlunkerAppModule {}

然后像这样构建你的组件:

import {Component, AfterViewInit, ViewChild, ViewChildren} from '@angular/core';
import { MdTabGroup, MdTab } from '@angular/material';


@Component({
  selector: 'tabs-overview-example',
  template:`
  <md-tab-group [selectedIndex]="selected"  (swipeleft)="swipe($event.type)" (swiperight)="swipe($event.type)">
    <md-tab label="Tab 1"><div class="content">Content 1</div></md-tab>
    <md-tab label="Tab 2"><div class="content">Content 2</div></md-tab>
    <md-tab label="Tab 3"><div class="content">Content 3</div></md-tab>
    <md-tab label="Tab 4"><div class="content">Content 4</div></md-tab>
    <md-tab label="Tab 5"><div class="content">Content 5</div></md-tab>
  </md-tab-group>`,
  styles:['.content{ height: 500px; background-color: yellow;}']
})
export class TabsOverviewExample implements AfterViewInit{
  @ViewChild(MdTabGroup) group;
  @ViewChildren(MdTab) tabs;
  tab_num = 0;
  selected = 0;
  SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };

  number_tabs
  ngAfterViewInit(){
    this.tab_num = this.tabs.length
    console.log(this.group)
  }
  swipe(eType){
    console.log(eType);
    if(eType === this.SWIPE_ACTION.LEFT && this.selected > 0){
      console.log("movin left")
      this.selected--;
    }
    else if(eType === this.SWIPE_ACTION.RIGHT && this.selected < this.tab_num){
      console.log("movin right")
      this.selected++;
    }
    console.log(this.selected)
  }


}

答案 1 :(得分:2)

这对我有用

https://plnkr.co/edit/VC270mPwh2o8CbMt9u7k?p=preview

模板

<div class="md-content" flex md-scroll-y (swipeleft)="swipe(idx, $event.type)" (swiperight)="swipe(idx, $event.type)">
<md-tab-group md-stretch-tabs [(selectedIndex)]="selectedIndex" (selectedIndexChange)="selectChange()">
  <md-tab label="Tab 1" (swipeleft)="swipe(1, $event.type)" (swiperight)="swipe(1, $event.type)">
      Content 1
    </md-tab>
  <md-tab label="Tab 2" (swipeleft)="swipe(2, $event.type)" (swiperight)="swipe(2, $event.type)">Content 2</md-tab>
</md-tab-group>
</div>

组件

export class TabsOverviewExample {


  selectedIndex: number = 1;

  selectChange(): void{
    console.log("Selected INDEX: " + this.selectedIndex);
  }

  SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };

  // Action triggered when user swipes
  swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
  console.log("swipe");
    console.log("number",selectedIndex);
    console.log("action",action);
    // Out of range
    if (this.selectedIndex < 0 || this.selectedIndex > 1 ) return;

    // Swipe left, next tab
    if (action === this.SWIPE_ACTION.LEFT) {
      const isLast = this.selectedIndex === 1;
      this.selectedIndex = isLast ? 0 : this.selectedIndex + 1;
      console.log("Swipe right - INDEX: " + this.selectedIndex);
    }

    // Swipe right, previous tab
    if (action === this.SWIPE_ACTION.RIGHT) {
      const isFirst = this.selectedIndex === 0;
      this.selectedIndex = isFirst ? 1 : this.selectedIndex - 1;
      console.log("Swipe left - INDEX: " + this.selectedIndex);
    }
  }
}

答案 2 :(得分:0)

这是我使用this approach的@ ahmed-musallam答案的版本:

模板:

<mat-tab-group #tabGroup [selectedIndex]="selected" (touchstart)="swipe($event, 'start')" (touchend)="swipe($event, 'end')">
...
</mat-tab-group>

组件:

@ViewChild('tabGroup', { static: true }) tabGroup: MatTabGroup;
public selected: number;
private swipeCoord?: [number, number];
private swipeTime?: number;
swipe(e: TouchEvent, when: string): void {
    const coord: [number, number] = [e.changedTouches[0].clientX, e.changedTouches[0].clientY];
    const time = new Date().getTime();

    if (when === 'start') {
        this.swipeCoord = coord;
        this.swipeTime = time;
    } else if (when === 'end') {
        const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
        const duration = time - this.swipeTime;

        if (duration < 1000 //
            && Math.abs(direction[0]) > 30 // Long enough
            && Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough
            const swipe = direction[0] < 0 ? 'next' : 'previous';
            switch (swipe) {
                case 'previous':
                    if (this.selected > 0) { this.selected--; }
                    break;
                case 'next':
                    if (this.selected < this.tabGroup._tabs.length - 1) { this.selected++; }
                    break;
            }
        }
    }
}

您需要在RTL方向上切换“上一个”和“下一个”。

答案 3 :(得分:0)

通过此当前代码(https://stackoverflow.com/a/43752352/9026103)可以工作,但是仅具有2个选项卡,因为您需要设置tabsCount而不是文字1。该解决方案仅针对两个选项卡实现。

下面针对任何数量的标签页进行了改进的解决方案。

正在使用最新资料的工作沙箱-https://stackblitz.com/edit/angular-1nqeiw

此人的积分-https://stackoverflow.com/a/43752352/9026103

export class TabsOverviewExample {


  selectedIndex: number = 1;
  tabsCount = 3;

  selectChange(): void{
    console.log("Selected INDEX: " + this.selectedIndex);
  }

  SWIPE_ACTION = { LEFT: 'swipeleft', RIGHT: 'swiperight' };

  // Action triggered when user swipes
  swipe(selectedIndex: number, action = this.SWIPE_ACTION.RIGHT) {
  console.log("swipe");
    console.log("number",selectedIndex);
    console.log("action",action);
    // Out of range
    if (this.selectedIndex < 0/* starter point as 0 */ || this.selectedIndex > this.tabsCount/* here it is */ ) return;

    // Swipe left, next tab
    if (action === this.SWIPE_ACTION.LEFT) {
      const isLast = this.selectedIndex === this.tabsCount;
      this.selectedIndex = isLast ? 0 : this.selectedIndex + 1;
      console.log("Swipe right - INDEX: " + this.selectedIndex);
    }

    // Swipe right, previous tab
    if (action === this.SWIPE_ACTION.RIGHT) {
      const isFirst = this.selectedIndex === 0 /* starter point as 0 */;
      this.selectedIndex = isFirst ? 1 : this.selectedIndex - 1;
      console.log("Swipe left - INDEX: " + this.selectedIndex);
    }
  }
}