2017-10-15 20 views
7

ドラッグ&ドロップ機能を備えたgridviewを異なるサイズの1つのセルとともに作成しようとしています。私はすでにグリッドをドラッグアンドドロップして動作させました。あなたはherecolspanとrowSpanを使用したGridView

my code output

からコードを確認することができますが、私は私がdraging、交換される他のドロップされるように、それはこのようなことと純粋にダイナミックにしたいとdesired output

+0

スタッガードグリッドレイアウトを調べます。また、リサイクラービューを使用することができる場合は、[this](https://stackoverflow.com/questions/29457712/how-to-set-different-columns-for-rows-in-android-gridview)のようなものが役に立ちます。 –

+0

私のコードにはドラッグアンドドロップ機能があり、UIの場合はhttps://github.com/felipecsl/AsymmetricGridViewなどの多くのオプションがあります – Furqan

+0

ナレッジポストをプロモートしている場合は、質問の回答も表示します。 – AsifAli72090

答えて

5

セルのサイズ変更に対応する新しいコードで更新されました。 あなたの質問はGridViewを参照していますが、指定したコードにはGridViewは表示されませんが、GridLayoutが代わりに使用されていますので、GridLayoutが正しいレイアウトであると仮定しています。

1つの2x2タイルのモックアップレイアウトを使用してデモを作成しました。 2x2タイルに対応するために提供したコードを変更しました。 2x2タイルを実装するために追加したコード以外にも、MainAcitivityの唯一の変更点は、(x、y)位置でインデックスを計算する別の方法を使用するcalculateNextIndexメソッドでした。レイアウトとLongPressListenerクラスも提供されていなかったので、嘲笑されました。ここで

は、デモのビデオです:

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

デモで少し作業する場合、あなたはそれが可能であることがわかります1×1のタイルギャップが開くようにタイルを移動させる。これは問題ありませんが、そうでない場合はコードを少し修正する必要があります。

+0

あなたのプログラムの唯一の問題は、1がサイズ変更されていないことです.3行目にドラッグします。 – Furqan

+0

@Furqan GridLayoutは3列×5行です。 3行目にドラッグしたときのリサイズについてはっきりしていません。もっと説明できますか? – Cheticamp

+0

番号1を任意の位置にドラッグすると、番号1は通常のサイズにサイズ変更され、もう1つの数字は大きい番号に変更された番号の位置に置き換えられます。要するに、位置0の数字のサイズは同じですが、他の数字は0に配置されるときにサイズを適応させることができます。 – Furqan

関連する問題