GridLayout的视图动态获取行/列 [英] GridLayout with view dynamic get row/column

查看:207
本文介绍了GridLayout的视图动态获取行/列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是跟着这个教程,创建一个自定义查看作为的网​​格布局的项目。

I just followed this tutorial, to create a custom View as an item of a GridLayout.

这是我的 CustomView

public class RowView extends View{

boolean touchOn;
boolean mDownTouch = false;
private OnToggledListener toggledListener;
int _IdRow = 0;
int _IdColumn = 0;

public RowView(Context context, int Rows, int Columns) {
    super(context);
    this._IdRow = Rows;
    this._IdColumn = Columns;
    init();
}

public RowView(Context context) {
    super(context);
    init();
}

public RowView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public RowView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init();
}

private void init() {
    touchOn = false;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
            MeasureSpec.getSize(heightMeasureSpec));
}

@Override
protected void onDraw(Canvas canvas) {
    if (touchOn) {
        canvas.drawColor(Color.RED);
    } else {
        canvas.drawColor(Color.GRAY);
    }
}
//onClick not possible to use on custom View so, onTouchEvent is the solution
@Override
public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);

    switch (event.getAction()) {
        //if Click
        case MotionEvent.ACTION_DOWN:

            touchOn = !touchOn;
            invalidate();

            if(toggledListener != null){
                toggledListener.OnToggled(this, touchOn);
            }

            mDownTouch = true;
            return true;

        case MotionEvent.ACTION_UP:
            if (mDownTouch) {
                mDownTouch = false;
                performClick();
                return true;
            }
    }
    return false;
}

@Override
public boolean performClick() {
    super.performClick();
    return true;
}

public void setOnToggledListener(OnToggledListener listener){
    toggledListener = listener;
}

public int get_IdRow() {
    return _IdRow;
}

public int get_IdColumn() {
    return _IdColumn;
}

在此上课的时候​​用户点击网​​格布局的项目我可以检测和其更改为另一种颜色,这是确定。
但是问题来了在创建此时间:

On this class I can detect when user clicks on an item of GridLayout and change it to another color, that's ok. But the problem comes at the time to create this :

这是我的 MainActivity 在这里我显示网​​格布局

This is my MainActivity where I show the GridLayout :

int numOfCol = mGridLayout.getColumnCount();
    int numOfRow = mGridLayout.getRowCount();
    mRowViews = new RowView[numOfCol*numOfRow];
    for(int yPos=0; yPos<numOfRow; yPos++){
        for(int xPos=0; xPos<numOfCol; xPos++){
            RowView tView = new RowView(this, xPos, yPos);
            tView.setOnToggledListener(this);
            mRowViews[yPos*numOfCol + xPos] = tView;
            mGridLayout.addView(tView);
        }
    }
     mGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){

       @Override
       public void onGlobalLayout() {

        final int MARGIN = 5;

        int pWidth = mGridLayout.getWidth();
        int pHeight = mGridLayout.getHeight();
        int numOfCol = mGridLayout.getColumnCount();
        int numOfRow = mGridLayout.getRowCount();
        int w = pWidth/numOfCol;
        int h = pHeight/numOfRow;

        for(int yPos=0; yPos<numOfRow; yPos++){
         for(int xPos=0; xPos<numOfCol; xPos++){
          GridLayout.LayoutParams params =
           (GridLayout.LayoutParams)mRowViews[yPos*numOfCol + xPos].getLayoutParams();
          params.width = w - 2*MARGIN;
          params.height = h - 2*MARGIN;
          params.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);
          mRowViews[yPos*numOfCol + xPos].setLayoutParams(params);
         }
        }
       }});

还有就是接口 OnToggledListener ,让我的我的<$的行和列的方法C $ C>网​​格布局点击它的一个项目时:

Also there is a method of the Interface OnToggledListener that gives to me the row and column of my GridLayout when an item of it is clicked :

@Override
public void OnToggled(MyView v, boolean touchOn) {
//get the id string
 String idString = v.get_IdRow() + ":" + v.get_IdColumn();
}

