如何使滑动手势可以移动到Angular材料的下一个选项卡模块?(寻找适用于2个以上选项卡的解决方案)



我正在使用角材料中的选项卡组件:https://material.angular.io/components/components/components/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,并且文档似乎没有提及任何内容

具体来说,我希望能够单击并将鼠标拖到左侧,以将其向左滑到左图。然后单击并将我的鼠标拖到右侧的右侧滑动。

这是一种简单的方法:

工作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)
  }

}

这对我有用

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);
    }
  }
}

这是我使用以下方法的 @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方向切换"上一个"one_answers"下一个"。

通过此当前代码(https://stackoverflow.com/a/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);
    }
  }
}

所提出的解决方案都不支持交互式滑动手势。如果需要的话;考虑使用诸如swiperjs的库。

最新更新