private static class MyDragShadowBuilder extends View.DragShadowBuilder {
1 |
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// The drag shadow image, defined as a drawable thing
private static Drawable shadow;
// Defines the constructor for myDragShadowBuilder
public MyDragShadowBuilder(View v) {
// Stores the View parameter passed to myDragShadowBuilder.
super(v);
// Creates a draggable image that will fill the Canvas provided by the system.
shadow = new ColorDrawable(Color.LTGRAY);
}
// Defines a callback that sends the drag shadow dimensions and touch point back to the
// system.
@Override
public void onProvideShadowMetrics (Point size, Point touch)
// Defines local variables
private int width, height;
// Sets the width of the shadow to half the width of the original View
width = getView().getWidth() / 2;
// Sets the height of the shadow to half the height of the original View
height = getView().getHeight() / 2;
// The drag shadow is a ColorDrawable. This sets its dimensions to be the same as the
// Canvas that the system will provide. As a result, the drag shadow will fill the
// Canvas.
shadow.setBounds(0, 0, width, height);
// Sets the size parameter's width and height values. These get back to the system
// through the size parameter.
size.set(width, height);
// Sets the touch point's position to be in the middle of the drag shadow
touch.set(width / 2, height / 2);
}
// Defines a callback that draws the drag shadow in a Canvas that the system constructs
// from the dimensions passed in onProvideShadowMetrics().
@Override
public void onDrawShadow(Canvas canvas) {
// Draws the ColorDrawable in the Canvas passed in from the system.
shadow.draw(canvas);
}
}
* 注意* :记住你不必去继承View.DragShadowBuilder。构造方法View.DragShadowBuilder(View))会创建一个默认的拖动阴影,这个拖动阴影与传递给它的View参数一样大,并且位于以接触点为中心的位置。
回应一个拖动的开始
在拖动过程中,系统将拖动事件分配给当前布局中的视图对象的拖动事件监听器。监听器应该调用getAction())这个方法获取操作类型。在一个拖动开始时,这个方法返回ACTION_DRAG_STARTED。
作为回应一个操作类型为 ACTION_DRAG_STARTED的事件,监听器应该做到以下几点:
1.调用getClipDescription())方法获取ClipDescription。使用在ClipDescription 中的MIME类型的方法查看监听器是否接收被拖动的数据。
如果拖放操作没有代表数据的移动,那么这个步骤就不是必须的。
2.如果监听器可以接收一个拖动,它必须返回true。这样会告诉系统继续发送拖动事件给监听器。如果监听器不接收一个拖动,就会返回false,系统就会停止发送拖动事件直到它发送ACTION_DRAG_ENDED。
注意对于ACTION_DRAG_STARTED事件,以下这些DragEvent的方法都是无效的:getClipData())、 getX())、 getY())和getResult())。
在拖动过程中处理事件
在拖动过程中,作为回应ACTION_DRAG_STARTED拖动事件,监听器返回true来继续接受拖动事件。监听器在拖动过程中接收到的拖动事件类型取决于拖放阴影的位置以及监听器视图的可见性。
在拖动过程中,监听器首先使用拖动事件来决定是否应该改变他们的视图的外观。
在拖动过程中,getAction())返回以下三个变量中的一个:
-
ACTION_DRAG_ENTERED:当接触点(屏幕上位于用户手指下的那个点)进入监听器的视图的边界框范围内时监听器会接收到这个事件。
-
ACTION_DRAG_LOCATION:一旦监听器接收到ACTION_DRAG_LOCATION事件,在它接收到ACTION_DRAG_EXITED事件之前,接触点每移动一次,它都会接收到一个新的ACTION_DRAG_LOCATION事件。方法getX())和getY())会返回接触点的X轴和Y轴的坐标。
-
ACTION_DRAG_EXITED:在拖动阴影不再位于监听器视图的边界框范围之内时,这个事件会被发送给以前接收到ACTION_DRAG_ENTERED事件的监听器。
监听器不必对这些操作类型中的任意一个作出反应。如果监听器返回一个值给系统,它会被忽略掉。下面是应对这些动作类型的一些准则:
-
在回应ACTION_DRAG_ENTERED或者ACTION_DRAG_LOCATION时,监听器可以通过改变视图的外观来表明它将要接收到一个拖动。
-
具有ACTION_DRAG_LOCATION操作类型的事件包含了对getX())和getY())方法有效的数据,相应的接触点的位置。监听器可能可以使用这些信息来改变在接触点的视图的部分的外观。监听器也可以用这些信息来决定用户想要释放拖动阴影的精确位置。
-
在回应ACTION_DRAG_EXITED时,监听器应该重置它在回应ACTION_DRAG_ENTERED或ACTION_DRAG_LOCATION中应用的任何外观的变化。这是在向用户表明视图不再是一个临近被释放的目标。
回应一个释放动作
当用户在应用程序的视图上释放拖动阴影时,并且该视图会事先报告是否可以接收被拖动的内容,系统将拖动事件分发给那个含有 ACTION_DROP操作类型的视图。监听器应做到以下几点:
1.调用getClipData())方法获取最初在startDrag())方法中应用的ClipData对象,并储存之。如果拖放操作没有代表数据的移动,这些都不是必须的。
2.监听器应返回true来表明释放动作已顺利完成,如果没有完成的话,则返回false。这个被返回的值成为ACTION_DRAG_ENDED事件中getResult())方法的返回值。
需要注意的是,如果系统没有发送出ACTION_DROP事件,那么ACTION_DRAG_ENDED事件中getResult())方法的返回值就为false。
对于ACTION_DROP事件来说,在释放动作的瞬间,getX())和getY())方法使用接收释放动作的视图上的坐标系统,返回拖动点的X轴和Y轴的坐标。
系统允许用户在监听器不接收拖动事件的视图上释放拖动阴影。系统允许用户在应用程序UI的空区域或者应用程序之外的区域释放拖动阴影。在以上例子中,系统虽然会发送ACTION_DRAG_ENDED事件,但是不会发送一个ACTION_DROP事件。
回应一个拖动的结束
用户释放了拖动阴影后,系统会立即给应用程序中所有的拖动事件监听器发送ACTION_DRAG_ENDED类型的拖动事件,表明拖动动作结束了。
每个监听器都应该做下列事情:
1.如果监听器在操作期间改变了View对象的外观,那么应该把View对象重置为默认的外观。这是对用户可见的操作结束的指示.
2.监听器能够可选的调用getResult())方法来查找更多的相关操作。如果在响应ACTION_DROP类型的事件中监听器返回了true,那么getResult())方法也会返回true。在其他的情况中,getResult())方法会返回false,包括系统没有发出ACTION_DROP事件的情况.
3.监听器应该给系统返回true。
回应拖动事件:一个例子
所有的拖动事件都会被拖动事件的回调方法或监听器所接收。以下代码片段是一个简单的在监听器中对拖动事件作出反应的示例。
// Creates a new drag event listener
mDragListen = new myDragEventListener();
View imageView = new ImageView(this);
// Sets the drag event listener for the View
imageView.setOnDragListener(mDragListen);
…
protected class myDragEventListener implements View.OnDragEventListener {
1 |
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// This is the method that the system calls when it dispatches a drag event to the
// listener.
public boolean onDrag(View v, DragEvent event) {
// Defines a variable to store the action type for the incoming event
final int action = event.getAction();
// Handles each of the expected events
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
// Determines if this View can accept the dragged data
if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
// As an example of what your application might do,
// applies a blue color tint to the View to indicate that it can accept
// data.
v.setColorFilter(Color.BLUE);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
// returns true to indicate that the View can accept the dragged data.
return(true);
} else {
// Returns false. During the current drag and drop operation, this View will
// not receive events again until ACTION_DRAG_ENDED is sent.
return(false);
}
break;
case DragEvent.ACTION_DRAG_ENTERED: {
// Applies a green tint to the View. Return true; the return value is ignored.
v.setColorFilter(Color.GREEN);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
return(true);
break;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return(true);
break;
case DragEvent.ACTION_DRAG_EXITED:
// Re-sets the color tint to blue. Returns true; the return value is ignored.
v.setColorFilter(Color.BLUE);
// Invalidate the view to force a redraw in the new tint
v.invalidate();
return(true);
break;
case DragEvent.ACTION_DROP:
// Gets the item containing the dragged data
ClipData.Item item = event.getClipData().getItemAt(0);
// Gets the text data from the item.
dragData = item.getText();
// Displays a message containing the dragged data.
Toast.makeText(this, "Dragged data is " + dragData, Toast.LENGTH_LONG);
// Turns off any color tints
v.clearColorFilter();
// Invalidates the view to force a redraw
v.invalidate();
// Returns true. DragEvent.getResult() will return true.
return(true);
break;
case DragEvent.ACTION_DRAG_ENDED:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
总结
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-BTLwj8YW-1712694373488)]
总结
最后对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-AwyFMEef-1712694373488)]
[外链图片转存中…(img-EtUWS6K5-1712694373488)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-1M4xc2wF-1712694373489)]