2013-04-22 23 views
9

Pracuję dla api> 14 i zaimplementowałem funkcję przeciągania/upuszczania na GridView.Przewiń gridview podczas przeciągania elementu (jako cień)

Jednak podczas przeciągania elementów do górnej lub dolnej części ekranu GridView nie przewija.

Chciałbym, aby przewinął się w kierunku, w którym przeciągasz element coraz szybciej, gdy poruszasz się do krawędzi i powolny, gdy przesuwasz przedmiot z powrotem w kierunku pionowego środka ekranu.

Z pewnością ten rodzaj funkcjonalności powinien być standardem w przypadku przeciągania i upuszczania?

W każdym razie, czy ktoś zna najlepszy sposób podejścia do tego?

UPDATE: nie mogę rzeczywiście znaleźć jeden przykład w internecie, że nawet próbuje przejść z pozycji przeciągany siatki niech sam rozwiązać mój problem (ja czegoś brakuje tutaj?).

Jak uzyskać element przeciągalny (który pojawia się jako cień), aby przewinąć widok siatki? Przypisuję opór w następujący sposób:

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

Powyższy kod tworzy przeciągalny cień, a wszystkie inne elementy są obecnie przyciemniane. Ale nie jestem pewien, jak mogę uzyskać cień, aby przewinąć widok siatki.

+0

Zapoznaj się odpowiedź tutaj: http://stackoverflow.com/questions/12236035/android -how-to-auto-scroll-a-gridview-pionowo-na-przeciągnięciu-item-to-the-edg? rq = 1 – dennisdrew

+0

@dennisdrew Dzięki, już to widziałem. Brak wytłumaczenia przewijania w trybie przeciągania. – HGPB

+0

Możesz zapoznać się z samouczkiem DragDrop http: //blahti.wordpress.com/2011/10/03/drag-drop-for-android-gridview/które może ci pomóc. – GrIsHu

Odpowiedz

1

Myślę, że musisz użyć metod smoothScrollToPosition(int position) lub smoothScrollByOffset(int offset) z GridView. Weź dwa prostokąty u góry iu dołu ekranu. Jeśli zdarzenie dotykowe zostanie odebrane na tych prostokątach podczas przeciągania, przewiń GridView. Możesz uzyskać ostatnią widoczną pozycję w danym momencie, używając metody getLastVisiblePosition().

7

Fajną rzeczą w przypadku Drag Events jest to, że można ich słuchać również w jednostce macierzystej: ViewGroupteż. Rozszerz GridView i przesuń onDragEvent, aby monitorować DragEvent.ACTION_DRAG_LOCATION. W tym miejscu pobierz współrzędne Y (event.getY()) przeciągnięcia. Pamiętaj, aby zwrócić wartość true z numeru ACTION_DRAG_STARTED, inaczej nie otrzymasz zdarzenia w postaci ACTION_DRAG_LOCATION.

Określ swoje "pudełka trafień", być może używając techniki, która jest jaibatrik suggests, lub po prostu używając procentowej zmierzonej wysokości GridView.

Prawdopodobnie byłoby najbardziej sensowne użycie smoothScrollByOffset(int offset), w ten sposób można zaimplementować przewijanie krokowe/wykładnicze. Im dłużej użytkownik trzyma przeciągnięty element w polu trafień, tym większe przesunięcie.

Brzmi jak fajny pomysł na bibliotekę/składnik open source. ;-)

EDIT:

Oto przykład tego, jak można to zrobić:

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

Będę bawić się z tym, co sugerujesz. – HGPB

+0

@Haraldo Zobacz przykładowy kod w zaktualizowanej odpowiedzi. :-) –

+0

Dziękuję, potrzebuję trochę czasu, aby spojrzeć na to, jak byłem przekierowany. Jednak nadal będę honorować nagrodę, jeśli to rozwiązanie okaże się pomocne. – HGPB

Powiązane problemy