Android'de, bir ListView
kullanıyorum ve sürükle bırak kullanarak öğelerini yeniden sıralamak istiyorum. Bir "sürükle ve bırak listview" farklı uygulama olduğunu biliyorum, ancak API düzey 11 beri gelen Drag and Drop framework kullanmak istiyorum.Sürükle ve bırak, ListView ve öğe ACTION_DRAG_STARTED etkinliğini kaçırmayan görünümler
Sürükleyip bırakırken ListView
sayfamı kaydırmak istedim kadar çok iyi başladı. Aşağıdaki örnekte yazıldığı gibi, şimdilik, hangi liste elemanının üstündeyim diye kontrol ediyorum, bu yüzden pozisyonu ListView.getLastVisiblePosition()
ve ListView.getFirstVisiblePosition()
arasında değilse, diğer liste maddelerini görüntülemek için ListView.smoothScrollToPosition()
kullanın.
Bu ilk uygulama ancak oldukça iyi çalışıyor.
Kaydırma sırasında sorun ortaya çıkıyor: bazı öğeler sürükle ve bırak olaylarına - DragEvent.ACTION_DRAG_ENTERED
ve diğerleri - yanıt vermem. ListView'in öğe görünümlerini yönetme biçiminden kaynaklanıyor: Artık görünmeyen öğe görünümlerini geri dönüştürmeye çalışıyor.
Sorun yok ve çalışıyor, ancak bazen ListAdapter
'un getView()
yeni bir nesneyi döndürüyor. Yeni olduğu için, bu nesne diğer DragEvent
olaylarına cevap vermemesi için DragEvent.ACTION_DRAG_STARTED
cevapsız!
İşte bir örnek. Bu durumda, bir liste öğesine uzun bir tıklama ile bir sürükle ve bırak işlemi başlatırsam ve sürüklediğimde, bunların çoğunda olduğumda öğelerin çoğunluğu yeşil bir arka plana sahip olur; ama bazıları değil.
Onları yapma hakkında herhangi bir fikir, DragEvent.ACTION_DRAG_STARTED
yanıtsız olsalar bile sürükle ve bırak etkinlik mekanizmasına abone olur mu?
// 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;
}
}
}
: sürükle dinleyici örnek olarak
(ki, benListView
uygulanan, hatırlatılır), onun gibi bir şey olabilir. Bu gerçekten iyi bir iş gibi görünüyor ve oldukça teknik! Benden al. –