2017-10-15 19 views
7

Tôi đã cố gắng thực hiện một GridView với chức năng kéo và thả cùng với một ô có kích thước khác nhau. Tôi đã thực hiện việc kéo và thả lưới và làm việc tốt. bạn có thể kiểm tra mã từ hereGridView với colspan và rowSpan

my code output

nhưng tôi muốn nó được như thế này và hoàn toàn năng động như tôi sẽ được kéo và thả người kia sẽ được thay thế và thay đổi kích cỡ tự động desired output

+0

Nhìn vào bố cục lưới so le. Ngoài ra nếu bạn có thể sử dụng một cái nhìn tái chế một cái gì đó như [this] (https://stackoverflow.com/questions/29457712/how-to-set-different-columns-for-rows-in-android-gridview) có thể giúp bạn. –

+0

mã của tôi có chức năng kéo và thả nếu đó chỉ là giao diện người dùng thì tôi có nhiều tùy chọn như https://github.com/felipecsl/AsymmetricGridView – Furqan

+0

Nếu bạn đang quảng cáo bài đăng kiến ​​thức cũng là câu trả lời cho câu hỏi của bạn. – AsifAli72090

Trả lời

5

Được cập nhật bằng mã mới có khả năng thay đổi kích thước ô. Câu hỏi của bạn đề cập đến GridView nhưng mã bạn đã cung cấp không đề cập đến GridView nhưng sử dụng GridLayout thay vào đó, vì vậy tôi giả định rằng GridLayout là bố cục phù hợp.

Tôi đã đặt cùng một bản trình diễn bằng cách sử dụng bố cục giả lập với một ô xếp 2x2. Tôi đã sửa đổi mã mà bạn đã cung cấp để phù hợp với ngói 2x2. Khác với mã mà tôi đã thêm vào để thực hiện gạch 2x2, thay đổi duy nhất khác đối với MainAcitivity là phương pháp calculateNextIndex sử dụng một cách khác để tính chỉ mục tại vị trí (x, y). Layouts và lớp LongPressListener cũng được giả lập vì chúng không được cung cấp.

Dưới đây là một đoạn video của bản demo:

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

Nếu bạn làm việc với các bản demo một chút, bạn sẽ thấy rằng nó có thể để di chuyển các lát gạch sao cho khoảng trống ngói 1x1 được mở ra. Điều này có thể được, nhưng mã có thể cần phải được làm lại một chút nếu không.

+0

Vấn đề duy nhất với chương trình của bạn là 1 không thay đổi kích cỡ bạn kéo nó đến hàng thứ 3. – Furqan

+0

@Furqan GridLayout là 3 cột theo 5 hàng. Tôi không rõ ràng về việc thay đổi kích cỡ bạn mong đợi khi kéo đến hàng thứ 3. Bạn có thể giải thích thêm? – Cheticamp

+0

Ý tôi là khi bạn kéo số 1 đến vị trí bất kỳ thì số 1 sẽ đổi kích thước thành kích thước bình thường và số kia thay thế vị trí của số thay đổi thành kích thước lớn hơn. Trong ngắn hạn, kích thước của số ở vị trí 0 vẫn giữ nguyên nhưng các số khác có thể điều chỉnh kích thước khi chúng được đặt thành 0. – Furqan

Các vấn đề liên quan