我一直在尝试使用拖放功能和一个不同大小的单元格来制作gridview.我已经使网格拖放并且工作正常.你可以查看
here的代码
但我希望它像这样,纯粹是动态的,因为我将拖拽另一个将被替换并自动调整大小
解决方法
更新了适用于细胞大小调整的新代码.
你的问题是指GridView,但你提供的代码没有提到GridView,而是使用GridLayout,所以我假设GridLayout是正确的布局.
你的问题是指GridView,但你提供的代码没有提到GridView,而是使用GridLayout,所以我假设GridLayout是正确的布局.
我已经使用带有一个2×2磁贴的模拟布局组装了一个演示.我修改了您提供的代码以容纳2×2磁贴.除了我为实现2×2磁贴而添加的代码之外,对MainAcitivity的唯一其他更改是calculateNextIndex方法,该方法使用不同的方法计算(x,y)位置的索引.布局和LongPressListener类也被模拟,因为它们没有提供.
这是一个演示视频:
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,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); 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); 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图块间隙.这可能没问题,但如果没有,可能需要重新编写代码.