How to make a GridLayout fit screen size
Note: The information below the horizontal line is no longer accurate with the introduction of Android 'Lollipop' 5, as GridLayout
does accommodate the principle of weights since API level 21.
Quoted from the Javadoc:
Excess Space Distribution
As of API 21, GridLayout's distribution of excess space accomodates
the principle of weight. In the event that no weights are specified,
the previous conventions are respected and columns and rows are taken
as flexible if their views specify some form of alignment within their
groups. The flexibility of a view is therefore influenced by its
alignment which is, in turn, typically defined by setting the gravity
property of the child's layout parameters. If either a weight or
alignment were defined along a given axis then the component is taken
as flexible in that direction. If no weight or alignment was set, the
component is instead assumed to be inflexible.Multiple components in the same row or column group are considered to
act in parallel. Such a group is flexible only if all of the
components within it are flexible. Row and column groups that sit
either side of a common boundary are instead considered to act in
series. The composite group made of these two elements is flexible if
one of its elements is flexible.To make a column stretch, make sure all of the components inside it
define a weight or a gravity. To prevent a column from stretching,
ensure that one of the components in the column does not define a
weight or a gravity.When the principle of flexibility does not provide complete
disambiguation, GridLayout's algorithms favour rows and columns that
are closer to its right and bottom edges. To be more precise,
GridLayout treats each of its layout parameters as a constraint in the
a set of variables that define the grid-lines along a given axis.
During layout, GridLayout solves the constraints so as to return the
unique solution to those constraints for which all variables are
less-than-or-equal-to the corresponding value in any other valid
solution.
It's also worth noting that android.support.v7.widget.GridLayout
contains the same information. Unfortunately it doesn't mention which version of the support library it was introduced with, but the commit that adds the functionality can be tracked back to July 2014. In November 2014, improvements in weight calculation and a bug was fixed.
To be safe, make sure to import the latest version of the gridlayout-v7 library.
The principle of 'weights', as you're describing it, does not exist with GridLayout
. This limitation is clearly mentioned in the documentation; excerpt below. That being said, there are some possibilities to use 'gravity' for excess space distribution. I suggest you have read through the linked documentation.
Limitations
GridLayout does not provide support for the principle of weight, as
defined in weight. In general, it is not therefore possible to
configure a GridLayout to distribute excess space in non-trivial
proportions between multiple rows or columns. Some common use-cases
may nevertheless be accommodated as follows. To place equal amounts of
space around a component in a cell group; use CENTER alignment (or
gravity). For complete control over excess space distribution in a row
or column; use a LinearLayout subview to hold the components in the
associated cell group. When using either of these techniques, bear in
mind that cell groups may be defined to overlap.
For an example and some practical pointers, take a look at last year's blog post introducing the GridLayout
widget.
Edit: I don't think there's an xml-based approach to scaling the tiles like in the Google Play app to 'squares' or 'rectangles' twice the length of those squares. However, it is certainly possible if you build your layout programmatically. All you really need to know in order two accomplish that is the device's screen dimensions.
Below a (very!) quick 'n dirty approximation of the tiled layout in the Google Play app.
Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
int halfScreenWidth = (int)(screenWidth *0.5);
int quarterScreenWidth = (int)(halfScreenWidth * 0.5);
Spec row1 = GridLayout.spec(0, 2);
Spec row2 = GridLayout.spec(2);
Spec row3 = GridLayout.spec(3);
Spec row4 = GridLayout.spec(4, 2);
Spec col0 = GridLayout.spec(0);
Spec col1 = GridLayout.spec(1);
Spec colspan2 = GridLayout.spec(0, 2);
GridLayout gridLayout = new GridLayout(this);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(15);
TextView twoByTwo1 = new TextView(this);
GridLayout.LayoutParams first = new GridLayout.LayoutParams(row1, colspan2);
first.width = screenWidth;
first.height = quarterScreenWidth * 2;
twoByTwo1.setLayoutParams(first);
twoByTwo1.setGravity(Gravity.CENTER);
twoByTwo1.setBackgroundColor(Color.RED);
twoByTwo1.setText("TOP");
twoByTwo1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByTwo1, first);
TextView twoByOne1 = new TextView(this);
GridLayout.LayoutParams second = new GridLayout.LayoutParams(row2, col0);
second.width = halfScreenWidth;
second.height = quarterScreenWidth;
twoByOne1.setLayoutParams(second);
twoByOne1.setBackgroundColor(Color.BLUE);
twoByOne1.setText("Staff Choices");
twoByOne1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne1, second);
TextView twoByOne2 = new TextView(this);
GridLayout.LayoutParams third = new GridLayout.LayoutParams(row2, col1);
third.width = halfScreenWidth;
third.height = quarterScreenWidth;
twoByOne2.setLayoutParams(third);
twoByOne2.setBackgroundColor(Color.GREEN);
twoByOne2.setText("Games");
twoByOne2.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne2, third);
TextView twoByOne3 = new TextView(this);
GridLayout.LayoutParams fourth = new GridLayout.LayoutParams(row3, col0);
fourth.width = halfScreenWidth;
fourth.height = quarterScreenWidth;
twoByOne3.setLayoutParams(fourth);
twoByOne3.setBackgroundColor(Color.YELLOW);
twoByOne3.setText("Editor's Choices");
twoByOne3.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByOne3, fourth);
TextView twoByOne4 = new TextView(this);
GridLayout.LayoutParams fifth = new GridLayout.LayoutParams(row3, col1);
fifth.width = halfScreenWidth;
fifth.height = quarterScreenWidth;
twoByOne4.setLayoutParams(fifth);
twoByOne4.setBackgroundColor(Color.MAGENTA);
twoByOne4.setText("Something Else");
twoByOne4.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne4, fifth);
TextView twoByTwo2 = new TextView(this);
GridLayout.LayoutParams sixth = new GridLayout.LayoutParams(row4, colspan2);
sixth.width = screenWidth;
sixth.height = quarterScreenWidth * 2;
twoByTwo2.setLayoutParams(sixth);
twoByTwo2.setGravity(Gravity.CENTER);
twoByTwo2.setBackgroundColor(Color.WHITE);
twoByTwo2.setText("BOTOM");
twoByTwo2.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByTwo2, sixth);
The result will look somewhat like this (on my Galaxy Nexus):
GridLayout autosize items to fit screen
According to your description, you want to split the screen row height and column width for GridLayout item, if yes, you can take a look the following code to modify your code.
You can use:
GridLayout.InvokeSpec(r, GridLayout.Fill, 1f)
to average current available space:
for (int r=0;r<5;r++)
{
for(int c=0;c<7;c++)
{
var row = GridLayout.InvokeSpec(r, GridLayout.Fill, 1f);
var col = GridLayout.InvokeSpec(c, GridLayout.Fill,1f);
View layout1 = View.Inflate(this, Resource.Layout.layout1, null);
TextView textview = layout1.FindViewById<TextView>(Resource.Id.textView1);
textview.Text = "test!";
layout1.LayoutParameters = new GridLayout.LayoutParams(row, col);
monthGrid.AddView(layout1);
}
}
Result:
Specifying items in an android grid layout to re-size to fill screen height
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="3">
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorPrimaryDark"
android:gravity="center"
android:text="Tile1" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorAccent"
android:gravity="center"
android:text="Tile2" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="Tile3" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorAccent"
android:gravity="center"
android:text="Tile4" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="Tile5" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_columnWeight="1"
android:layout_gravity="fill_horizontal"
android:layout_rowWeight="1"
android:background="@color/colorAccent"
android:gravity="center"
android:text="Tile6" />
</GridLayout>
GridLayoutManager - how to auto fit columns?
You can calculate available number of columns, given a desired column width, and load the image as calculated. Define a static funtion to calculate as:
public class Utility {
public static int calculateNoOfColumns(Context context, float columnWidthDp) { // For example columnWidthdp=180
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
float screenWidthDp = displayMetrics.widthPixels / displayMetrics.density;
int noOfColumns = (int) (screenWidthDp / columnWidthDp + 0.5); // +0.5 for correct rounding to int.
return noOfColumns;
}
}
And then when using it in the activity or fragment you can do like this :
int mNoOfColumns = Utility.calculateNoOfColumns(getApplicationContext());
............
mGridLayoutManager = new GridLayoutManager(this, mNoOfColumns);
Stretch GridView to fit full screen
You can achieve this with a GridLayout
, instead of a GridView
, by using the layout_columnWeight
and layout_rowWeight
attributes. GridLayout
was added in API level 14, but these attributes were not added until API level 21. But you can make use of the GridLayout
as well as the layout_columnWeight
and layout_rowWeight
attributes back to API level 7 by using the v7 GridLayout Support Library:
compile 'com.android.support:gridlayout-v7:25.0.1'
Then, all you have to do is make sure every cell in the GridLayout
has an equal layout_columnWeight
and layout_rowWeight
:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout android:id="@+id/app_bar"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.GridLayout
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:columnCount="2"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1"
android:background="@color/black_alpha_26">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="YouTube"/>
</FrameLayout>
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Videos"/>
</FrameLayout>
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="VR Apps"/>
</FrameLayout>
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1"
android:background="@color/black_alpha_26">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="VR Movies"/>
</FrameLayout>
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1"
android:background="@color/black_alpha_26">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="VR Games"/>
</FrameLayout>
<FrameLayout
app:layout_columnWeight="1"
app:layout_rowWeight="1">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="Shop"/>
</FrameLayout>
</android.support.v7.widget.GridLayout>
</android.support.design.widget.CoordinatorLayout>
This is the result I got:
Android GridView to fit Screen Height
If you already know that you have 6 items, why not just create 6 blocks. i.e. If you have 6 images, why not just create 6 image views?
Ex:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="3" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation = "horizontal"
android:layout_weight="1"
android:weightSum="100">
<ImageView
android:id="@+id/image1"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
<ImageView
android:id="@+id/image2"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation = "horizontal"
android:layout_weight="1"
android:weightSum="100">
<ImageView
android:id="@+id/image3"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
<ImageView
android:id="@+id/image4"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:orientation = "horizontal"
android:layout_weight="1"
android:weightSum="100">
<ImageView
android:id="@+id/image5"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
<ImageView
android:id="@+id/image6"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="50"
android:src="@drawable/sunny"/>
</LinearLayout>
</LinearLayout>
Resize gridview for different screen sizes
@James_Duh here is some code that will work but I do not feel this is the most elegant way to deal with your question. My concern is how much overhead in terms of processing power and time this method uses. Also what is the impact on memory? I do not have the ability to answer these concerns perhaps another user will expand on these questions. I would like to know how to do this by changing the properties of the GridView or utilize the styles. My solution has the potential to create a lot of code for a larger project. That said here is the code listed for your pleasure
`public class PageThree extends AppCompatActivity {
Button button;
TextView TVinfo;
TextView TVone, TVtwo;
RelativeLayout RLpage3;
TextView tv1,tv2,tv3,tv4,tv5,tv6;
//GridView GVtext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_page_three );
button = (Button) findViewById( R.id.button );
TVinfo = (TextView) findViewById( R.id.TVinfo );
TVone = (TextView) findViewById( R.id.TVone );
TVtwo = (TextView) findViewById( R.id.TVtwo );
RLpage3 = (RelativeLayout) findViewById( R.id.RLpage3 );
tv1 = (TextView)findViewById( R.id.tv1 );
tv2 = (TextView)findViewById( R.id.tv2 );
tv3 = (TextView)findViewById( R.id.tv3 );
tv4 = (TextView)findViewById( R.id.tv4 );
tv5 = (TextView)findViewById( R.id.tv5 );
tv6 = (TextView)findViewById( R.id.tv6 );
//GVtext = (GridView)findViewById( R.id.GVtext );
DisplayMetrics metrics = getResources().getDisplayMetrics();
int DeviceTotalWidth = metrics.widthPixels;
int dens = metrics.densityDpi;
int dp = (DeviceTotalWidth * 160/dens);
TVtwo.setText( String.valueOf( DeviceTotalWidth +" "+dens +" "+ dp) );
int dpL = dp ;
int dpR = dp ;
int ts = 0;
String L = String.valueOf( dpL+"sp" );
TVone.setText( L );
if (DeviceTotalWidth == 480) {
if (dp == 320) {
dpL = 240;
dpR = 200;
ts = 14;
}
}
if (DeviceTotalWidth == 768) {
if (dp == 384) {
dpL = 360;
dpR = 360;
ts = 20;
}
}
if (DeviceTotalWidth == 1080) {
if (dp == 411) {
dpL = 520;
dpR = 550;
ts = 20;
}
}
if (DeviceTotalWidth == 1536) {
if (dp == 768) {
dpL = 740;
dpR = 790;
ts = 20;
}
}
TVone.setTextSize( 16 );
tv1.setTextSize( ts );
tv2.setTextSize( ts );
tv3.setTextSize( ts );
tv4.setTextSize( ts );
tv5.setTextSize( ts );
tv6.setTextSize( ts );
tv1.setWidth( dpL );
tv2.setWidth( dpR );
tv3.setWidth( dpL );
tv4.setWidth( dpR );
tv5.setWidth( dpL );
tv6.setWidth( dpR );
}`
Related Topics
Android Gridlayout with Dynamic Number of Columns Per Row
Actionbaractivity Is Deprecated
Apply a Theme to an Activity in Android
How to Draw Free Hand Polygon in Google Map V2 in Android
How to Handle Cookies in Httpurlconnection Using Cookiemanager
Google Speech Recognition Timeout
Connectivitymanager Getnetworkinfo(Int) Deprecated
Webview Shouldinterceptrequest Example
How to Create and Read Log on Android Devices
How to Make a Phone Call from HTML on Android
Facebook Key Hash Does Not Match Any Stored Key Hashes
Transitive Dependencies for Local Aar Library
Why Do I Get "Unresolved Reference" Error for My View's Name/Id When I Type It in Kotlin
Why Doesn't Logcat Show Anything in My Android
How to Capture an Image and Store It with the Native Android Camera
Getview Returning Null When Fragment Has Been Created from an Activity