正如问题所述。这是我的dragshadowbuilder供参考。如您所知,拖动时创建的阴影是半透明的。反正有没有让它变得不透明? (完全可靠)
public class MyDragShadowBuilder extends View.DragShadowBuilder {
View view;
int width;
int height;
Bitmap bitmap;
public MyDragShadowBuilder(View v) {
super(v);
view = v;
ImageView b = (ImageView)view;
int x = Character.getNumericValue(b.getContentDescription().charAt(0));
int y = Character.getNumericValue(b.getContentDescription().charAt(1));
bitmap = InGameActivity.currentBoardState[x][y].getPicture();
width = bitmap.getWidth();
height = bitmap.getHeight();
}
@Override
public void onDrawShadow(Canvas canvas) {
Rect source = new Rect(0, 0, InGameActivity.chessSquareHeightWidth, InGameActivity.chessSquareHeightWidth);
canvas.drawBitmap(bitmap, null, source, null);
}
@Override
public void onProvideShadowMetrics(Point shadowSize, Point touchPoint) {
shadowSize.set(InGameActivity.chessSquareHeightWidth, InGameActivity.chessSquareHeightWidth);
touchPoint.set(InGameActivity.chessSquareHeightWidth/2, InGameActivity.chessSquareHeightWidth/2);
}
}
编辑:这是我当前的onTouch代码,我还将提供该应用程序的背景。
OnTouchListener myOnTouchListener = new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
System.out.println(event.toString());
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ImageView b = (ImageView)view;
int x = Character.getNumericValue(b.getContentDescription().charAt(0));
int y = Character.getNumericValue(b.getContentDescription().charAt(1));
if (!currentBoardState[x][y].isEmpty()) {
((ImageView)view).setImageBitmap(null);
DragShadowBuilder shadowBuilder = new MyDragShadowBuilder(view);
view.startDrag(null, shadowBuilder, view, 0);
}
moveChessPiece;
return true;
}
return false;
}
});
好的,这就是你需要知道的。我正在开发一个象棋应用程序。我有一个8x8 GridLayout ,我将其命名为currentBoardState
。所以目前我希望能够拖动这件作品,但是我希望拖动的部分不透明,这样用户就会觉得他/她实际上是 MOVING 这件作品而不是单击然后点击我之前拥有的目的地。
答案 0 :(得分:9)
正如@Ernir所说,没有API获取DragShadow。但我们知道拖动位置和拖动视图,因此我们可以自己绘制它。
我编写了一个简单且功能有限的演示版,您可以将其下载here。
它实现了一个名为DragContainer的自定义ViewGroup,使用它将原始根视图包装在布局xml中。
<info.dourok.android.demo.DragContainer xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- original root view -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- ... -->
</RelativeLayout>
</info.dourok.android.demo.DragContainer>
调用DragContainer #startDragChild开始拖动(演示有更详细的信息):
在活动中:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDragContainer = (DragContainer) findViewById(R.id.root);
View drag = mDragContainer.findViewById(R.id.drag);
View drop = mDragContainer.findViewById(R.id.drop);
drag.setTag(IMAGEVIEW_TAG);
drag.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item((CharSequence) v
.getTag());
ClipData dragData = new ClipData((CharSequence) v.getTag(),
new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN },
item);
return mDragContainer.startDragChild(v, dragData, // the data to
// be
// dragged
null, // no need to use local data
0 // flags (not currently used, set to 0)
);
}
});
}
您还可以扩展DragContainer以绘制自定义拖动阴影,这是您需求的示例。
public class MyDragContainer extends DragContainer {
public MyDragContainer(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyDragContainer(Context context) {
super(context, null);
}
public MyDragContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
int width;
int height;
Bitmap bitmap;
@Override
protected void onSetDragTarget(View v) {
ImageView b = (ImageView) v;
int x = Character.getNumericValue(b.getContentDescription().charAt(0));
int y = Character.getNumericValue(b.getContentDescription().charAt(1));
bitmap = InGameActivity.currentBoardState[x][y].getPicture();
width = bitmap.getWidth();
height = bitmap.getHeight();
}
@Override
protected void drawDragShadow(Canvas canvas) {
Rect source = new Rect(0, 0, InGameActivity.chessSquareHeightWidth, InGameActivity.chessSquareHeightWidth);
int w = InGameActivity.chessSquareHeightWidth;
int h = InGameActivity.chessSquareHeightWidth;
canvas.translate(getDragX() - w / 2, getDragY() - h / 2);
canvas.drawBitmap(bitmap, null, source, null);
}
}
我希望它会有所帮助。
答案 1 :(得分:3)
我认为实现这一目标的正确方法是:
/* Create the shadow from a view */
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
/* Access the view created and set the alpha of it to 1 (totally opaque)*/
shadowBuilder.getView().setAlpha(1);
/* Start dragging the object */
view.startDrag(data, shadowBuilder, view, 0);
EDIT 它似乎不适用于4.4及以上:(
答案 2 :(得分:3)
不知道是否有人知道它, 我们可以使用标志DRAG_FLAG_OPAQUE实现相同的功能, 因此,相应的startDrag方法将如下所示:
View.DragShadowBuilder dragShadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(clipData, dragShadowBuilder, view, DRAG_FLAG_OPAQUE);
答案 3 :(得分:2)
不,遗憾的是,据我所知,这是不可能的。
阴影Bitmap
绘制在您无法触及的表面上。唯一的解决方案是实现Drag&amp; amp;像它在API 11之前完成的那样下降。它实际上并不像你想象的那么难。
一些可以帮助您入门的链接:
Link 2 *已更新
答案 4 :(得分:0)
这不可能实现。 startDragAndDrop
就是这样创建要拖动的表面:
final SurfaceControl surfaceControl = new SurfaceControl.Builder(session)
.setName("drag surface")
.setParent(root.getSurfaceControl())
.setBufferSize(shadowSize.x, shadowSize.y)
.setFormat(PixelFormat.TRANSLUCENT)
.setCallsite("View.startDragAndDrop")
.build();
如您所见,格式设置为PixelFormat.TRANSLUCENT,没有选项可以更改