簡體   English   中英

用Android中的掉落位置交換Gridview麻煩中的項目

[英]swap items in a Gridview trouble with the dropped position in Android

我一直在嘗試交換網格視圖中的項目,這就是我得到的地方:

xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parent_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/grid_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:horizontalSpacing="10dip"
        android:numColumns="4"
        android:verticalSpacing="10dip" />

</RelativeLayout>

主要活動類別:

public class MainActivity extends Activity implements OnDragListener,
        OnItemLongClickListener {

    ArrayList drawables;

    GridView gridView;
    private BaseAdapter adapter;
    private int draggedIndex = -1;
    private int droppedIndex = -1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        drawables = new ArrayList();
        drawables.add(R.drawable.ic_launcher);
        drawables.add(R.drawable.ic_launcher1);
        drawables.add(R.drawable.ic_launcher2);
        drawables.add(R.drawable.ic_launcher);
        drawables.add(R.drawable.ic_launcher);
        drawables.add(R.drawable.ic_launcher);
        drawables.add(R.drawable.ic_launcher);
        drawables.add(R.drawable.ic_launcher);
        gridView = (GridView) findViewById(R.id.grid_view);
        gridView.setOnItemLongClickListener(MainActivity.this);
        gridView.setAdapter(adapter = new BaseAdapter() {

            @Override
            // Get a View that displays the data at the specified position in
            // the data set.
            public View getView(int position, View convertView,
                    ViewGroup gridView) {
                // try to reuse the views.
                ImageView view = (ImageView) convertView;
                // if convert view is null then create a new instance else reuse
                // it
                if (view == null) {
                    view = new ImageView(MainActivity.this);
                }
                view.setImageResource((Integer) drawables.get(position));
                view.setTag(String.valueOf(position));
                return view;
            }

            @Override
            // Get the row id associated with the specified position in the
            // list.
            public long getItemId(int position) {
                return position;
            }

            @Override
            // Get the data item associated with the specified position in the
            // data set.
            public Object getItem(int position) {
                return drawables.get(position);
            }

            @Override
            // How many items are in the data set represented by this Adapter.
            public int getCount() {
                return drawables.size();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        switch (dragEvent.getAction()) {
        case DragEvent.ACTION_DRAG_STARTED:
            // Ignore this event
             return true;
        case DragEvent.ACTION_DRAG_ENTERED:
            // Ignore this event
            return true;
        case DragEvent.ACTION_DRAG_EXITED:
            // Ignore this event
            return true;
        case DragEvent.ACTION_DRAG_LOCATION:
            // Ignore this event
            return true;
        case DragEvent.ACTION_DROP:
            // Dropped inside a new view\
                adapter.notifyDataSetChanged();
                ImageView v2 = (ImageView)view.getParent();
                final int position1 = gridView.getPositionForView(v2);
                if (position1 >= 0) 
                { 
                    final long droppedIndex = gridView.getAdapter().getItemId(position1); 
                }
                Object item1 = gridView.getAdapter().getItem(draggedIndex);
                Object item2 = gridView.getAdapter().getItem(droppedIndex);
                drawables.remove(draggedIndex);
                drawables.remove(droppedIndex);
                drawables.add(droppedIndex,item1);
                drawables.add(draggedIndex,item2);
                draggedIndex = -1;
                droppedIndex = -1;
                adapter.notifyDataSetChanged();
        case DragEvent.ACTION_DRAG_ENDED:
           //
            view.setOnDragListener(null);
            return true;

         }
        return false;
    }

    @Override
    public boolean onItemLongClick(AdapterView gridView, View view,
            int position, long row) {
        ClipData.Item item = new ClipData.Item((String) view.getTag());
        ClipData clipData = new ClipData((CharSequence) view.getTag(),
                new String[] { ClipDescription.MIMETYPE_TEXT_PLAIN }, item);
        view.startDrag(clipData, new View.DragShadowBuilder(view), null, 0);
        view.setVisibility(View.INVISIBLE);
        draggedIndex = position;
        return true;
    }
}

我的問題是在DragEvent.ACTION_DROP中。 我的工作方式是這樣的:我拖動一個項目,然后將其放到另一位置時,該項目就會消失。 僅此而已。

假設首先獲取兩個位置:被拖動項目的位置(draggedIndex)和被放置項目的位置(droppedIndex)。 之后,我將兩個項目都刪除,並將它們再次添加到相反位置的數組中(被拖動的項目轉到了dropdIndex,另一個項目到了dragdIndex,因此它們被交換/交換了)

我想知道這是否是一個好方法,或者在嘗試檢索放置的位置(droppedIndex)時是否犯了任何錯誤。 有任何想法嗎?

在刪除項目之前,只需將項目添加到放置位置。 然后通過將放置位置增加1來刪除相應的項目。

case DragEvent.ACTION_DROP:

....
drawables.add(droppedIndex,item1);
            drawables.add(draggedIndex+1,item2);
 drawables.remove(draggedIndex+2);
            drawables.remove(droppedIndex+2);
....

希望這會幫助你。

我采用了略有不同的方法來獲取刪除的索引。 對於ACTION_DROP事件,getX()和getY()使用接收到放置的View(即gridview)的坐標系返回放置時拖動點的X和Y位置。

float dropX = event.getX();
float dropY = event.getY();

一旦有了x和y坐標,就可以在網格視圖中計算相應的行和列,然后使用類似以下的方法來獲取數據數組中對象的索引(我有一個4 x 4的網格) :

index = row * 4 + column;

最后,我使用數組列表(targetDrawables)來保存對gridview內容的引用,因此要重新排序,請使用:

targetDrawables.remove(draggedIndex);
targetDrawables.add(droppedIndex, draggedContents);

//  Invalidate the view to force a redraw of the Grid View

imageAdapter.notifyDataSetChanged();

您的代碼很好; 只需更換

Object item1 = gridView.getAdapter().getItem(draggedIndex);
Object item2 = gridView.getAdapter().getItem(droppedIndex);
drawables.remove(draggedIndex);
drawables.remove(droppedIndex);
drawables.add(droppedIndex,item1);
drawables.add(draggedIndex,item2);

Collections.swap(drawables, draggedIndex, droppedIndex);

它交換列表的位置,現在可以使用了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM