2016-02-21 30 views
0

我想要一个正方形(宽度与高度相同)GridView以横向方向填充屏幕的整个高度。在GridView是(由8个方块8)棋盘与XML:在android中的全高方形元素

<com.example.jens.jchess2.view.MyGridView 
    android:id="@+id/chessboard" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:padding="0dp" 
    android:numColumns="8" 
    android:verticalSpacing="0dp" 
    android:horizontalSpacing="0dp"> 
</com.example.jens.jchess2.view.MyGridView> 

和网格的元素是:

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/square" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="#000080" 
    android:orientation="vertical" 
    android:padding="0pt"> 

    <ImageView 
     android:id="@+id/square_background" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:adjustViewBounds="true" 
     android:padding="0pt" /> 


    <ImageView 
     android:id="@+id/piece" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center" 
     android:adjustViewBounds="true" 
     android:padding="0pt" /> 

</FrameLayout> 

,其中ImageViews对应于正方形和片(均来自PNG图像)的董事会。

在定制MyGridView我重写onMeasure如下:

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = getContext().getResources().getDisplayMetrics().heightPixels; 


    if (width > height) { 
     super.onMeasure(
       MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY), 
       MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY) 
     ); 
    } else { 
     super.onMeasure(
       MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), 
       MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY) 
     ); 
    } 
} 

这使我在纵向和横向的方形GridView控件。在纵向模式下,它填满整个宽度,一切都很好。但在横向模式下,它会延伸到屏幕下方,因为GridView /板的高度(=宽度)太大。它由工具栏的高度和状态栏的高度过大。我怎样才能得到GridView的正确大小,即屏幕高度减去状态栏高度减去工具栏高度?

+0

make heightMeasureSpec等于窗口的高度.... –

回答

0

开始布局文件的两个版本:

/res/layout/grid.xml

... 

    <!-- full width --> 
    <com.example.MyGridView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     ... 
     /> 

    ... 

/res/layout-land/grid.xml

... 

    <!-- full height --> 
    <com.example.MyGridView 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     ... 
     /> 

    ... 

你可能已经有这样的事情了。

现在,在您onMeasure()覆盖,该match_parent尺寸将有EXACTLY一个MeasureSpec模式和wrap_content尺寸将有AT_MOST一个MeasureSpec模式。你可以使用它来实现你想要的布局。

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

    int width = MeasureSpec.getSize(widthMeasureSpec); 
    int height = MeasureSpec.getSize(heightMeasureSpec); 
    int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
    int heightMode = MeasureSpec.getMode(heightMeasureSpec); 


    if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.AT_MOST) { 
     // portrait 
     super.onMeasure(widthMeasureSpec, widthMeasureSpec); 

    } else if (heightMode == MeasureSpec.EXACTLY && widthMode == MeasureSpec.AT_MOST) { 
     // landscape 
     super.onMeasure(heightMeasureSpec, heightMeasureSpec); 

    } else { 
     super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    } 
} 

编辑:我发现这两种模式可以AT_MOST取决于ViewGroup容器上。请参阅我的其他答案以获取更新的测量代码。

+0

这似乎不适用于我。我只得到一行网格元素。 – user1583209

+0

'GridView'本身是否正方形?如果是这样,那么你可能需要做一些事情来让你的项目视图大小不同。如果你可以发布你的网格项目布局XML,这将有所帮助。 –

+0

感谢您的回复,我发布了上面的网格条目的XML,并试图澄清我的问题是什么。 – user1583209

0

啊。现在我看到这是一款游戏。

有时最好有布局和子视图,但在大多数情况下,如果是游戏板,最好创建一个表示游戏视图的单个View子类。

例如,如果您的用户说他们希望能够捏缩放到游戏板的一个象限中,该怎么办?你不能用GridView来做到这一点。

我掀起了一个简单的应用程序,告诉你这是如何工作的。我简化了之前发布的onMeasure()代码,而不是GridView,一个View子类呈现游戏板。

MainActivity只设置内容视图。

/res/layout/activity_main。XML:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.gameboard.MainActivity"> 

    <com.example.gameboard.GameBoardView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" /> 
</RelativeLayout> 

/res/layout-land/activity_main.xml:

通知match_parentwrap_content和切换为宽度和高度。

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.example.gameboard.MainActivity"> 

    <com.example.gameboard.GameBoardView 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_centerHorizontal="true" /> 
</RelativeLayout> 

GameBoardView.java:

public class GameBoardView extends View { 

    private Paint mPaint; 

    public GameBoardView(Context context) { 
     super(context); 
    } 

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

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public GameBoardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

     int width = MeasureSpec.getSize(widthMeasureSpec); 
     int height = MeasureSpec.getSize(heightMeasureSpec); 
     int size = Math.min(width, height); 
     int sizeMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY); 

     super.onMeasure(sizeMeasureSpec, sizeMeasureSpec); 

     mPaint = new Paint(); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 

     int w = getWidth()/8; 
     int h = getHeight()/8; 

     for (int row = 0; row < 8; row++) { 
      for (int col = 0; col < 8; col++) { 
       // choose black or white depending on the square 
       mPaint.setColor((row + col) % 2 == 0 ? 0xFFFFFFFF : 0xFF000000); 
       canvas.drawRect(w * col, h * row, w * (col + 1), h * (row + 1), mPaint); 
      } 
     } 
    } 
} 

在这里,我只是画正方形右视图。现在,如果我正在制作国际象棋游戏,我还会创建一个Drawable子类,它将采用游戏模型并进行渲染。有一个单独的Drawable用于渲染游戏可以很容易地缩放到正确的大小。例如,您的Drawable可以以固定的常量大小呈现,然后由View子类缩放以适合。 View子类将主要用作控制器,解释触摸事件并更新游戏模型。