我想要实现的目标:
我想在Android中创建拖放功能.我想使用特定的布局(与拖动的对象本身不同)作为拖动阴影.
我得到了什么结果:
我的方法都没有按预期工作 – 我最终没有可见的拖动阴影(虽然目标确实接收到了掉落).
我尝试了什么:
我试过了
>在活动中展开drag_item布局,然后将其作为参数传递给阴影构建器的构造函数
和
>在阴影构建器的onDrawShadow方法中展开drag_item布局,然后在画布上绘制它
布局:
我的活动布局:
<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>
我想用作拖动阴影的布局:
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>
源代码:
这是两种方法的代码(分别用1,BuilderOne和2,BuilderTwo表示):
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,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,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的视图实际上并不存在于布局中,因此它不会渲染.
不是将null作为第二个参数传递给inflater.inflate,而是尝试将膨胀的View添加到某个层次结构中,然后将其传递给常规的DragShadowBuilder:
View dragView = findViewById(R.id.dragged_item); mDragShadowBuilder = new DragShadowBuilder(dragView); v.startDrag(null,mDragShadowBuilder,0);
编辑
我知道让dragged_item视图一直在渲染,这不是你想要的,但如果它有效,那么至少我们知道问题出在哪里,并且可以寻找解决方案!