Tuesday, October 24, 2017

GridView with colspan and rowSpan

Leave a Comment

I have been trying to make a gridview with drag and drop functionality along with one cell of different size. I have already made the the grid drag and drop and its working fine. you can check the code from here

my code output

but I want it to be like this and purely dynamic as I will be draging and dropping the other which will be replaced and resized automatically desired output

2 Answers

Answers 1

Your question refers to GridView but the code you supplied doesn't mention GridView but uses GridLayout instead, so I am assuming that GridLayout is the right layout.

I have put together a demo using a mocked-up layout with one 2x2 tile. I have modified the code that you have supplied to accommodate the 2x2 tile. Other than the code that I added to implement the 2x2 tile, the only other change to MainAcitivity was to the calculateNextIndex method that uses a different way of calculating the index at an (x, y) position. Layouts and the LongPressListener class were also mocked up since they were not supplied.

Here is a video of the 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;      @Override     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 = new GridLayout.LayoutParams();         lp.rowSpec = GridLayout.spec(GridLayout.UNDEFINED, 2);         lp.columnSpec = GridLayout.spec(GridLayout.UNDEFINED, 2);         DisplayMetrics displayMetrics = new DisplayMetrics();         getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);         float dpiToPx = displayMetrics.density;          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());             if (i == 0) {                 // Setup 2x2 tile for demo purposes.                 lp.width = (int) (127 * 2 * dpiToPx);                 lp.height = (int) (102 * 2 * dpiToPx);                 int margin = (int) (2 * dpiToPx);                 lp.setMargins(margin, margin, margin, margin);                 itemView.setLayoutParams(lp);             }             mGrid.addView(itemView);         }     }      class DragListener implements View.OnDragListener {         @Override         public boolean onDrag(View v, DragEvent event) {             final View view = (View) event.getLocalState();             switch (event.getAction()) {                 case DragEvent.ACTION_DRAG_LOCATION:                     if (view == v) return true;                     // get the new list index                     final int index = calculateNextIndex(event.getX(), event.getY());                      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();                     }                      // remove the view from the old position                     mGrid.removeView(view);                     //add new view                     mGrid.addView(view, index);                     break;                 case DragEvent.ACTION_DROP:                     view.setVisibility(View.VISIBLE);                     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;     } } 

activity_main.xml

<ScrollView      android:id="@+id/scrollView"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:fillViewport="true"     android:fitsSystemWindows="true">      <GridLayout         android:id="@+id/grid"         android:layout_width="match_parent"         android:layout_height="match_parent"         android:columnCount="3"         android:orientation="horizontal"         android:rowCount="5"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"         app:layout_constraintTop_toTopOf="parent" />  </ScrollView> 

item.xml

<TextView      android:id="@+id/text"     android:layout_width="125dp"     android:layout_height="100dp"     android:background="@android:color/darker_gray"     android:gravity="center"     android:layout_margin="2dp"     android:textColor="@android:color/black"     android:textSize="36sp"     tools:text="88"> </TextView> 

LongPressListener.java - original listener was not supplied, so the following was substituted for the demo.

public class LongPressListener implements View.OnLongClickListener {      public boolean onLongClick(View view) {          ClipData data = ClipData.newPlainText("", "");         View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(             view);         view.startDrag(data, shadowBuilder, view, 0);         view.setVisibility(View.INVISIBLE);         return true;      } } 

If you work with the demo a little, you will see that it is possible to move tiles such that a 1x1 tile gap is opened up. This may be OK, but the code may need to be reworked a little if not.

Answers 2

You can try :

https://github.com/askerov/DynamicGrid

enter image description here

I hope it can help your problem!

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment