2017-10-15 1 views
7

J'ai essayé de faire un gridview avec la fonctionnalité de glisser-déposer avec une cellule de taille différente. J'ai déjà fait glisser et laisser tomber la grille et cela fonctionne bien. vous pouvez vérifier le code de hereGridView avec colspan et rowSpan

my code output

mais je veux que ce soit comme ça et purement dynamique que je vais draging et laisser tomber l'autre qui sera remplacé et redimensionnées automatiquement desired output

+0

Regardez dans la disposition quadrillée de la grille. Aussi, si vous pouvez utiliser un recycleur afficher quelque chose comme [this] (https://stackoverflow.com/questions/29457712/how-to-set-different-columns-for-rows-in-android-gridview) pourrait vous aider. –

+0

mon code a glisser et déposer des fonctionnalités si ce n'est que l'interface utilisateur alors j'ai beaucoup d'options comme https://github.com/felipecsl/AsymmetricGridView – Furqan

+0

Si vous faites la promotion d'un poste de connaissances aussi une réponse à votre question. – AsifAli72090

Répondre

5

Mis à jour avec un nouveau code qui prend en charge le redimensionnement des cellules. Votre question fait référence à GridView mais le code que vous avez fourni ne mentionne pas GridView mais utilise plutôt GridLayout, donc je suppose que GridLayout est la bonne mise en page.

J'ai mis en place une démo en utilisant une mise en page avec un carreau 2x2. J'ai modifié le code que vous avez fourni pour accueillir la tuile 2x2. Autre que le code que j'ai ajouté pour implémenter la tuile 2x2, le seul autre changement à MainAcitivity était à la méthode calculateNextIndex qui utilise une manière différente de calculer l'index à une position (x, y). Les mises en page et la classe LongPressListener ont également été mockées car elles n'étaient pas fournies.

Voici une vidéo de la démo:

enter image description here

MainActivity.java

public class MainActivity extends AppCompatActivity { 

    private static final int ITEMS = 10; 
    private GridLayout mGrid; 
    private ScrollView mScrollView; 
    private ValueAnimator mAnimator; 
    private Boolean isScroll = false; 
    private GridLayout.Spec m1xSpec = GridLayout.spec(GridLayout.UNDEFINED, 1); 
    private GridLayout.Spec m2xSpec = GridLayout.spec(GridLayout.UNDEFINED, 2); 
    private int mBaseWidth; 
    private int mBaseHeight; 
    private int mBaseMargin; 

    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     mScrollView = (ScrollView) findViewById(R.id.scrollView); 
     mScrollView.setSmoothScrollingEnabled(true); 

     mGrid = (GridLayout) findViewById(R.id.grid); 

     mGrid.setOnDragListener(new DragListener()); 

     final LayoutInflater inflater = LayoutInflater.from(this); 

     GridLayout.LayoutParams lp; 

     DisplayMetrics displayMetrics = new DisplayMetrics(); 
     getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); 
     float dpiToPx = displayMetrics.density; 
     View view = inflater.inflate(R.layout.item, mGrid, false); 
     lp = (GridLayout.LayoutParams) view.getLayoutParams(); 
     mBaseWidth = lp.width; 
     mBaseHeight = lp.height; 
     mBaseMargin = lp.rightMargin; 

     for (int i = 0; i < ITEMS; i++) { 
      final View itemView = inflater.inflate(R.layout.item, mGrid, false); 
      final TextView text = (TextView) itemView.findViewById(R.id.text); 
      text.setText(String.valueOf(i + 1)); 
      itemView.setOnLongClickListener(new LongPressListener()); 
      lp = (i == 0) ? make2x2LayoutParams(itemView) : make1x1LayoutParams(itemView); 
      mGrid.addView(itemView, lp); 
     } 
    } 

    private GridLayout.LayoutParams make2x2LayoutParams(View view) { 
     GridLayout.LayoutParams lp = (GridLayout.LayoutParams) view.getLayoutParams(); 

     lp.width = mBaseWidth * 2 + 2 * mBaseMargin; 
     lp.height = mBaseHeight * 2 + 2 * mBaseMargin; 
     lp.rowSpec = m2xSpec; 
     lp.columnSpec = m2xSpec; 
     lp.setMargins(mBaseMargin, mBaseMargin, mBaseMargin, mBaseMargin); 
     return lp; 
    } 

    private GridLayout.LayoutParams make1x1LayoutParams(View view) { 
     GridLayout.LayoutParams lp = (GridLayout.LayoutParams) view.getLayoutParams(); 

     lp.width = mBaseWidth; 
     lp.height = mBaseHeight; 
     lp.setMargins(mBaseMargin, mBaseMargin, mBaseMargin, mBaseMargin); 
     lp.rowSpec = m1xSpec; 
     lp.columnSpec = m1xSpec; 
     return lp; 
    } 

    private int mDraggedIndex; 

    class DragListener implements View.OnDragListener { 
     @Override 
     public boolean onDrag(View v, DragEvent event) { 
      final View view = (View) event.getLocalState(); 
      int index = calculateNextIndex(event.getX(), event.getY()); 
      View child; 

      switch (event.getAction()) { 
       case DragEvent.ACTION_DRAG_STARTED: 
        mDraggedIndex = index; 
        break; 

       case DragEvent.ACTION_DRAG_LOCATION: 
        if (view == v) return true; 
        // get the new list index 


        final Rect rect = new Rect(); 
        mScrollView.getHitRect(rect); 
        final int scrollY = mScrollView.getScrollY(); 

        if (event.getY() - scrollY > mScrollView.getBottom() - 250) { 
         startScrolling(scrollY, mGrid.getHeight()); 
        } else if (event.getY() - scrollY < mScrollView.getTop() + 250) { 
         startScrolling(scrollY, 0); 
        } else { 
         stopScrolling(); 
        } 

        child = mGrid.getChildAt(0); 
        if (index == 0) { 
         child.setLayoutParams(make1x1LayoutParams(child)); 
         view.setLayoutParams(make2x2LayoutParams(view)); 
        } else if (mDraggedIndex == 0) { 
         view.setLayoutParams(make1x1LayoutParams(view)); 
         child.setLayoutParams(make2x2LayoutParams(child)); 
        } else { 
         child.setLayoutParams(make2x2LayoutParams(child)); 
         view.setLayoutParams(make1x1LayoutParams(view)); 
        } 
        mGrid.removeView(view); 
        mGrid.addView(view, index); 
        break; 
       case DragEvent.ACTION_DROP: 
        for (int i = 0; i < mGrid.getChildCount(); i++) { 
         child = mGrid.getChildAt(i); 
         child.setLayoutParams(make1x1LayoutParams(child)); 
        } 
        mGrid.removeView(view); 
        if (index == 0) { 
         view.setLayoutParams(make2x2LayoutParams(view)); 
        } 
        mGrid.addView(view, index); 
        view.setVisibility(View.VISIBLE); 
        mGrid.getChildAt(0).setLayoutParams(make2x2LayoutParams(mGrid.getChildAt(0))); 
        break; 
       case DragEvent.ACTION_DRAG_ENDED: 
        if (!event.getResult()) { 
         view.setVisibility(View.VISIBLE); 
        } 
        break; 
      } 
      return true; 
     } 
    } 

    private void startScrolling(int from, int to) { 
     if (from != to && mAnimator == null) { 
      isScroll = true; 
      mAnimator = new ValueAnimator(); 
      mAnimator.setInterpolator(new OvershootInterpolator()); 
      mAnimator.setDuration(Math.abs(to - from)); 
      mAnimator.setIntValues(from, to); 
      mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
       @Override 
       public void onAnimationUpdate(ValueAnimator valueAnimator) { 
        mScrollView.smoothScrollTo(0, (int) valueAnimator.getAnimatedValue()); 
       } 
      }); 
      mAnimator.addListener(new AnimatorListenerAdapter() { 
       @Override 
       public void onAnimationEnd(Animator animation) { 
        isScroll = false; 
        mAnimator = null; 
       } 
      }); 
      mAnimator.start(); 
     } 
    } 

    private void stopScrolling() { 
     if (mAnimator != null) { 
      mAnimator.cancel(); 
     } 
    } 

    private int calculateNextIndexOld(float x, float y) { 
     // calculate which column to move to 
     final float cellWidth = mGrid.getWidth()/mGrid.getColumnCount(); 
     final int column = (int) (x/cellWidth); 

     final float cellHeight = mGrid.getHeight()/mGrid.getRowCount(); 
     final int row = (int) Math.floor(y/cellHeight); 

     int index = row * mGrid.getColumnCount() + column; 
     if (index >= mGrid.getChildCount()) { 
      index = mGrid.getChildCount() - 1; 
     } 
     Log.d("MainActivity", "<<<<index=" + index); 
     return index; 
    } 

    private int calculateNextIndex(float x, float y) { 
     // calculate which column to move to 
     int index; 

     for (index = 0; index < mGrid.getChildCount(); index++) { 
      View child = mGrid.getChildAt(index); 
      Rect rect = new Rect(); 
      child.getHitRect(rect); 
      if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) { 
       break; 
      } 
     } 
     if (index >= mGrid.getChildCount()) { 
      // Move into empty cell? Calculate based upon uniform cell sizes. 
      index = calculateNextIndexOld(x, y); 
     } 
     if (index >= mGrid.getChildCount()) { 
      // Can't determine where to put it? Add it to the end. 
      index = mGrid.getChildCount() - 1; 
     } 
     return index; 
    } 
} 

Si vous travaillez avec la démo un peu, vous verrez qu'il est possible déplacer les carreaux de façon à ouvrir un espace de carrelage 1x1. Cela peut être OK, mais le code devra peut-être être retravaillé un peu sinon.

+0

Le seul problème avec votre programme est 1 n'est pas le redimensionnement vous le faites glisser vers la 3e rangée. – Furqan

+0

@Furqan Le GridLayout est de 3 colonnes sur 5 lignes. Je ne suis pas clair sur le redimensionnement que vous attendez en faisant glisser vers la 3ème rangée. Pouvez-vous expliquer plus loin? – Cheticamp

+0

Je veux dire que lorsque vous faites glisser le chiffre 1 à n'importe quelle position, le nombre 1 doit être redimensionné à la taille normale et l'autre nombre remplace la position du nombre. En bref, la taille du nombre à la position 0 reste la même mais les autres nombres peuvent adapter la taille quand ils seront placés à 0. – Furqan