DragEventListener 不适用于三星 S7 (6.0)
DragEventListener not working on Samsung S7 (6.0)
我正在寻找与此相关的方向。我有一个纸牌融合游戏 (Five Kings),已经运行了大约 6 个月;我的最新版本 0.9.22 自 3 月以来一直稳定。但是,最近我收到用户无法将丢弃物拖到丢弃物堆的报告,并且常见线程似乎 是带有Android 6.0 的Samsung S7。当您从手中拖出一张卡片时,您可以拖动的地方会变成透明的,而当您拖过它们时,它们会恢复正常(alpha = 1)。您可以拖动的其他地方似乎工作正常,但丢弃堆不会变暗或变亮,这让我觉得拖动事件侦听器不工作。
这是 DiscardPileDragEventListener
:
class DiscardPileDragEventListener implements View.OnDragListener {
// This is the method that the system calls when it dispatches a drag event to the
// listener.
@Override
public boolean onDrag(final View v, final DragEvent event) {
//that we are not ready to accept the drag if not at the right point of the play
CardView cv = (CardView)v;
// 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 (cv.isAcceptDrag() && event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
//fades out of the draw pile
cv.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
// returns true to indicate that the View can accept the dragged data.
return true;
} else {
//remind user what they should be doing if in the first few rounds
((FiveKings) cv.getContext()).setShowHint(null, FiveKings.HandleHint.SHOW_HINT, FiveKings.GameDifficulty.EASY);
// Returns false. During the current drag and drop operation, this View will
// not receive events again until ACTION_DRAG_ENDED is sent.
return false;
}
case DragEvent.ACTION_DRAG_ENTERED:
cv.clearAnimation();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return true;
case DragEvent.ACTION_DRAG_EXITED:
cv.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
return true;
case DragEvent.ACTION_DROP:
cv.clearAnimation();
// Gets the item containing the dragged data
ClipData.Item item = event.getClipData().getItemAt(0); //this is the View index to recover which card
// Gets the text data from the item.
String dragData = item.getText().toString();
//Handle exception here and return false (drop wasn't handled) if it wasn't found
int iView = -1;
try {
iView = Integer.parseInt(dragData);
}catch (NumberFormatException e) {
return false;
}
return ((FiveKings)cv.getContext()).discardedCard(iView);
case DragEvent.ACTION_DRAG_ENDED:
if (cv.isAcceptDrag()) cv.clearAnimation();
return true;
// An unknown action type was received.
default:
Log.e("DiscardPileDragEventListener", "Unknown action type received by OnDragListener.");
}
return false;
}
}
这是设置实际拖动卡片的代码片段;在这个 CardView 中是 ImageView 的子类:
for (Card card : meld) {
//highlight wildcards unless no dragging (Computer turn, or Human final turn)
CardView cv = new CardView(this, card, iView, allowDragging ? highlightWildCardRank : null);
cv.setTag(iView); //allows us to pass the index into the dragData without dealing with messy object passing
...
cv.bringToFront();
cv.setClickable(false); //TODO:B: Allow selection by clicking for multi-drag?
if (allowDragging) {//no dragging of computer cards or Human cards after final turn
cv.setOnDragListener(new CardViewDragEventListener()); //needed per-card to reset the dragged card to normal visibility (alpha)
cv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN) return false;
// Create a new ClipData using the tag as a label, the plain text MIME type, and
// the string containing the View index. This will create a new ClipDescription object within the
// ClipData, and set its MIME type entry to "text/plain"
ClipData dragData = ClipData.newPlainText("Discard", v.getTag().toString());
View.DragShadowBuilder cardDragShadow = new CardViewDragShadowBuilder(v);
v.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
// Starts the drag
v.startDrag(dragData, cardDragShadow, null, 0);
return true;
}//end onClick
});
}//end if allowDragging
...
并且在 onCreate 中,我设置了 Discard Pile onDragListener:
...
mDiscardPile.setOnDragListener(new DiscardPileDragEventListener());
...
一个问题是我在 Discard Pile 的父视图中也有一个 onDragListener,以便在您将卡片拖到 Discard Pile 时提供消息。这在我的测试中运行良好,但我只是想知道它是否有某种关联。
如有任何关于前进方向的建议,我们将不胜感激。
事实证明,三星为 S7 引入了一项名为 Game Tuner 的功能,并将其反向移植到 S6 和其他设备。它会自动更改市场上标记为 "Game" 的任何已安装应用程序的分辨率。这对于图形驱动的游戏非常有用,但完全搞砸了像我这样的纸牌游戏的拖放。请注意,即使您从未进入 Game Tuner 应用程序,也会发生这种情况。
因此,如果您在玩游戏或应用时遇到这种情况,请询问用户是否安装了 Game Tuner,并要求他们将分辨率设置为 100%(他们可以针对每个游戏进行设置)。
2017 年 3 月更新:
我现在有 99% 的解决方案。即使没有安装 Game Tuner,三星也可以扩展游戏(显然达到 75%)。因此,您必须安装 Game Tuner,然后将分辨率重置为 100% 才能使拖放正常工作。
我没有的那 1% 就是为什么他们会做出这样愚蠢的事情。
Samsung Display Scaling 选项:它可以缩小某些屏幕上的内容。
例如,当您在主屏幕上打开一个文件夹时,您会看到更多图标。
我相信三星最近(2016 年 7 月)发布了具有此功能的 OTA 更新。如果此功能在 Settings/Display 中可用,则表示已安装 OTA 更新,似乎可以解决拖放问题。
我正在寻找与此相关的方向。我有一个纸牌融合游戏 (Five Kings),已经运行了大约 6 个月;我的最新版本 0.9.22 自 3 月以来一直稳定。但是,最近我收到用户无法将丢弃物拖到丢弃物堆的报告,并且常见线程似乎 是带有Android 6.0 的Samsung S7。当您从手中拖出一张卡片时,您可以拖动的地方会变成透明的,而当您拖过它们时,它们会恢复正常(alpha = 1)。您可以拖动的其他地方似乎工作正常,但丢弃堆不会变暗或变亮,这让我觉得拖动事件侦听器不工作。
这是 DiscardPileDragEventListener
:
class DiscardPileDragEventListener implements View.OnDragListener {
// This is the method that the system calls when it dispatches a drag event to the
// listener.
@Override
public boolean onDrag(final View v, final DragEvent event) {
//that we are not ready to accept the drag if not at the right point of the play
CardView cv = (CardView)v;
// 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 (cv.isAcceptDrag() && event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
//fades out of the draw pile
cv.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
// returns true to indicate that the View can accept the dragged data.
return true;
} else {
//remind user what they should be doing if in the first few rounds
((FiveKings) cv.getContext()).setShowHint(null, FiveKings.HandleHint.SHOW_HINT, FiveKings.GameDifficulty.EASY);
// Returns false. During the current drag and drop operation, this View will
// not receive events again until ACTION_DRAG_ENDED is sent.
return false;
}
case DragEvent.ACTION_DRAG_ENTERED:
cv.clearAnimation();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
// Ignore the event
return true;
case DragEvent.ACTION_DRAG_EXITED:
cv.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
return true;
case DragEvent.ACTION_DROP:
cv.clearAnimation();
// Gets the item containing the dragged data
ClipData.Item item = event.getClipData().getItemAt(0); //this is the View index to recover which card
// Gets the text data from the item.
String dragData = item.getText().toString();
//Handle exception here and return false (drop wasn't handled) if it wasn't found
int iView = -1;
try {
iView = Integer.parseInt(dragData);
}catch (NumberFormatException e) {
return false;
}
return ((FiveKings)cv.getContext()).discardedCard(iView);
case DragEvent.ACTION_DRAG_ENDED:
if (cv.isAcceptDrag()) cv.clearAnimation();
return true;
// An unknown action type was received.
default:
Log.e("DiscardPileDragEventListener", "Unknown action type received by OnDragListener.");
}
return false;
}
}
这是设置实际拖动卡片的代码片段;在这个 CardView 中是 ImageView 的子类:
for (Card card : meld) {
//highlight wildcards unless no dragging (Computer turn, or Human final turn)
CardView cv = new CardView(this, card, iView, allowDragging ? highlightWildCardRank : null);
cv.setTag(iView); //allows us to pass the index into the dragData without dealing with messy object passing
...
cv.bringToFront();
cv.setClickable(false); //TODO:B: Allow selection by clicking for multi-drag?
if (allowDragging) {//no dragging of computer cards or Human cards after final turn
cv.setOnDragListener(new CardViewDragEventListener()); //needed per-card to reset the dragged card to normal visibility (alpha)
cv.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN) return false;
// Create a new ClipData using the tag as a label, the plain text MIME type, and
// the string containing the View index. This will create a new ClipDescription object within the
// ClipData, and set its MIME type entry to "text/plain"
ClipData dragData = ClipData.newPlainText("Discard", v.getTag().toString());
View.DragShadowBuilder cardDragShadow = new CardViewDragShadowBuilder(v);
v.startAnimation(Utilities.instantFade(FiveKings.HALF_TRANSPARENT_ALPHA, FiveKings.HALF_TRANSPARENT_ALPHA));
// Starts the drag
v.startDrag(dragData, cardDragShadow, null, 0);
return true;
}//end onClick
});
}//end if allowDragging
...
并且在 onCreate 中,我设置了 Discard Pile onDragListener:
...
mDiscardPile.setOnDragListener(new DiscardPileDragEventListener());
...
一个问题是我在 Discard Pile 的父视图中也有一个 onDragListener,以便在您将卡片拖到 Discard Pile 时提供消息。这在我的测试中运行良好,但我只是想知道它是否有某种关联。
如有任何关于前进方向的建议,我们将不胜感激。
事实证明,三星为 S7 引入了一项名为 Game Tuner 的功能,并将其反向移植到 S6 和其他设备。它会自动更改市场上标记为 "Game" 的任何已安装应用程序的分辨率。这对于图形驱动的游戏非常有用,但完全搞砸了像我这样的纸牌游戏的拖放。请注意,即使您从未进入 Game Tuner 应用程序,也会发生这种情况。
因此,如果您在玩游戏或应用时遇到这种情况,请询问用户是否安装了 Game Tuner,并要求他们将分辨率设置为 100%(他们可以针对每个游戏进行设置)。
2017 年 3 月更新: 我现在有 99% 的解决方案。即使没有安装 Game Tuner,三星也可以扩展游戏(显然达到 75%)。因此,您必须安装 Game Tuner,然后将分辨率重置为 100% 才能使拖放正常工作。
我没有的那 1% 就是为什么他们会做出这样愚蠢的事情。
Samsung Display Scaling 选项:它可以缩小某些屏幕上的内容。
例如,当您在主屏幕上打开一个文件夹时,您会看到更多图标。
我相信三星最近(2016 年 7 月)发布了具有此功能的 OTA 更新。如果此功能在 Settings/Display 中可用,则表示已安装 OTA 更新,似乎可以解决拖放问题。