我想避免创建 mGridLayout.getViewTreeObserver()。addOnGlobalLayoutListener(新ViewTreeObserver.OnGlobalLayoutListener(),因为它填补上我不屏幕的事不想...我试图把网​​格布局的6x6与的android:layout_height =400dp,它只能显示3x3的这就是 LogCat中的消息

I'd like to avoid to create that mGridLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() because it fills on the screen thing that I don't want... I tried to put GridLayout 6x6 with android:layout_height="400dp" and it only show 3x3 and this is the LogCat message

D / android.widget.GridLayout:垂直约束:Y6-Y0> = 1749年,Y6-Y5&LT; = 291,Y5,Y4&LT; = 291,Y4-Y3&LT; = 291,Y3-Y2&LT; = 291,Y2 -y1&LT; = 291,Y1-Y0&LT; = 291不一致;永久删除:Y6-Y5&LT; = 291。

D/android.widget.GridLayout: vertical constraints: y6-y0>=1749, y6-y5<=291, y5-y4<=291, y4-y3<=291, y3-y2<=291, y2-y1<=291, y1-y0<=291 are inconsistent; permanently removing: y6-y5<=291.

我想要做类似网​​格布局[行] [柱] 来获得背景的颜色,然后做的东西,但我无法找到此解决方案。

I'd like to do something like GridLayout[row][colum] to get the color of background and then do stuff, but I'm not able to find this solution.

推荐答案

有关简化,可以实现自定义的查看包裹网​​格布局和相关的逻辑。下面我报告一个可能的方法。

For simplifying, you can implement a custom Board view wrapping the GridLayout and related logic. Below I report a possible approach.

在这里期望是有一个 ItemView控件重新presenting一个单一的中板细胞。

Expectation here is to have an ItemView for representing one single cell in the board.

public class Board extends FrameLayout implements View.OnClickListener {

    private GridLayout mGridView;
    private int mRowsCount;
    private int mColsCount;
    private int mCellSpace;
    private OnItemClickListener mOnItemClickListener;

    public Board(Context context) {
        super(context);
        init(context, null);
    }

    // other constructors

    private void init(Context context, AttributeSet attrs) {
        // default values
        mRowsCount = 1;
        mColsCount = 1;
        View layout = inflate(getContext(), R.layout.view_lights_board, null);
        mGridView = (GridLayout) layout.findViewById(R.id.view_grid);
        mGridView.setRowCount(mRowsCount);
        mGridView.setColumnCount(mColsCount);
        mGridView.post(new Runnable() {
            @Override
            public void run() {
                int width = getMeasuredWidth() / getColumnsCount();
                int height = getMeasuredHeight() / getRowsCount();
                for (int i = 0; i < getRowsCount(); i++) {
                    for (int j = 0; j < getColumnsCount(); j++) {
                        GridLayout.LayoutParams params = (GridLayout.LayoutParams)
                                getChildAt(i, j).getLayoutParams();
                        params.width = width;
                        params.height = height;
                        getChildAt(i, j).setLayoutParams(params);
                    }
                }
            }
        });
        addView(layout);
    }

    // this method allows to dinamically create grid
    public void buildChildren(int rowsCount, int colsCount) {
        mRowsCount = rowsCount;
        mColsCount = colsCount;
        mGridView.setRowCount(mRowsCount);
        mGridView.setColumnCount(mColsCount);
        buildChildren();
    }

    public void buildChildren() {
        for (int i = 0; i < getRowsCount(); i++) {
            for (int j = 0; j < getColumnsCount(); j++) {
                ItemView view = new ItemView(getContext(), i, j);
                view.setOnClickListener(this);
                mGridView.addView(view);
            }
        }
    }

    public void setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
    }

    public ItemView getChildAt(int rowIndex, int columnIndex) {
        int index = (getColumnsCount() * rowIndex) + columnIndex;
        return (ItemView) mGridView.getChildAt(index);
    }

    public boolean isTouchOn(int rowIndex, int columnIndex) {
        return getChildAt(rowIndex, columnIndex).isTouchOn();
    }

    public int getColumnsCount() {
        return mGridView.getColumnCount();
    }

    public int getRowsCount() {
        return mGridView.getRowCount();
    }

    @Override
    public void onClick(View v) {
        if (v instanceof ItemView) {
            ItemView view = (ItemView) v;
            if (mOnItemClickListener != null) {
                mOnItemClickListener.onItemClick(view);
            }
        }
    }

    public interface OnItemClickListener {

        void onItemClick(ItemView view);

    }

}

在你的活动布局,您将有这样的事情(在这里我假设你的应用程序包是com.android.example):

In your Activity layout you will have something like this (here I assume your app package is com.android.example):

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <com.android.example.Board
        android:id="@+id/grid"
        android:layout_width="match_parent"
        android:layout_height="400dp" />

</FrameLayout>

这是可能实现的活动:

And this is possible implementation of the Activity:

public class MainActivity extends AppCompatActivity implements LightsOutBoard.OnItemClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Board board  = (Board) findViewById(R.id.grid);
        board.setOnItemClickListener(this);

        board.buildChildren(3, 3);
    }

    @Override
    public void onItemClick(ItemView view) {
        String text = view.getRowIndex() + " - " + view.getColumnIndex();
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    }

}

希望这可以帮助。

Hope this could help.

这篇关于GridLayout的视图动态获取行/列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