简体   繁体   English

GridView与colspan和rowSpan

[英]GridView with colspan and rowSpan

I have been trying to make a gridview with drag and drop functionality along with one cell of different size. 我一直在尝试使用拖放功能和一个不同大小的单元格来制作gridview。 I have already made the the grid drag and drop and its working fine. 我已经使网格拖放并且工作正常。 you can check the code from here 你可以从这里查看代码

我的代码输出

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 但我希望它像这样,纯粹是动态的,因为我将拖拽另一个将被替换并自动调整大小 期望的输出

Updated with new code that accommodates resizing of cells. 更新了适用于细胞大小调整的新代码。 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. 你的问题是指GridView但你提供的代码没有提到GridView而是使用GridLayout ,所以我假设GridLayout是正确的布局。

I have put together a demo using a mocked-up layout with one 2x2 tile. 我已经使用带有一个2x2磁贴的模拟布局组装了一个演示。 I have modified the code that you have supplied to accommodate the 2x2 tile. 我修改了您提供的代码以容纳2x2磁贴。 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. 除了我为实现2x2磁贴而添加的代码之外,MainAcitivity的唯一其他更改是calculateNextIndex方法,该方法使用不同的方法计算(x,y)位置的索引。 Layouts and the LongPressListener class were also mocked up since they were not supplied. 布局和LongPressListener类也被模拟,因为它们没有提供。

Here is a video of the demo: 这是一个演示视频:

在此输入图像描述

MainActivity.java 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;
    }
}

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. 如果您稍微使用该演示,您将看到可以移动图块,以便打开1x1图块间隙。 This may be OK, but the code may need to be reworked a little if not. 这可能没问题,但是如果没有,可能需要重新编写代码。

You can try : 你可以试试 :

https://github.com/askerov/DynamicGrid https://github.com/askerov/DynamicGrid

在此输入图像描述

I hope it can help your problem! 我希望它可以帮助你解决问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM