我已在我的应用中创建了一个拖放活动,可使用找到的代码here重新排序项目。
其中一个活动涉及重新排序图像,因此我在布局中添加了一个图像视图,并调整了代码以添加正确的图像和所有内容。一切都很好,除了当抓取物品时,从每个插槽中抓取的第一个项目始终是从该插槽中抓取任何其他项目时显示的内容。
例如,假设我有项目a,b,c和d,如果我抓住项目a并将其移动到最后,b现在位于第一个插槽中。如果我现在抓住项目b,拖动的浮动视图仍然显示。当它被丢弃时,一切看起来都很好,并且处于它应该处于的新顺序。现在在同一个例子中,如果我取第二个项目,现在是项目c,并将其移动到任何地方,同样的事情发生了拖动第一个项目始终显示a,第二个项目始终显示c。
我也可以把项目a,移动到第二个,然后是第三个,然后是第四个等等,然后无论我抓到哪个项目,项目a总是显示拖动项目时的项目。
我对导致这种情况的原因感到困惑,我认为这可能与这段代码有关,特别是与绘图缓存有关。
private void startDrag(int itemIndex, int y) {
stopDrag(itemIndex);
Log.i("startdrag","view " + itemIndex);
View item = getChildAt(itemIndex);
if (item == null) return;
item.setDrawingCacheEnabled(true);
if (mDragListener != null)
mDragListener.onStartDrag(item);
// Create a copy of the drawing cache so that it does not get recycled
// by the framework when the list tries to clean up memory
Bitmap bitmap = Bitmap.createBitmap(item.getDrawingCache());
WindowManager.LayoutParams mWindowParams = new WindowManager.LayoutParams();
mWindowParams.gravity = Gravity.TOP;
mWindowParams.x = 0;
mWindowParams.y = y - mDragPointOffset;
mWindowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mWindowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
mWindowParams.format = PixelFormat.TRANSLUCENT;
mWindowParams.windowAnimations = 0;
Context context = getContext();
ImageView v = new ImageView(context);
v.setImageBitmap(bitmap);
WindowManager mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
mWindowManager.addView(v, mWindowParams);
mDragView = v;
}
原始应用程序在拖动时偶尔会显示错误的项目,但我无法让它可靠地重复,这就是为什么我认为它与绘图缓存有关。我的版本有图像,它可能试图通过重用旧视图来节省内存。我真的不知道,如果还有更多需要展示的话。
提前致谢。
答案 0 :(得分:1)
而不是使用绘图缓存,而是尝试直接从视图中获取位图。这就是谷歌在DynamicListView中的表现方式,如下所示。我一直在使用它的轻微修改版本没有问题。您可以在此处找到更多信息:https://www.youtube.com/watch?v=_BZIvjMgH-Q
/** Draws a white border over the screenshot of the view passed in. */
private Bitmap getBitmapWithBorder(View v) {
Bitmap bitmap = getBitmapFromView(v);
Canvas can = new Canvas(bitmap);
Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(LINE_THICKNESS);
paint.setColor(getResources().getColor(R.color.transparent_white));
can.drawBitmap(bitmap, 0, 0, null);
can.drawRect(rect, paint);
return bitmap;
}
/** Returns a bitmap showing a screenshot of the view passed in. */
private Bitmap getBitmapFromView(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas (bitmap);
v.draw(canvas);
return bitmap;
}