एंड्रॉइड पर याद करते हैं, मैं ListView
का उपयोग करता हूं और मैं ड्रैग और ड्रॉप का उपयोग करके अपने आइटम को पुन: व्यवस्थित करने में सक्षम होना चाहता हूं। मुझे पता है कि "ड्रैग और ड्रॉप सूचीदृश्य" के विभिन्न कार्यान्वयन हैं, हालांकि मैं एपीआई स्तर 11 के बाद से आना चाहता हूं।खींचें और छोड़ें, ListView और आइटम दृश्य जो ACTION_DRAG_STARTED ईवेंट
यह बहुत अच्छा शुरू हुआ जब तक कि मैं ड्रैग और ड्रॉप करते समय अपना ListView
स्क्रॉल करना चाहता था। जैसा कि यह नीचे दिए गए उदाहरण में लिखा गया है, अभी के लिए, मैं किस सूची तत्व के शीर्ष पर हूं, इसलिए यदि इसकी स्थिति ListView.getLastVisiblePosition()
और ListView.getFirstVisiblePosition()
के बीच नहीं है, तो मैं अन्य सूची आइटम देखने के लिए ListView.smoothScrollToPosition()
का उपयोग करता हूं।
यह पहला कार्यान्वयन है लेकिन यह काफी अच्छा काम करता है।
स्क्रॉल करते समय समस्या उत्पन्न होती है: कुछ तत्व ड्रैग और ड्रॉप ईवेंट का जवाब नहीं देते - DragEvent.ACTION_DRAG_ENTERED
और अन्य - जब मैं उनके शीर्ष पर हूं। यह सूची दृश्य अपने आइटम दृश्यों के प्रबंधन के तरीके के कारण है: यह उन आइटम दृश्यों को रीसायकल करने का प्रयास करता है जो अब दिखाई नहीं दे रहे हैं।
यह ठीक है और यह काम करता है, लेकिन कभी-कभी ListAdapter
getView()
एक नई वस्तु देता है। चूंकि यह नया है, इस ऑब्जेक्ट को DragEvent.ACTION_DRAG_STARTED
से चूक गया है, इसलिए यह अन्य DragEvent
ईवेंट का उत्तर नहीं देता है!
यहां एक उदाहरण है। इस मामले में, यदि मैं एक सूची आइटम पर एक लंबे क्लिक के साथ एक ड्रैग और ड्रॉप शुरू करता हूं और यदि मैं इसे खींचता हूं, तो अधिकांश आइटमों में हरे रंग की पृष्ठभूमि होगी यदि मैं उनके ऊपर हूं; लेकिन कुछ नहीं करते हैं।
उन्हें DragEvent.ACTION_DRAG_STARTED
से चूकने के बावजूद ड्रैग और ड्रॉप इवेंट मैकेनिज्म की सदस्यता लेने के बारे में कोई विचार?
// Somewhere I have a ListView that use the MyViewAdapter
// MyListView _myListView = ...
// _myListView.setAdapter(new MyViewAdapter(getActivity(), ...));
_myListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(null, shadowBuilder, _myListView.getItemAtPosition(position), 0);
return true;
}
});
class MyViewAdapter extends ArrayAdapter<MyElement> {
public MyViewAdapter(Context context, List<TimedElement> objects) {
super(context, 0, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View myElementView = convertView;
if (myElementView == null) {
/* If the code is executed here while scrolling with a drag and drop,
* the new view is not associated to the current drag and drop events */
Log.d("app", "Object created!");
// Create view
// myElementView = ...
// Prepare drag and drop
myElementView.setOnDragListener(new MyElementDragListener());
}
// Associates view and position in ListAdapter, needed for drag and drop
myElementView.setTag(R.id.item_position, position);
// Continue to prepare view
// ...
return timedElementView;
}
private class MyElementDragListener implements View.OnDragListener {
@Override
public boolean onDrag(View v, DragEvent event) {
final int action = event.getAction();
switch(action) {
case DragEvent.ACTION_DRAG_STARTED:
return true;
case DragEvent.ACTION_DRAG_ENTERED:
v.setBackgroundColor(Color.GREEN);
v.invalidate();
return true;
case DragEvent.ACTION_DRAG_LOCATION:
int targetPosition = (Integer)v.getTag(R.id.item_position);
if (event.getY() < v.getHeight()/2) {
Log.i("app", "top "+targetPosition);
}
else {
Log.i("app", "bottom "+targetPosition);
}
// To scroll in ListView while doing drag and drop
if (targetPosition > _myListView.getLastVisiblePosition()-2) {
_myListView.smoothScrollToPosition(targetPosition+2);
}
else if (targetPosition < _myListView.getFirstVisiblePosition()+2) {
_myListView.smoothScrollToPosition(targetPosition-2);
}
return true;
case DragEvent.ACTION_DRAG_EXITED:
v.setBackgroundColor(Color.BLUE);
v.invalidate();
return true;
case DragEvent.ACTION_DROP:
case DragEvent.ACTION_DRAG_ENDED:
default:
break;
}
return false;
}
}
}
मैं यह कोशिश नहीं की, बल्कि जो जानते हैं कि शायद किसी दिन मैं लूंगा:
एक खींचें श्रोता उदाहरण के रूप में (जो, मैं आपको याद दिलाना,
ListView
पर लागू), यह ऐसा ही कुछ हो सकता है। यह एक असली अच्छा काम लगता है, और काफी तकनीकी! मुझसे ऊपर हटो –