Tôi không chắc đây có phải là vấn đề về thiết bị hay không, nhưng tôi đã tạo một danh sách có thể kéo có thể kéo bằng cách sử dụng bố cục tương đối và chế độ xem hình ảnh. Tôi có những lý do rất cụ thể để thực hiện nó theo cách này và đó không phải là câu hỏi của tôi.Android/kindle drag drop freezing thỉnh thoảng
Sự cố tôi gặp phải đôi khi nó sẽ đóng băng hoàn toàn ứng dụng của tôi. Mục sẽ bị kẹt trong trạng thái kéo. Nếu tôi nhấc ngón tay của mình, đối tượng bóng (kéo) vẫn còn trên màn hình và nếu tôi chạm vào màn hình nó sẽ di chuyển đến vị trí đó. Điều này sẽ tiếp tục trong khoảng một phút và sau đó tôi sẽ nhận được thông báo lỗi cho biết ứng dụng không phản hồi với tùy chọn giết hoặc chờ. Bit chỉ có ích trong logcat là như sau:
12-09 14:23:13.157: W/WindowManager(16415): Drag is in progress but there is no drag window handle.
Sau đó, khi lần ứng dụng ra tôi có được điều này là một lỗi
12-09 14:59:09.782: E/ActivityManager(16415): ANR in com.appname.appname (com.appname.appname/.MainActivity)
12-09 14:59:09.782: E/ActivityManager(16415): Reason: keyDispatchingTimedOut
Tôi googled thông báo lỗi này và các thông tin chỉ là một ai đó không có kéo người nghe và một người khác nói đó là cảm biến thiết bị cảm ứng không theo kịp.
Lý tưởng nhất, tôi rất muốn khắc phục lỗi này và ngăn điều đó xảy ra ngay từ đầu. Nó dường như xảy ra chủ yếu nếu tôi kéo nhanh, nhưng tôi không thể yêu cầu người dùng của tôi không kéo nhanh ... đúng không?
Cách khác, có cách nào để tôi có thể phát hiện rằng việc kéo đã làm đóng ứng dụng và làm gián đoạn quá trình kéo. Giống như thiết lập một bộ đếm thời gian trên người nghe cảm ứng và nếu không có tin nhắn drag_location trong vòng một hoặc hai lần gián đoạn kéo? Công cụ hẹn giờ tôi biết cách làm, nhưng tôi không biết làm thế nào tôi sẽ buộc kéo để dừng lại trong khi nó bị đóng băng. Bất kỳ ý tưởng?
Dưới đây là các mã:
thiết lập
//happens once when the app loads
RelativeLayout trackList = (RelativeLayout) findViewById(R.id.nsTrackList1);
trackList.setOnDragListener(new MyTrackDragListener(this));
//happens in a loop for each "track" (image view)
trackButton = new ImageView(this);
trackButton.setImageDrawable(nsPackages[trackId].banner[bannerSizeSelector]);
trackButton.setOnTouchListener(new MyTrackTouchListener());
Mở liên lạc
public class MyTrackTouchListener implements OnTouchListener {
boolean isDragging=false;
float prevX, prevY;
public boolean onTouch(View view, MotionEvent motionEvent) {
if(motionEvent.getPointerCount() < 2 && !isDragging) return false;
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
isDragging=false;
prevX=0;
prevY=0;
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {
if(isDragging) return true;
boolean wasFirst = (prevX == 0 || prevY == 0);
float theTotalDiff = Math.abs(prevX - motionEvent.getX()) + Math.abs(prevY - motionEvent.getY());
prevX=motionEvent.getX();
prevY=motionEvent.getY();
if(wasFirst) return true;
if(theTotalDiff <3) return true;
ClipData data = ClipData.newPlainText("", "");
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, shadowBuilder, view, 0);
int thisViewId = view.getId();
//hide view
view.setVisibility(View.GONE);
isDragging=true;
return true;
} else if (motionEvent.getAction() == MotionEvent.ACTION_UP || motionEvent.getAction() == MotionEvent.ACTION_CANCEL) {
isDragging=false;
return true;
}else {
Integer thisAction = motionEvent.getAction();
Log.d("looper","Motion action: "+thisAction.toString());
return false;
}
}
}
On Kéo
class MyTrackDragListener implements OnDragListener {
public static boolean isDragging=false;
private MainActivity parent;
public MyTrackDragListener(MainActivity myAct){
parent=myAct;
}
@Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
isDragging=true;
// do nothing
return true;
case DragEvent.ACTION_DROP:
View view = (View) event.getLocalState();
parent.doDropSort(view,(int) event.getY());
return true;
case DragEvent.ACTION_DRAG_ENDED:
if(isDragging && event.getResult()==false){
View view2 = (View) event.getLocalState();
parent.doDropSort(view2,(int) event.getY(),true);
return true;
}
isDragging=false;
break;
case DragEvent.ACTION_DRAG_LOCATION:
parent.doDragHover((int) event.getY());
return true;
default:
Log.d("looper","drag other... "+String.valueOf(event.getAction()));
}
return false;
}
}
Một vài điều tôi đã cố gắng
- Loại bỏ người nghe kéo hoàn toàn
- Luôn luôn trả về true từ onDrag
- Luôn luôn trả về false từ onDrag
- Về cơ bản tất cả các kết hợp của sự trở lại đúng/sai trong kéo và chạm vào
- Xóa phần 2 ngón tay và Action_Move và kích hoạt thao tác kéo trên Action_down thay vì
Kết quả tương tự. Kéo và thả hoạt động hoàn hảo khoảng 70% thời gian và sau đó đột nhiên thực hiện hành vi đóng băng được mô tả ở trên. Đôi khi nó là lần đầu tiên kéo nó đôi khi nó sau vài. Tôi đã nhận thấy trên mẫu nhất quán ngoại trừ có thể là tốc độ kéo. Dường như thường xảy ra khi tôi kéo nhanh, nhưng kéo hướng hoặc nơi tôi kéo đến dường như không quan trọng.
Là một cựu nhân viên Amazon và nhà phát triển Kindle, tôi sẽ xem bạn có thể làm cho nó liên tục repro với một ứng dụng thử nghiệm nhỏ và sau đó gửi một báo cáo lỗi. –
@CarlAnderson Cảm ơn, tôi đã thử nghiệm thủ công một vài ngày và tôi không thể thấy bất kỳ mẫu nào. Bạn có lời khuyên nào về cách xây dựng một ứng dụng thử nghiệm cho loại hành vi này không? Có cách nào để mô phỏng đầu vào cảm ứng/kéo-thả không? – Lenny
Không có gì tôi biết, và thật không may nếu bạn không thể làm cho nó liên tục repro họ có lẽ sẽ không nhìn vào nó. –