簡體   English   中英

GridView與colspan和rowSpan

[英]GridView with colspan and rowSpan

我一直在嘗試使用拖放功能和一個不同大小的單元格來制作gridview。 我已經使網格拖放並且工作正常。 你可以從這里查看代碼

我的代碼輸出

但我希望它像這樣,純粹是動態的,因為我將拖拽另一個將被替換並自動調整大小 期望的輸出

更新了適用於細胞大小調整的新代碼。 你的問題是指GridView但你提供的代碼沒有提到GridView而是使用GridLayout ,所以我假設GridLayout是正確的布局。

我已經使用帶有一個2x2磁貼的模擬布局組裝了一個演示。 我修改了您提供的代碼以容納2x2磁貼。 除了我為實現2x2磁貼而添加的代碼之外,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, 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;
    }
}

如果您稍微使用該演示,您將看到可以移動圖塊,以便打開1x1圖塊間隙。 這可能沒問題,但是如果沒有,可能需要重新編寫代碼。

你可以試試 :

https://github.com/askerov/DynamicGrid

在此輸入圖像描述

我希望它可以幫助你解決問題!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM