2013-04-22 8 views
9

私はapi> 14用に開発中で、GridViewにドラッグ&ドロップ機能を実装しました。アイテムをドラッグしている間にスクロールグリッドを表示する(シャドウとして)

ただし、項目を画面の上部または下部にドラッグすると、GridViewはスクロールしません。

私は、あなたが端に移動するにつれてアイテムをドラッグする方向にスクロールし、画面の垂直方向の中心に向かってアイテムを戻すようにスクロールさせたいと思います。

もちろん、この種の機能はドラッグアンドドロップで標準にする必要がありますか?

とにかく、誰もがこれにアプローチする最善の方法を知っていますか?

UPDATE: 私は実際にも、ドラッググリッド項目にスクロールしようとしたインターネット上の単一の例を見つける(私はここで何かが足りないのですか?)することはできませんだけでは私の問題を解決してみましょう。

グリッドビューをスクロールするためのドラッグ可能なアイテム(影として表示されます)をどうやって取得しますか?私は次のようにドラッグを割り当てています:

int gridChildPosition = position - mGridView.getFirstVisiblePosition();      
ViewFlipper gridItem = (ViewFlipper) mGridView.getChildAt(gridChildPosition); 

ClipData data = ClipData.newPlainText("", ""); 
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(gridItem); 

if (mGridView.startDrag(data, shadowBuilder, gridItem, 0)) { 

    int lastVisiblePosition = mGridView.getLastVisiblePosition() - mGridView.getFirstVisiblePosition(); 
    for (int i=0; i<=lastVisiblePosition; i++) { 
     if (i == gridChildPosition) { 
      continue; 
     } 
     mGridView.getChildAt(i).setOnDragListener(new GridItemDragListener(position)); 
     mGridView.getChildAt(i).setAlpha(0.4f); 
    } 
} 

上記のコードはドラッグ可能なシャドウを作成し、他のすべての項目は現在淡色表示になっています。しかし、私はグリッドビューをスクロールするためにどのように影を得ることができるのか分かりません。

+0

は、ここに答えをチェックアウト:http://stackoverflow.com/questions/12236035/androidを-to-to-auto-scroll-a-gridview-vertical-on-drag-item-to-the-edg?rq = 1 – dennisdrew

+0

@dennisdrewありがとう、すでにこれを見ました。オンドラッグスクロールの説明はありません。 – HGPB

+0

DragDropチュートリアルhttp://blahti.wordpressをご覧ください。com/2011/10/03/android-gridview/for drag-drop-forはあなたを助けるかもしれません。 – GrIsHu

答えて

1

smoothScrollToPosition(int position)またはsmoothScrollByOffset(int offset)GridViewの方法を使用する必要があると思います。画面の上部と下部に2つの長方形を表示します。ドラッグ中にタッチイベントが矩形で受信された場合は、GridViewをスクロールします。特定の時点で最後に目に見える位置を得るには、getLastVisiblePosition()メソッドを使用します。

7

ドラッグイベントのクールなことは、親の中でそれらを聞くことですViewGrouptooGridViewを拡張し、onDragEventをオーバーライドしてDragEvent.ACTION_DRAG_LOCATIONを監視します。そこに、ドラッグのY座標(event.getY())を取得します。 ACTION_DRAG_STARTEDから真を返すか、ACTION_DRAG_LOCATIONでイベントを受け取らないようにしてください。

おそらく、jaibatrik suggestsというテクニックを使用して、または単にGridViewの測定された高さのパーセンテージを使用して、「ヒットボックス」を決定します。

おそらくsmoothScrollByOffset(int offset)を使用するのが最も理にかなっています。この方法で、ステップ/指数スクロールを実装できます。つまり、ユーザーがドラッグしたアイテムをヒットボックスに保持する時間が長いほど、オフセットが大きくなります。

オープンソースのライブラリ/コンポーネントのクールなアイデアのような感じです。 ;-)

編集:ここでは

は、あなたがこれを行うことができる方法の例です:

import android.app.Activity; 
import android.content.ClipData; 
import android.content.ClipData.Item; 
import android.content.Context; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.DragEvent; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemLongClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.GridView; 

public class GridDragActivity extends Activity implements OnItemLongClickListener { 

    private static final String TAG = "GridDragActivity"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     MyGridView gridView = new MyGridView(this); 
     gridView.setNumColumns(3); 
     gridView.setOnItemLongClickListener(this); 
     gridView.setAdapter(new ArrayAdapter<String>(
       this, 
       android.R.layout.simple_list_item_1, 
       COUNTRIES)); 

     setContentView(gridView); 
    } 

    @Override 
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, 
      long id) { 

     ClipData data = ClipData.newPlainText((String) view.getTag(), 
       String.valueOf(position)); 
     View.DragShadowBuilder shadow = new View.DragShadowBuilder(view); 
     view.startDrag(data, shadow, null, 0); 

     return true; 
    } 

    class MyGridView extends GridView { 

     private static final int THRESHHOLD = 200; 
     private static final int OFFSET = 10; 

     public MyGridView(Context context) { 
      super(context); 
     } 

     @Override 
     public boolean onDragEvent(DragEvent event) { 

      int height = getMeasuredHeight(); 

      switch (event.getAction()) { 
       case DragEvent.ACTION_DRAG_STARTED: 
        return true; 

       case DragEvent.ACTION_DRAG_LOCATION: 

        float y = event.getY(); 
        if (height - y < THRESHHOLD) { 
         smoothScrollByOffset(OFFSET); 
        } else if (height - y > height - THRESHHOLD) { 
         smoothScrollByOffset(-OFFSET); 
        } 

        return true; 

       case DragEvent.ACTION_DROP: 

        ClipData data = event.getClipData(); 
        Item item = data.getItemAt(0); 
        int start = Integer.valueOf((String) item.getText()); 
        int end = pointToPosition((int) event.getX(), (int) event.getY()); 

        Log.i(TAG, "DROP started at = " + start + ", ended at = " + end); 

        return true; 
      } 

      return super.onDragEvent(event); 
     } 
    } 

    static final String[] COUNTRIES = new String[] { 
     "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", 
     "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", 
     "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", 
     "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", 
     "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", 
     "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", 
     "British Indian Ocean Territory", 
     "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi", 
     "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", 
     "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", 
     "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", 
     "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", 
     "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", 
     "Dominican Republic", 
     "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", 
     "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland", 
     "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia", 
     "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar", 
     "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", 
     "Guinea-Bissau", 
     "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", 
     "Hungary" 
    }; 
} 
+0

私はあなたの提案で遊んでいます。 – HGPB

+0

@Haraldo最新の回答のサンプルコードをご覧ください。 :-) –

+0

ありがとう、私は転用されているので、これを見るには時間が必要です。しかし、この解決策が役立つなら、私はまだ賞金を授与します。 – HGPB

関連する問題