Heterogeneous GridLayout
So here is the solution I promised after one year =)
It basically uses the ViewTreeObserver to get the dimensions of the parent layout and create custom views accordingly. Since this code is one year old ViewTreeObserver might not be the best way to get the dimensions dynamically.
You can find the full source code here:
https://github.com/cdoger/Android_layout
I divided the screen into 8 equal widths and 6 equal heights. Here is a snapshot of how I laid out the views:
final RelativeLayout mainLayout = (RelativeLayout) findViewById(R.id.main_layout);
ViewTreeObserver vto = mainLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
final int oneUnitWidth = mainLayout.getMeasuredWidth() / 8;
final int oneUnitHeight = mainLayout.getMeasuredHeight() / 6;
/**
* 1
***************************************************************/
final RelativeLayout.LayoutParams otelParams = new RelativeLayout.LayoutParams(
oneUnitWidth * 4, oneUnitHeight);
otelParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
otelParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
// otelParams.setMargins(0, 0, 2, 0);
View1.setLayoutParams(otelParams);
/***************************************************************/
/**
* 2
***************************************************************/
final RelativeLayout.LayoutParams otherParams = new RelativeLayout.LayoutParams(
oneUnitWidth * 4, oneUnitHeight);
otherParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
otherParams.addRule(RelativeLayout.RIGHT_OF, View1.getId());
otherParams.setMargins(2, 0, 0, 0);
View2.setLayoutParams(otherParams);
/***************************************************************/
//... goes on like this
Here is the final screenshot:
Different heights in an Android GridLayout
how to dynamically change heights of the note cards based on their text length - you can just set the layout height to wrap_content
like this:
android:layout_height="wrap_content"
You can put your items in scrollView like this:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="short text !!!!!!!!!!!!?!@#!@%$%$#"
android:layout_marginBottom="8dp"/>
<TextView
android:layout_width="50dp"
android:layout_height="wrap_content"
android:text="Longggggggggggggggggggggggggggggggggggggggggggggggg text very long"/>
</LinearLayout>
</ScrollView>
And it will look like this:
The blue line represents the separation between your 2 views.
If you want to achieve this using RecyclerView check out this post, Staggered RecyclerView and Heterogeneous GridLayout
how in GridLayout (Android) to fit the last two blocks to full width?
Have a look at SpanSizeLookup.
Something like:
val layoutManager = GridLayoutManager(activity, 2)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (position) {
YOUR_CONDITION -> 2
else -> 1
}
}
}
recyclerView.layoutManager = layoutManager
Replace YOUR_CONDITION with some logic fits your requirements to make a cell twice higher.
Gridlayout changes widths
After much frustration I was unable to find a solution in the XML layout. However I did find a solution that seems to be working fairly well programatically.
I added a method called at the end of my OnCreate
public void ResizeTexts(){
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
float density = getResources().getDisplayMetrics().density;
float dpWidth = (outMetrics.widthPixels / density);
text1.getLayoutParams().width = (int)dpWidth;
text2.getLayoutParams().width = (int)dpWidth;
text3.getLayoutParams().width = (int)dpWidth;
text4.getLayoutParams().width = (int)dpWidth;
text5.getLayoutParams().width = (int)dpWidth;
text6.getLayoutParams().width = (int)dpWidth;
}
Which i adapted from this link re-setting a TextView height programmatically
then in my XML layout I set it up with:
<GridLayout
android:layout_width="match_parent"
android:layout_height="70dp">
<TextView
android:text="points"
android:layout_height="wrap_content"
android:layout_width="10dp"
android:id="@+id/text1"
android:layout_row="0"
android:layout_column="0"
android:textAlignment="textEnd"
/>
<TextView
android:text="totals"
android:layout_height="wrap_content"
android:layout_width="10dp"
android:id="@+id/text2"
android:layout_row="1"
android:layout_column="0"
android:textAlignment="textEnd"/>
<TextView
android:text="score"
android:layout_height="wrap_content"
android:id="@+id/text3"
android:layout_width="10dp"
android:layout_row="2"
android:layout_column="0"
android:textAlignment="textEnd"/>
<TextView
android:text="123.4"
android:layout_height="wrap_content"
android:id="@+id/text4"
android:layout_width="10dp"
android:layout_row="1"
android:layout_column="1"
android:textAlignment="textEnd"/>
<TextView
android:text="1.23"
android:layout_height="wrap_content"
android:id="@+id/text5"
android:layout_width="10dp"
android:layout_row="2"
android:layout_column="1"
android:textAlignment="textEnd"/>
<TextView
android:text="1234 "
android:layout_height="wrap_content"
android:id="@+id/text6"
android:layout_width="10dp"
android:layout_row="0"
android:layout_column="1"
android:textAlignment="textEnd"/>
</GridLayout>
*the layout widths in the xml layout I was using to try and 'break' it, not actually used.
Admittedly, i'm not sure if this is the 'best' way to do this. Personally I feel like the GridLayout XML should be able to do this on it's own. But, I couldn't figure it out.
Create gridlayout.
I guess that the most straightforward way is combining horizontal and vertical LinearLayouts
, setting different weights
to its subviews.
This code snippet could be a start point.-
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="@color/green"
android:layout_margin="5dp" >
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="@color/orange" >
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="@color/green" >
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_weight="0.5"
android:background="@color/orange" >
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_margin="5dp"
android:layout_weight="1"
android:background="@color/black" >
</RelativeLayout>
</LinearLayout>
Which results in a layout like this.-
PinterestListView looks promising as well.
GridLayout weird behaviour
Note that this 'change' does not happen when you remove the
layout_gravity="center" from the
<TextView
android:text="2,2 longer, also"
android:gravity="center_horizontal"
android:layout_gravity="center"/>
Apparently, this layout_gravity attribute causes the misbehavior. I think , this layout_gravity attribute tries to position the textView at the center of its parent (GridLayout) and interferes with the column 3 being resized to fill horizontal.
Related Topics
What's Oncreate(Bundle Savedinstancestate)
Webview Link Click Open Default Browser
Error Strictmode$Androidblockguardpolicy.Onnetwork
Android Broadcast Receiver Bluetooth Events Catching
How to Dismiss a Progress Bar Even If There Is No View to Populate in the Firebaselistadapter
Android: What Is Android.R.Id.Content Used For
Download Files and Store Them Locally with Phonegap/Jquery Mobile Android and iOS Apps
Android: Using Webview Outside an Activity Context
How to Browse Localhost on Android Device
How to Add Buttons at Top of Map Fragment API V2 Layout
Failed Binder Transaction When Putting an Bitmap Dynamically in a Widget
How to Create a Custom Notification Layout in Android