GridLayout的视图动态获取行/列 [英] GridLayout with view dynamic get row/column
问题描述
我只是跟着这个教程,创建一个自定义查看
作为的网格布局
的项目。
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屋!