我想实现如材料设计中所示的滑动手势功能: https ://material.io/components/lists/#behavior (向下滚动一个屏幕到手势部分)。
不幸的是,我是 Angular 的新手,理论上我可以并且可以手动做这样的事情,但我觉得这将是拐杖上的拐杖 + 非常费力。此外,我怀疑人们很少使用它,以至于没有现成的库。我不否认我以某种方式搜索错误的可能性......
在互联网上,我在 git 上挖出了这个问题,他们要求添加功能: https ://github.com/angular/components/issues/4016
进一步的搜索把我带到了这里:
https://demo.mobiscroll.com/angular/listview/swipe-actions#theme=ios 正是我想要的(甚至是不必要的),但据我了解,这是一种显示所有内容的付费服务他们在一段时间后控制铭文DEMO。当然,我什么都懂,但是真的有这样的开源库吗?是的,也依赖于一些第三方服务,不要风水......
这是另一个开源库,在视觉上非常接近我正在寻找的内容,但是它通过滑动从 DOM 中删除了一个元素(这是合乎逻辑的,因为它被称为滑动删除),我需要挂起事件在向两侧滑动时,不从列表中删除元素。
请帮忙,有没有人做过类似的事情?
我看到了以下的实现(如果没有找到库):
- 我们创建一个代表列表项的组件。
- 我们将 DragDropModule 连接到它并配置元素只能沿 X 轴移动。
- 在 TS 中,我们订阅元素移动事件,当向一个方向或另一个方向移动一定百分比时,我们显示动作图标,当移动完成时,我们将元素返回到它的位置并调用一个或另一个回调函数在初始化期间传递给组件。
关于视图组件有几个想法:
- 也许我可以使用自定义占位符(此功能由 DragDropModule 提供)。如果它足够灵活,那就太好了。
- 取几个嵌套的 DIV 块。Last Child 将是一个移动元素,我会将动作图标附加到将由滑动和后台任务执行的父母。
剩下的就是制作一个漂亮的元素返回动画。接下来,通过 *ngFor 我们输入一个元素列表。鉴于我的经验不佳,我征求您的意见。一切都正确吗,告诉我如何正确地做。或者告诉我一个涵盖所需功能的库。
编辑:
由于我没有找到解决方案,我决定编写自己的实现。该决定尚未最终决定。我还没有检查是否可以通过输入将链接传递给方法(委托),但如果不能,那么我将进行相应的服务。我仍然不知道如何添加动画,以便在滑动后元素顺利返回到它的位置(请帮助解决这个问题)。在项目中我使用材料库。
TS:
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'table',
templateUrl: './table.component.html',
styleUrls: ['./table.component.scss']
})
export class TableComponent implements OnInit {
basePosition = {x:0,y:0};
@Input() tableId: string;
@Input() leftSwipeMethod: any; //test
@Input() rightSwipeMethod: any; //test
offsetPercent: number = 0;
private elementWidth = 0;
constructor() { }
ngOnInit() {
}
swipeStarted($event){
console.log("Started:" ,$event)
}
swipeMoved($event){
this.offsetPercent = Math.abs($event.distance.x / $event.source.element.nativeElement.offsetWidth * 2);
console.log(this.offsetPercent)
}
swipeEnded($event){
console.log("Ended:" ,$event);
this.offsetPercent = 0;
this.basePosition = {x:0,y:0};
}
}
风格:
.table-container, .table-drag-box {
height: 50px;
}
.table-drag-box{
width: 99vw;
background-color: white;
}
.table-container{
width: 100vw;
background-color: red;
}
.left-icon, .right-icon{
position: absolute;
height: inherit;
display: flex;
align-items: center;
opacity: 0;
}
.right-icon{
right: 0;
}
.fill-remaining-space{
flex: 1 1 auto;
}
HTML
<div class="table-container">
<span class="left-icon" [ngStyle]="{'opacity': offsetPercent}">
<mat-icon>credit_card</mat-icon>
<span>Send to payment</span>
</span>
<span class="fill-remaining-space"></span>
<span class="right-icon" [ngStyle]="{'opacity': offsetPercent}">
<mat-icon>close</mat-icon>
<span>Close all sessons</span>
</span>
<div class="table-drag-box" cdkDragLockAxis="x" cdkDrag [cdkDragFreeDragPosition]="basePosition"
(cdkDragStarted)="swipeStarted($event)" (cdkDragMoved)="swipeMoved($event)" (cdkDragReleased)="swipeEnded($event)">
<span> {{tableId}}</span>
</div>
</div>
用法:
<div *ngFor="let device of myDevicesObservable | async">
<table [tableId]="device.id"></table>
</div>
结果一切都比我想象的要容易得多。在编写自己的实现的过程中,我深入研究了 Material Drag&Drop库,并意识到我可以轻松使用它的功能。为了实现,我们需要一个 DropList,它的每个元素只允许沿 x 轴移动(cdkDragLockAxis="x")。我们还设置了一个自定义占位符,用于放置我们的图标。完全按照我的意愿工作!我还没有解决布局的所有问题,但是任何需要它的人都可以轻松地为自己纠正所有的小问题。我希望这可以帮助别人。我只需要挂断滑动和点击操作(参见代码中的注释)。我不会描述如何安装 Material,但我会直接展示实现(我为命名变量道歉——它们与我的上下文相关):
HTML:
CSS:
TS: