如何创建一个自定义的拖影?
我要达到什么样的:
我想创建一个拖放在Android的拖放功能。我想使用一个特定的布局,一拖影(从拖动对象本身不同)。
I want to create a drag and drop functionality in Android. I'd like to use a specific layout (different from the dragged object itself) as a drag shadow.
什么导致我收到代替:
无论是我的方法按预期工作 - 我最终没有明显的拖影都(虽然目标确实接收到滴)
Neither of my approaches works as expected - I end up with no visible drag shadow at all (although the target does receive the drop).
我的尝试:
我试过
- 充气
drag_item
布局中的活动,然后将它作为参数传递给阴影生成器的构造
- inflating the
drag_item
layout in the activity, then passing it as an argument to the shadow builder's constructor
和
- 膨胀的影子建筑工地
onDrawShadow
方法drag_item
布局,然后在画布
- inflating the
drag_item
layout in the shadow builder'sonDrawShadow
method, then drawing it on thecanvas
布局:
我的活动布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.app.DragDropTestActivity"
tools:ignore="MergeRootFrame">
<TextView
android:id="@+id/tvReceiver"
android:text="Drop here"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btnDragged"
android:layout_height="wrap_content"
android:text="Drag me"
android:layout_width="match_parent"/>
</LinearLayout>
我要为一拖影使用的布局:
The layout I want to use as a drag shadow:
dragged_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Dragged Item"/>
</LinearLayout>
来源$ C $ C:
这里的code有两种方法(重presented由 1
, BuilderOne
和 2 , BuilderTwo
,分别):
Here's the code with both approaches (represented by 1
, BuilderOne
and 2
, BuilderTwo
, respectively):
package com.example.app;
import android.graphics.Canvas;
import android.graphics.Point;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
public class DragDropTestActivity extends ActionBarActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drag_drop_test);
Button dragged = (Button) findViewById(R.id.btnDragged);
dragged.setOnTouchListener(
new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (event.getAction() != MotionEvent.ACTION_DOWN) {
return false;
}
LayoutInflater inflater = getLayoutInflater();
int approach = 1;
// both approaches fail
switch (approach) {
case 1: {
View draggedItem = inflater.inflate(R.layout.dragged_item, null);
BuilderOne builder = new BuilderOne(draggedItem);
v.startDrag(null, builder, null, 0);
break;
}
case 2: {
BuilderTwo builder = new BuilderTwo(inflater, v);
v.startDrag(null, builder, null, 0);
break;
}
}
return true;
}
});
}
我的 BuilderOne
类:
public static class BuilderOne extends View.DragShadowBuilder
{
public BuilderOne(View view)
{
super(view);
}
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
{
super.onProvideShadowMetrics(
shadowSize,
shadowTouchPoint);
}
}
和 BuilderTwo
类:
public static class BuilderTwo extends View.DragShadowBuilder
{
final LayoutInflater inflater;
public BuilderTwo(LayoutInflater inflater, View view)
{
super(view);
this.inflater = inflater;
}
@Override
public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint)
{
super.onProvideShadowMetrics(
shadowSize,
shadowTouchPoint);
}
@Override
public void onDrawShadow(Canvas canvas)
{
final View draggedItem = inflater.inflate(R.layout.dragged_item, null);
if (draggedItem != null) {
draggedItem.draw(canvas);
}
}
}
}
问:
我该怎么办错了?
更新:
赏金补充说。
Kurty是正确的,你不应该需要继承 DragShadowBuilder
在这种情况下。我的想法是,你传递给视图中的 DragShadowBuilder
实际上并不存在的布局,因此它不会呈现。
Kurty is correct in that you shouldn't need to subclass DragShadowBuilder
in this case. My thought is that the view you're passing to the DragShadowBuilder
doesn't actually exist in the layout, and therefore it doesn't render.
而不是传递空
作为第二个参数 inflater.inflate
,尝试实际添加的膨胀查看
的层次结构的某个地方,然后将它传递到正规 DragShadowBuilder
:
Rather than passing null
as the second argument to inflater.inflate
, try actually adding the inflated View
to the hierarchy somewhere, and then passing it to a regular DragShadowBuilder
:
View dragView = findViewById(R.id.dragged_item);
mDragShadowBuilder = new DragShadowBuilder(dragView);
v.startDrag(null, mDragShadowBuilder, null, 0);
修改
我知道,具有 dragged_item
视图渲染所有的时间是不是你想要的,但如果它的工作原理那么至少我们知道问题出在哪里并能寻找一个解决方案,那不是!
I'm aware that having the dragged_item
view being rendered all the time isn't what you want, but if it works then at least we know where the problem is and can look for a solution to that instead!