5

मुझे यकीन नहीं है कि यह एक डिवाइस समस्या है या मेरे कोड के साथ कोई समस्या है, लेकिन मैंने एक सापेक्ष लेआउट और छवि दृश्यों का उपयोग करके एक सरल ड्रैग करने योग्य क्रमबद्ध सूची बनाई है। मेरे पास ऐसा करने के लिए बहुत ही विशिष्ट कारण हैं और यह मेरा प्रश्न नहीं है।एंड्रॉइड/किंडल ड्रैग ड्रॉप फ्रीजिंग कभी-कभी

मेरी समस्या यह है कि कभी-कभी यह मेरे ऐप को पूरी तरह स्थिर कर देगा। आइटम ड्रैगिंग स्थिति में फंस जाएगा। अगर मैं अपनी उंगली उठाता हूं तो छाया (ड्रैगिंग) ऑब्जेक्ट स्क्रीन पर अभी भी है और यदि मैं स्क्रीन को स्पर्श करता हूं तो यह उस स्थान पर चलेगा। यह लगभग एक मिनट तक चल जाएगा और फिर मुझे एक त्रुटि मिलेगी कि ऐप इसे मारने या प्रतीक्षा करने के विकल्प के साथ उत्तरदायी नहीं है।

12-09 14:23:13.157: W/WindowManager(16415): Drag is in progress but there is no drag window handle. 

फिर जब एप्लिकेशन का समय समाप्त मैं यह एक त्रुटि के रूप में

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 

मैं यह त्रुटि संदेश googled और केवल जानकारी नहीं के साथ किसी था मिलती है: logcat में ही उपयोगी बिट इस प्रकार है ड्रैग श्रोता और एक और व्यक्ति कह रहा है कि यह डिवाइस टच सेंसर नहीं रख रहा था।

आदर्श रूप से, मुझे इस त्रुटि को ठीक करना और इसे पहले स्थान पर होने से रोकना अच्छा लगेगा। ऐसा लगता है कि अगर मैं जल्दी से खींचता हूं, लेकिन मैं अपने उपयोगकर्ताओं से जल्दी से खींचने के लिए नहीं कह सकता ... सही?

वैकल्पिक रूप से, क्या कोई तरीका है कि मैं यह पता लगा सकता हूं कि ड्रैगिंग ने ऐप को जमे हुए हैं और ड्रैग को बाधित कर दिया है। टच श्रोता पर एक टाइमर सेट करने की तरह और यदि कोई ड्रैग_लोकेशन संदेश नहीं है तो दूसरे या दो में ड्रैग को बाधित करें? टाइमर सामान मुझे पता है कि कैसे करना है, लेकिन मुझे नहीं पता कि मैं जमे हुए होने पर रोकने के लिए ड्रैग को कैसे मजबूर करूंगा। कोई विचार?

कोड यह रहा:

सेटअप

//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()); 

touch पर

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; 
     } 
    } 
} 

खींचें पर

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; 
    } 
} 

कुछ बातें मैं पहले से ही

  • की कोशिश की खींचें श्रोता निकाला जा रहा है पूरी तरह से
  • हमेशा onDrag
  • से सच लौट
  • हमेशा झूठे onDrag
  • से लौटने के प्रत्येक संयोजन के लौटने
  • मूल रूप से सही/खींचें में झूठी और
  • 2 उंगली और Action_Move भाग को हटाकर और action_down पर खींचें ट्रिगर करने के बजाय

वही परिणाम। खींचें और ड्रॉप करें लगभग 70% समय के बारे में पूरी तरह से काम करता है और फिर अचानक ऊपर वर्णित ठंड व्यवहार करता है। कभी-कभी यह कई बार ड्रैग पर होता है कभी-कभी यह कई के बाद होता है। मैंने को संभवतः ड्रैग गति को छोड़कर लगातार पैटर्न पर ध्यान दिया है। ऐसा लगता है कि जब मैं जल्दी से खींच रहा हूं, लेकिन दिशा खींचें या जहां मैं खींचूं, इससे कोई फर्क नहीं पड़ता।

+0

एक पूर्व अमेज़न कर्मचारी और Kindle डेवलपर के रूप में, मैं अगर आप देखना चाहते हैं इसे एक छोटे से टेस्ट ऐप के साथ लगातार repro करने के लिए मिल सकता है और फिर एक बग रिपोर्ट जमा कर सकते हैं। –

+0

@ करल एंडरसन धन्यवाद, मैं कुछ दिनों के लिए मैन्युअल परीक्षण के साथ प्रयास कर रहा हूं और मुझे कोई पैटर्न नहीं दिख रहा है। क्या आपको इस तरह के व्यवहार के लिए टेस्ट ऐप बनाने का कोई सलाह है? स्पर्श/ड्रैग-ड्रॉप इनपुट अनुकरण करने का कोई तरीका है? – Lenny

+0

कोई भी जिसे मैं जानता हूं, और दुर्भाग्य से यदि आप इसे लगातार repro करने के लिए नहीं मिल पा रहे हैं तो शायद वे इसे नहीं देख पाएंगे। –

उत्तर

2

हाँ! मैं यह समझ गया।यहां जवाब है कि यह भविष्य में किसी की मदद करता है।

मैं अंत में यह केवल शीर्ष सूची आइटम को संकुचित होता (कैसे मुझे लगता है कि याद किया पता नहीं है) और फिर लाइनों बाहर टिप्पणी जब तक यह नहीं तोड़ा है जो इसे इस लाइन तक ही सीमित शुरू कर दिया:

view.setVisibility(View.GONE); 

जिस तरह से मेरी सूची सेट की गई थी, प्रत्येक आइटम लेआउट प्रॉपर्टी के नीचे एक रिश्तेदार लेआउट (शीर्ष आइटम को छोड़कर) का उपयोग करता था। एक बार जब मैंने दृश्य से शीर्ष आइटम हटा दिया तो दूसरा से ऊपर आइटम एक आइटम से नीचे था जो दृश्यता थी, इसलिए यह नहीं पता था कि क्या करना है। समाधान दृश्य में अगले आइटम के पैरामीटर को सेट करना था। सौभाग्य से मैं मैन्युअल रूप से अपने ट्रैक बटन की दृश्य आईडी सेट करता हूं (ऐसे अन्य विचार भी हैं जो स्क्रॉल करते हैं .. लेबल और ऐसे) ताकि वे क्रमिक हों। तो मेरी ठीक बस आईडी + 1 के साथ आइटम खोजने और शून्य इस तरह करने के लिए नीचे की स्थापना करके यह शीर्ष वस्तु बन कर रहा था ...

// the top item in my list is ALWAYS view id 1 
if(thisViewId == 1){ 
    ImageView nextTrackButton = (ImageView) trackList.findViewById(thisViewId+1); 
    LayoutParams ntLP = (LayoutParams) nextTrackButton.getLayoutParams(); 
    ntLP.addRule(RelativeLayout.BELOW,0); 
    nextTrackButton.setLayoutParams(ntLP); 
}   

//hide view 
view.setVisibility(View.GONE); 
संबंधित मुद्दे