I have two tablets. I have run a test resolution app to get screen parameters. Thouse are the results.
1) Coby MID7042 7": low density, scale: 0.75, 120dpi, 480 x 764,
layout for large screen, drawable LDPI.
2) BQ Elcano 7": high density, scale: 1.5, 240dpi, 800 x 1208, layout
for large screen, drawable HDPI.
I have developed an android application that fits good on Coby screen, but in BQ the screen is cut in the right and in the bottom. That is, the screen is bigger than you can see on the screen. I think BQ screen is better and bigger than Coby, but I don't know why it doesn't fit the screen.
In my developed android app, the xml file for the screen is into res/layout folder. I always use sp and dp.
I have read about "supporting multiple screen" and so on, but in this case, I think BQ should show the screen at right fit using the same layout. But it doesn't.
Some one could help me about this issue? I don't know how could I solve this, because two tablets are large for layouts.
Thanks.
Edited. This is a layout that is cut in the right (the latest EditText is cut):
<LinearLayout
style="#style/GroupBox3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:baselineAligned="true" >
<LinearLayout
android:layout_width="130dp"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/TextView08"
style="#style/etstyle1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/Box" />
<EditText
android:id="#+id/eBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:layout_weight="1"
android:background="#drawable/roundedittext"
android:ems="10"
android:enabled="true"
android:gravity="right"
android:inputType="number|numberSigned|numberDecimal"
android:selectAllOnFocus="true" >
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<TextView
android:id="#+id/TextView06"
style="#style/etstyle1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/Uds" />
<EditText
android:id="#+id/euds"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="#drawable/roundedittext"
android:ems="10"
android:enabled="true"
android:gravity="right"
android:inputType="number|numberSigned|numberDecimal"
android:selectAllOnFocus="true" />
</LinearLayout>
<LinearLayout
android:layout_width="130dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical" >
<TextView
android:id="#+id/TextView09"
style="#style/etstyle1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|left"
android:paddingLeft="10dp"
android:text="#string/Tar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingBottom="5dp" >
<EditText
android:id="#+id/etar"
android:layout_width="60dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#drawable/roundedittext"
android:ems="10"
android:enabled="true"
android:gravity="center_vertical|right"
android:inputType="number"
android:selectAllOnFocus="true" />
<Button
android:id="#+id/btnTarifa"
style="#style/btnSer"
android:layout_width="50dp"
android:layout_height="40dp"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginTop="2dp"
android:text="#string/Inter" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="135dp"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:orientation="vertical" >
<TextView
android:id="#+id/etit"
style="#style/etstyle1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/price" />
<EditText
android:id="#+id/eprice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:background="#drawable/roundedittext"
android:ems="10"
android:enabled="true"
android:gravity="center_vertical|right"
android:inputType="numberDecimal"
android:selectAllOnFocus="true" />
</LinearLayout>
</LinearLayout>
DroidUsers answer is little bit confusing but method is effective...
look for more effective example:
http://www.vanteon.com/downloads/Scaling_Android_Apps_White_Paper.pdf
I have Used one approach where I design the Layout I wanted in a standard device, and store all dynamically apply all the layout dependent values(eg: padding, margin etc) using a seperate class. And by calculating a ratio with current device config to the standard i have stored,
I will give you my sample code. just go through it and find your way accordingly
public class ListViewDimensions
{
private Context _context;
private Configuration config;
private Display display;
private int _width;
private int _height;
private int _portOrLand;
private int _ORIENTATION_LAND=2;
private int _ORIENTATION_PORT=1;
private DisplayMetrics metrics;
private Dimension dimension;
//***************************** PORTRAIT ********************************\\
public int PlistLayoutPaddingLeft=16;
public int PlistLayoutPaddingRight=16;
public int PlistLayoutPaddingTop=16;
public int PlistLayoutPaddingBottom=15;
public int PsuraNoTextsize=10;
public int PsuraNameTextsize=20;
public int PayaNoTextsize=10;
public int PsuraNameWidth=180;
public int PpageNoTextsize=10;
public int PpageNoPadding=2;
public int PmalayalamFontsize;
public int ParabiFontsize;
public int PsuraHeadHeight=40;
//----------------------------------------------------------------------------------------
//***************************** LANDSCAPE IN TABS ********************************\\
public int LTlistLayoutPaddingLeft=35;
public int LTlistLayoutPaddingTop=30;
public int LTlistLayoutPaddingRight=35;
public int LTlistLayoutPaddingRightRightPage=35;
public int LTlistLayoutPaddingBottom=5;
public int LTpageNoTextsize=13;
public int LTpageNoPadding=0;
public int LTsuraNoTextsize=15;
public int LTsuraNameTextsize=25;
public int LTayaNoTextsize=15;
public int LTsuraNameWidth=375;
public int LTmalayalamFontsize;
public int LTarabiFontsize;
public int LTsuraHeadHeight=60;
//----------------------------------------------------------------------------------------
//***************************** LANDSCAPE IN NON-TABS ********************************\\
public int LlistLayoutPaddingLeft=21;
public int LlistLayoutPaddingRight=20;
public int LlistLayoutPaddingTop=16;
public int LlistLayoutPaddingBottom=17;
public int LsuraNoTextsize=10;
public int LsuraNameTextsize=20;
public int LayaNoTextsize=10;
public int LsuraNameWidth=330;
public int LpageNoTextsize=13;
public int LpageNoPadding=3;
public int LmalayalamFontsize;
public int LarabiFontsize;
public int LsuraHeadHeight=40;
//----------------------------------------------------------------------------------------
public float xScale;
private float yScale;
private double diagonalInches;
public class Dimension
{
public int listLayoutPaddingLeft;
public int listLayoutPaddingRight;
public int listLayoutPaddingTop;
public int listLayoutPaddingBottom;
public int pageNoTextsize;
public int pageNoPadding;
public int suraNoTextsize;
public int suraNameTextsize;
public int ayaNoTextsize;
public int suraNameWidth;
public int malayalamFontsize;
public int arabiFontsize;
public int suraHeadHeight;
public String bismi;
}
public ListViewDimensions.Dimension getDimensions(Context c)
{
PmalayalamFontsize=MyApp.appSettings.listMalayalamFontSize;
ParabiFontsize=MyApp.appSettings.listMalayalamFontSize;
LTmalayalamFontsize=MyApp.appSettings.listMalayalamFontSize*2;
LTarabiFontsize=MyApp.appSettings.listMalayalamFontSize*2;
LmalayalamFontsize=MyApp.appSettings.listMalayalamFontSize;
LarabiFontsize=MyApp.appSettings.listMalayalamFontSize;
dimension=new Dimension();
_context=c;
config =c.getResources().getConfiguration();
display=((Activity) c).getWindowManager().getDefaultDisplay();
_width = display.getWidth();
_height =display.getHeight();
if(config.orientation==config.ORIENTATION_LANDSCAPE)
_portOrLand=_ORIENTATION_LAND;
else
_portOrLand=_ORIENTATION_PORT;
metrics = new DisplayMetrics();
((Activity) c).getWindowManager().getDefaultDisplay().getMetrics(metrics);
int widthPixels = metrics.widthPixels;
int heightPixels = metrics.heightPixels;
int density=metrics.densityDpi;
float widthDpi = metrics.xdpi;
float heightDpi = metrics.ydpi;
if(density/widthDpi>1.2)
{
widthDpi=density;
heightDpi=density;
}
float widthInches = widthPixels / widthDpi;
float heightInches = heightPixels / heightDpi;
diagonalInches = Math.sqrt((widthInches * widthInches) + (heightInches * heightInches));
if(diagonalInches>=6.7 && _portOrLand==_ORIENTATION_LAND)
{
//TODO : for landscape in tabs
xScale = (_width/2)/(float)640 ;
yScale = _height/(float)752 ;
dimension.listLayoutPaddingLeft=LTlistLayoutPaddingLeft;
dimension.listLayoutPaddingRight=LTlistLayoutPaddingRight;
dimension.listLayoutPaddingTop=LTlistLayoutPaddingTop;
dimension.listLayoutPaddingBottom=LTlistLayoutPaddingBottom;
dimension.pageNoTextsize=LTpageNoTextsize;
dimension.pageNoPadding=LTpageNoPadding;
dimension.malayalamFontsize=LTmalayalamFontsize;
dimension.arabiFontsize=LTarabiFontsize;
dimension.suraNoTextsize=LTsuraNoTextsize;
dimension.suraNameTextsize=LTsuraNameTextsize;
dimension.ayaNoTextsize=LTayaNoTextsize;
dimension.suraNameWidth=LTsuraNameWidth;
dimension.suraHeadHeight=LTsuraHeadHeight;
dimension.bismi="&%$";
}
else if( _portOrLand==_ORIENTATION_PORT)
{
//TODO : for portrait in non-tab devices and tabs
xScale = _width/(float)320 ;
yScale = _height/(float)480 ;
dimension.listLayoutPaddingLeft=PlistLayoutPaddingLeft;
dimension.listLayoutPaddingRight=PlistLayoutPaddingRight;
dimension.listLayoutPaddingTop=PlistLayoutPaddingTop;
dimension.listLayoutPaddingBottom=PlistLayoutPaddingBottom;
dimension.pageNoTextsize=PpageNoTextsize;
dimension.pageNoPadding=PpageNoPadding; //TODO: check whether it is mandatory
dimension.malayalamFontsize=PmalayalamFontsize;
dimension.arabiFontsize=ParabiFontsize;
dimension.suraHeadHeight=PsuraHeadHeight;
dimension.suraNoTextsize=PsuraNoTextsize;
dimension.suraNameTextsize=PsuraNameTextsize;
dimension.ayaNoTextsize=PayaNoTextsize;
dimension.suraNameWidth=PsuraNameWidth;
if(diagonalInches<4.0)
dimension.bismi="รณ";
else
dimension.bismi="&%$";
}
else if(diagonalInches<6.7 && _portOrLand==_ORIENTATION_LAND)
{
//TODO : for land in non-tab devices
xScale = _height/(float)320 ;
yScale = _width/(float)480 ;
dimension.listLayoutPaddingLeft=LlistLayoutPaddingLeft;
dimension.listLayoutPaddingRight=LlistLayoutPaddingRight;
dimension.listLayoutPaddingTop=LlistLayoutPaddingTop;
dimension.listLayoutPaddingBottom=LlistLayoutPaddingBottom;
dimension.suraHeadHeight=LsuraHeadHeight;
dimension.suraNoTextsize=LsuraNoTextsize;
dimension.suraNameTextsize=LsuraNameTextsize;
dimension.ayaNoTextsize=LayaNoTextsize;
dimension.suraNameWidth=LsuraNameWidth;
dimension.pageNoTextsize=LpageNoTextsize;
dimension.pageNoPadding=LpageNoPadding; //TODO: check whether it is mandatory
dimension.malayalamFontsize=LmalayalamFontsize;
dimension.arabiFontsize=LarabiFontsize;
dimension.suraHeadHeight=LsuraHeadHeight;
dimension.bismi="&%$";
}
dimension.listLayoutPaddingLeft=(int) (dimension.listLayoutPaddingLeft*xScale);
dimension.listLayoutPaddingRight=(int) (dimension.listLayoutPaddingRight*xScale);
dimension.listLayoutPaddingTop=(int) (dimension.listLayoutPaddingTop*yScale);
dimension.listLayoutPaddingBottom=(int) (dimension.listLayoutPaddingBottom*yScale);
dimension.pageNoTextsize=(int) (dimension.pageNoTextsize*xScale);
dimension.pageNoPadding=(int) (dimension.pageNoPadding*yScale);
dimension.malayalamFontsize=(int) (dimension.malayalamFontsize*xScale);
dimension.arabiFontsize=(int) (dimension.arabiFontsize*xScale);
dimension.suraHeadHeight=(int) (dimension.suraHeadHeight*yScale);
dimension.suraNoTextsize=(int) (dimension.suraNoTextsize*xScale);
dimension.suraNameTextsize=(int) (dimension.suraNameTextsize*xScale);
dimension.ayaNoTextsize=(int) (dimension.ayaNoTextsize*xScale);
dimension.suraNameWidth=(int) (dimension.suraNameWidth*xScale);
return this.dimension;
}
public ListViewDimensions.Dimension updateFontSize()
{
if(diagonalInches>=6.7 && _portOrLand==_ORIENTATION_LAND)
{
xScale = (_width/2)/(float)640 ;
yScale = _height/(float)752 ;
dimension.malayalamFontsize=LTmalayalamFontsize;
dimension.arabiFontsize=LTarabiFontsize;
}
else if( _portOrLand==_ORIENTATION_PORT)
{
xScale = _width/(float)320 ;
yScale = _height/(float)480 ;
dimension.malayalamFontsize=PmalayalamFontsize;
dimension.arabiFontsize=ParabiFontsize;
}
else if(diagonalInches<6.7 && _portOrLand==_ORIENTATION_LAND)
{
xScale = _height/(float)320 ;
yScale = _width/(float)480 ;
dimension.malayalamFontsize=LmalayalamFontsize;
dimension.arabiFontsize=LarabiFontsize;
}
dimension.malayalamFontsize=(int) (dimension.malayalamFontsize*xScale);
dimension.arabiFontsize=(int) (dimension.arabiFontsize*xScale);
return dimension;
}
}
You should try to work with android:layout_weight instead of specifying your LinearLayout's android:layout_width="130dp". This way, the widths of your textviews and edittexts and what not can be set to fill_parent and Android will scale anything to the size of your screen, whatever the device you're working on might be.
With an exception for the linear layout where you have a new linearlayout for the edittext and a button, there you should use the weight attribute for this edittext and button again instead of their width parameters.
A slightly modified (I couldn't keep the style and text attributes when testing, for obvious reasons) example of how your xml would look:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:layout_weight="1"
android:baselineAligned="true" >
<LinearLayout
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1" >
<TextView
android:id="#+id/TextView08"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<EditText
android:id="#+id/eBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:ems="10"
android:enabled="true"
android:gravity="right"
android:inputType="number|numberSigned|numberDecimal"
android:selectAllOnFocus="true" >
</EditText>
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="1" >
<TextView
android:id="#+id/TextView06"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" />
<EditText
android:id="#+id/euds"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:ems="10"
android:enabled="true"
android:gravity="right"
android:inputType="number|numberSigned|numberDecimal"
android:selectAllOnFocus="true" />
</LinearLayout>
<LinearLayout
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:orientation="vertical"
android:layout_weight="1" >
<TextView
android:id="#+id/TextView09"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|left"
android:paddingLeft="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:paddingBottom="5dp" >
<EditText
android:id="#+id/etar"
android:layout_weight="0.5"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:ems="10"
android:enabled="true"
android:gravity="center_vertical|right"
android:inputType="number"
android:selectAllOnFocus="true" />
<Button
android:id="#+id/btnTarifa"
android:layout_weight="0.5"
android:layout_height="40dp"
android:layout_gravity="center_vertical|center_horizontal|center"
android:layout_marginTop="2dp" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_height="match_parent"
android:layout_marginLeft="5dp"
android:orientation="vertical" >
<TextView
android:id="#+id/etit"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" />
<EditText
android:id="#+id/eprice"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:ems="10"
android:enabled="true"
android:gravity="center_vertical|right"
android:inputType="numberDecimal"
android:selectAllOnFocus="true" />
</LinearLayout>
</LinearLayout>
After lot of sarch I haven't found why it happens, but a very quickly solution. I can scale all the application adding this code to the main activity:
public void changeDensity(float desiredDensity) {
//desiredDensity : ldpi = 0.75 (120dpi) , mdpi = 1 (160dpi), hdpi = 1.5 (240dpi), xhdpi = 2.0 (320dpi)
DisplayMetrics metrics = getResources().getDisplayMetrics();
metrics.density = desiredDensity;
metrics.xdpi = desiredDensity * 160;
metrics.ydpi = desiredDensity * 160;
metrics.densityDpi = (int) (desiredDensity * 160);
getResources().updateConfiguration(null, null);
}
Calling this function on creating main activity, with 1.25f as desiredDensity, the application is scaled to fit the right dimension. I know this isn't the rigth way. I should change all layout, but I can't do it with this device because both use the same layout (large) and then, perhaps, I should use w as parameter in res/layout. Briefly, scaling resolve the problem.
From this: https://stackoverflow.com/a/12077236/1616700
Related
Our app looks like this on Huawei 8510, and android version is 2.3.5.
This screenshot came from our customer. We disabled screenshot on app, so our customer used another phone to take screenshot.
How is it possible?
this is layout code that i think there is no problem.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="0px"
android:layout_height="0px"
android:focusable="true"
android:focusableInTouchMode="true" />
<com.asdasd.asdasd.controls.CMScrollView
android:id="#+id/scvAgreement"
style="#style/pm_ContentStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:fadingEdge="none"
android:paddingLeft="0dp"
android:paddingRight="0dp">
<TextView
android:id="#+id/tvAgreement"
style="#style/pm_TextStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="#dimen/pm_content_padding_left"
android:layout_marginRight="#dimen/pm_content_padding_right"
android:gravity="center"
android:text=""
android:typeface="monospace" />
</com.asdasd.asdasd.controls.CMScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal">
<Button
style="#style/pm_ButtonStyle_Standart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/selector_btn_black"
android:gravity="center"
android:onClick="onBtnNegativeClicked"
android:text="#string/pgPrivacy_btnNotAccept"
android:textSize="#dimen/pm_middle_text_size"
android:singleLine="false"/>
<Button
android:id="#+id/btnSendAgreement"
style="#style/pm_ButtonStyle_Standart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/pm_button_margin_left"
android:layout_weight="1"
android:background="#drawable/selector_btn_black"
android:enabled="false"
android:gravity="center"
android:onClick="onBtnSendAgreement"
android:text="#string/pgPrivacy_btnSendAgreement"
android:textSize="#dimen/pm_middle_text_size"
android:singleLine="false"/>
<Button
android:id="#+id/btnPositive"
style="#style/pm_ButtonStyle_Standart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/pm_button_margin_left"
android:layout_weight="1"
android:background="#drawable/selector_btn_orange"
android:enabled="false"
android:gravity="center"
android:onClick="onBtnPositiveClicked"
android:text="#string/pgPrivacy_btnAccept"
android:textSize="#dimen/pm_middle_text_size"
android:singleLine="false"/>
</LinearLayout>
And also, our custom listView
public class CMScrollView extends ScrollView {
public static final String LOG_TAG = "com.asdasd.asdasd.controls.CMScrollView";
private OnScrollViewReachedToEnd onScrollViewReachedToEnd;
public CMScrollView(Context context, AttributeSet st) {
super(context, st);
}
public OnScrollViewReachedToEnd getOnScrollViewReachedToEnd() {
return onScrollViewReachedToEnd;
}
public void setOnScrollViewReachedToEnd(OnScrollViewReachedToEnd onScrollViewReachedToEnd) {
this.onScrollViewReachedToEnd = onScrollViewReachedToEnd;
}
#Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
View view = (View) getChildAt(getChildCount() - 1);
int diff = (view.getBottom() - (getHeight() + getScrollY() + view.getTop()));// Calculate the scrolldiff
if (diff == 0) { // if diff is zero, then the bottom has been reached
if (ApplicationController.DEBUGMODE)
Log.d(CMScrollView.LOG_TAG, "MyScrollView: Bottom has been reached");
if (onScrollViewReachedToEnd != null) {
onScrollViewReachedToEnd.onReachedToEnd(this);
}
}
super.onScrollChanged(l, t, oldl, oldt);
}
public interface OnScrollViewReachedToEnd {
void onReachedToEnd(IngScrollView scrollView);
}}
on AndroidManifest GL Version:
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
One of my friend found a promising Answer after a lot of time & search.
The same kind of issue (Flickering in GUI) is solved by simply Turn OFF the Developer Options
Because if you enable hardware overlay , GPU will be takes care of UI & sometimes there will be some conflict in GUI rendering.
my problem is this, using TextViewEx (https://github.com/bluejamesbond/TextJustify-Android) class texts to justify my android application works fine until the text over a carriage return appear \ n, when this happens the text is cut losing asin several lines of this, I need a solution to justify text without html injection, to change the font size if the application is open from mobile or from a tablet, if know what the problem is and can help me I thank you.
I will put the code in my application:
code xml:
<ScrollView
android:id="#+id/scrollView1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="25dp"
android:layout_marginRight="25dp"
android:layout_marginTop="45dp"
android:layout_below="#+id/view1" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="50dp"
android:background="#drawable/background_border" >
<TextView
android:id="#+id/txt_fecha_promociones"
style="#style/fechaDentroxlarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:text="24/05/2014" />
<TextView
android:id="#+id/txt_titulo_promociones"
style="#style/tituloDentroxlarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_below="#+id/comparte"
android:text="Titulo" />
**<com.xxxxx.tools.TextViewEx
android:id="#+id/txt_noticia_promociones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/img_promo"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp"
android:textSize="30sp"
android:text="noticia"
android:textColor="#color/txtBlanco" />**
<ImageView
android:id="#+id/comparte"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_marginTop="15dp"
android:layout_toLeftOf="#+id/txt_fecha_promociones"
android:onClick="compartir"
android:src="#drawable/share_icon_white" />
<ImageView
android:id="#+id/img_promo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/txt_titulo_promociones"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:src="#drawable/promo1" />
</RelativeLayout>
</ScrollView>
code java:
public class xxxxx extends NavegacionActivity {
TextView txt_servicio;
TextViewEx txt_descripcion;
TextView prueba;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_servicios_dentro);
setBehindContentView(R.layout.menu);
getSlidingMenu().setBehindOffset(100);
txt_servicio = (TextView) findViewById(R.id.txt_titulo_servicio);
txt_descripcion = (TextViewEx) findViewById(R.id.txt_descripcion_servicios);
Intent i = getIntent();
txt_servicio.setText(i.getStringExtra("servicio"));
txt_descripcion.setText(i.getStringExtra("descripcion"),true);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
Intent i = new Intent(this, xxxx.class);
startActivity(i);
this.finish();
}
}
Import the classes TextJustifyUtils.java and TextViewEx.java in the root of your project
In your XML Replace TextView --->> com.example.myaplication.TextViewEx
Just go to TextViewEx.java and change to this code:
#Override
public void setPadding(int left, int top, int right, int bottom) {
DisplayMetrics metrics = getContext().getResources()
.getDisplayMetrics();
super.setPadding((int) ((left + (metrics.density * 10))), top,
(int) (right + (metrics.density * 10)),
(int) (bottom + (metrics.heightPixels * 1.5)));
Log.i("Log", "metrics : " + metrics);
}
I have list of button in bottom of the page which is in horizontal listview, i want to show only 4 row in listview, when screen become bigger it's item size should also become bigger so only 4 item shows.
for example
here you can see that after increasing size of width it's related horizontal listview's listitem also increasing
is it possible? if possible than can any body suggest me how we can handle it ?
Create one custom layout class like below..
public class MyLinearLayout extends LinearLayout {
public MyLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyLinearLayout(Context context) {
super(context);
}
public void setLayoutParams(int width) {
LayoutParams params = new LayoutParams(width / 4,
LayoutParams.WRAP_CONTENT);
this.setLayoutParams(params);
}
#Override
public void setLayoutParams(android.view.ViewGroup.LayoutParams params) {
super.setLayoutParams(params);
}
}
put this horizontal scrollview in your xml file
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<com.example.widget.MyLinearLayout
android:id="#+id/llMainHome"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/orange_bg"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/home" />
</com.example.widget.MyLinearLayout>
<com.example.widget.MyLinearLayout
android:id="#+id/llHomeSearch"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/green_bg"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/search" />
</com.example.widget.MyLinearLayout>
<com.example.widget.MyLinearLayout
android:id="#+id/llHomeFavorite"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/green_bg"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/favorite" />
</com.example.widget.MyLinearLayout>
<com.example.widget.MyLinearLayout
android:id="#+id/llHomeGrocery"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/green_bg"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/make_juice" />
</com.example.widget.MyLinearLayout>
<com.example.widget.MyLinearLayout
android:id="#+id/llHomeSettings"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/green_bg"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/settings" />
</com.example.widget.MyLinearLayout>
</LinearLayout>
</HorizontalScrollView>
And in your activity class file declare
private MyLinearLayout llHomeSearch, llHomeFavorite,
llHomeGrocery, llHomeSettings,llMainHome;
oncreate Method code is
llHomeFavorite = (MyLinearLayout) findViewById(R.id.llHomeFavorite);
llHomeFavorite.setOnClickListener(this);
llMainHome = (MyLinearLayout) findViewById(R.id.llMainHome);
llMainHome.setOnClickListener(this);
llHomeSearch = (MyLinearLayout) findViewById(R.id.llHomeSearch);
llHomeSearch.setOnClickListener(this);
llHomeGrocery = (MyLinearLayout) findViewById(R.id.llHomeGrocery);
llHomeGrocery.setOnClickListener(this);
llHomeSettings = (MyLinearLayout) findViewById(R.id.llHomeSettings);
llHomeSettings.setOnClickListener(this);
Display display = getWindowManager().getDefaultDisplay();
Point size = getDisplaySize(display);
int width = size.x;
llMainHome.setLayoutParams(width);
llHomeFavorite.setLayoutParams(width);
llHomeGrocery.setLayoutParams(width);
llHomeSearch.setLayoutParams(width);
llHomeSettings.setLayoutParams(width);
and getDisplaysize method is
#SuppressLint("NewApi")
private static Point getDisplaySize(final Display display) {
final Point point = new Point();
try {
display.getSize(point);
} catch (java.lang.NoSuchMethodError ignore) { // Older device
point.x = display.getWidth();
point.y = display.getHeight();
}
return point;
}
here you go..it will work nice..
there is no need to take horizontal list view if you have fix number of item in your tab bar..
Maybe try to get Screen width and then set List's element to 1/4 of that width?
Something like in onResume/onCreate
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x; //remember that width
And in getView
LayoutParams params=new LayoutParams(width/4, -1);
element.setLayoutParams(params)
My problem is very similar to How to get a layout where one text can grow and ellipsize, but not gobble up the other elements on the layout, but read on below why I can't use TableLayouts as proposed there.
I'm trying to create a listview row that basically looks like this:
| TextView | View 1 | View 2 |
All views contain variable width elements. The TextView has ellipsize="end" set. View 1 should align left of the TextView, while View 2 should align to the right of the screen. So, normally, there would be whitespace between View 1 and View 2. As the text in the TextView grows longer, the TextView should grow, pushing View 1 to the right until there is no more whitespace left. Then, ellipsize should kick in, cutting of the text in TextView and appending an ellipsis ("...") at the end.
So, the result should look something like this:
+----------------------------------------+
| short text [view1] [view2] |
+----------------------------------------+
| long text with ell ... [view1] [view2] |
+----------------------------------------+
I've tried:
TableLayouts, but they seem to make scrolling extremely slow on some devices.
RelativeLayouts, but I either had overlapping views, or view1 or view2 disappeared completely.
GridLayouts, but the TextView always grows until it takes up the whole width of the screen, thus pushing view1 and view2 out of the screen.
This is the GridLayout I tried:
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_gravity="left|fill_horizontal"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis" />
<TextView
android:layout_gravity="left"
android:text="(view1)" />
<TextView
android:layout_gravity="right"
android:text="(view2)" />
</GridLayout>
View 1 and View 2 are not really TextViews, I just used them in the example to simplify things.
Is there any way to achieve this without using TableLayouts?
EDIT:
As requested, here is my attempt at solving this with a RelativeLayout. The TextView takes up the full width of the screen in this case, so neither view1 nor view2 are visible.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/rl0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis" />
<TextView
android:id="#+id/rl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/rl0"
android:layout_marginLeft="10dp"
android:text="(view1)" />
<TextView
android:id="#+id/rl2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/rl1"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
android:text="(view2)" />
</RelativeLayout>
I seem to have found a potential solution to prevent a TextView in GridLayout from growing unboundedly and pushing out other views. Not sure if this has been documented before.
You need to use fill layout_gravity and set an arbitrary layout_width or width on the long TextView in need of ellipsizing.
android:layout_gravity="fill"
android:layout_width="1dp"
Works for both GridLayout and android.support.v7.widget.GridLayout
I'm a big fan of LinearLayouts, so here's my suggestion using those:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_weight="1" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="(view1)" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="(view2)" />
</LinearLayout>
I will suggest you to play with layout_weight property of your widget
Example:
<LinearLayout 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"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="10">
<LinearLayout
android:id="#+id/ll_twoViewContainer"
android:layout_weight="8"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/rl0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text" />
<TextView
android:id="#+id/rl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#id/rl0"
android:layout_weight="1"
android:minWidth="120dp"
android:text="(view1)" />
</LinearLayout>
<TextView
android:id="#+id/rl2"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/rl1"
android:layout_alignParentRight="true"
android:layout_marginLeft="10dp"
android:text="(view2)" />
</LinearLayout>
</LinearLayout>
finally your layout will look like as follow:
+----------------------------------------+
| short text [view1] [view2] |
+----------------------------------------+
| long text with ell ... [view1] [view2] |
+----------------------------------------+
I think you should create custom layout for your purpose. I don't know how to do this using only default layouts/view and make it work for all cases.
The trick which worked for me was to use maxWidth to restrict the width of the first view. You need to do it with Java, here is the basic logic:
firstView.setMaxWidth(parentView.getWidth() - view2.getWidth() - view1.getWidth() - padding * 2);
Not pretty, but it works.
I think there's just a small issue on the layout that could be solved, anchoring the view3 to the right and start from there to force the view to have a delimited area (hence being able to properly set the ellipse):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/rl3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="(view2)" />
<TextView
android:id="#+id/rl2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#id/rl3"
android:text="(view1)" />
<TextView
android:id="#+id/rl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#id/rl2"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis" />
</RelativeLayout>
Hope this helps...
Regards!
Try this
<?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="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="(view1)"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="(view2)"/>
</LinearLayout>
</LinearLayout>
Currently, all views are centered. You can change android:gravity property to meet your needs. For example, you may want to align view1 right and view2 left in which case last two LinearLayouts would look something like (with 5dp margin on the right and left respectively):
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|right">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_marginRight="5dp"
android:text="(view1)"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center|left">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginLeft="5dp"
android:text="(view2)"/>
</LinearLayout>
I find my solution for the case number 2 (the one with a long text):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:weightSum="3" >
<TextView
android:id="#+id/rl0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="3"
android:ellipsize="end"
android:singleLine="true"
android:text="Long text to demonstrate problem with TextView in GridLayout taking up too much space despite ellipsis" />
<TextView
android:id="#+id/rl1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="(view1)" />
<TextView
android:id="#+id/rl2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="(view2)" />
</LinearLayout>
The real problem is case one, and i didn't try a lot of things for this. I hope it helps (and if i have more spare time, i will try to achieve first one!).
If the views on the right get pushed over by the text by design, you might as well use a ListView instead of a GridView.
You would just need to make the base of the list item layout a RelativeLayout, and set rules like this:
You can set the two views on the right to alignParentRight (using android:layout_alignParentLeft="true"), but make sure the first view stays to the left of the second so it will push itself to the left as the views stretch out.
You can make the TextView on the left align to the left, but stay to the left of the first view (using android:layout_toLeftOf="#+id/viewId") so it won't overlap with the views.
Try using Layout Weight
<TableRow
android:id="#+id/tableRow3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/tableRow2"
android:layout_alignParentBottom="true"
android:gravity="center"
android:weightSum="10"
android:background="#android:color/black" >
<TextView
android:id="#+id/txtInningsTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center"
android:text="0"
android:textColor="#android:color/white" />
<TextView
android:id="#+id/txtTeamOneTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:gravity="center"
android:text="0"
android:textColor="#android:color/white" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2" />
<TextView
android:id="#+id/txtTeamTwoTotal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2.5"
android:gravity="center"
android:text="0"
android:textColor="#android:color/white" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2" />
<TextView
android:id="#+id/txtGrandTotal"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3"
android:gravity="center"
android:text="0"
android:textColor="#android:color/white" />
</TableRow>
Here i have taken table row in which there is layout weight sum which is of 10 means that it is 100% width of its parent. and in all its child views i have set width to 0Dp and given weight to 1 or 2. so that it will take up to that percent of total 10. so the layout will be adjusted accordingly screen and also there will be no issue of overlapping.
If i have understood you correctly then this is the answer you wanted.
Hope it Helps!
First, you must layout [view 2] to parent Right;
Again, you reference the reference to the last two layout!
<Relativelayout android:layout_width="match_parent"
android:layout_height="wrap_content"
<TextView
android:id="#+id/view2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toLeft="#id/view2"
android:gravity="left">
<TextView
android:id="#+id/shortORlongtTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/view1"
android:ellipsize="end"
android:maxLines="1"
android:textSize="18dp"/>
<TextView
android:id="#+id/view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
/>
</RelativeLayout>
I had the same problem with the grid layout. what i did is given a fixed width for the text view and also given layout_columnWeight property for each text view then the issue was fixed ,hope it helps ...
<TextView
android:id="#+id/txtName"
style="#style/MyDetailTitle"
android:layout_width="#dimen/detail_length"
android:layout_height="wrap_content"
android:text="#string/app_name"
app:layout_column="3"
app:layout_columnWeight="1"
app:layout_gravity="start"
app:layout_row="1" />
GridLayout is like the other things on Android : flawed by design.
You will need a custom Layout, the following example will allow you to layout things like:
[ label | short text | very long label | short text ]
[ long label | very very very | label | very long text ]
[ | long text | | ]
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;
public class TwoColumsGridLayout extends ViewGroup {
private final List<List<View>> rows;
private int rowCount = 0;
private int firstColumWidth;
private int secondColumWidth;
private int thirdColumWidth;
private int fourthColumnWidth;
private final List<Integer> rowHeights = new ArrayList<>();
private final List<List<Integer>> cellHeights = new ArrayList<>();
private final List<Integer> firstCellsWidths = new ArrayList<>(4);
private final List<Integer> thirdCellsWidths = new ArrayList<>(4);
public TwoColumsGridLayout(Context context, int rowCount) {
super(context);
rows = new ArrayList<>(rowCount);
}
public void add(Context ctx, TextView l1, View t1, TextView l2, View t2) {
final List<View> row = new ArrayList<>(4);
row.add(l1);
row.add(t1);
row.add(l2);
row.add(t2);
rows.add(row);
this.addView(l1);
this.addView(t1);
if (l2 != null)
this.addView(l2);
if (t2 != null)
this.addView(t2);
this.rowCount++;
}
public int getRowCount() {
return rowCount;
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int curLeft = 0;
int curBottom;
int curRight;
int curTop = 0;
int i = 0;
for (List<View> row : rows) {
final int rowHeight = this.rowHeights.get(i);
final List<Integer> rowCellHeights = this.cellHeights.get(i);
final View v0 = row.get(0);
curLeft = 0;
curRight = curLeft + this.firstColumWidth;
if (v0 != null) {
curBottom = curTop + rowCellHeights.get(0);
// Right align
v0.layout(curLeft + this.firstColumWidth - this.firstCellsWidths.get(i), curTop + 7, curRight, curBottom + 7);
}
//
final View v1 = row.get(1);
curLeft += this.firstColumWidth;
curRight = curLeft + this.secondColumWidth;
if (v1 != null) {
curBottom = curTop + rowCellHeights.get(1);
v1.layout(curLeft, curTop, curRight, curBottom);
}
//
final View v2 = row.get(2);
curLeft += this.secondColumWidth;
curRight = curLeft + this.thirdColumWidth;
if (v2 != null) {
curBottom = curTop + rowCellHeights.get(2);
// Right align
v2.layout(curLeft + this.thirdColumWidth - this.thirdCellsWidths.get(i), curTop + 7, curRight, curBottom + 7);
}
//
final View v3 = row.get(3);
curLeft += this.thirdColumWidth;
curRight = curLeft + this.fourthColumnWidth;
if (v3 != null) {
curBottom = curTop + rowCellHeights.get(3);
v3.layout(curLeft, curTop, curRight, curBottom);
}
curTop += rowHeight;
i++;
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
// Compute first column width
firstColumWidth = 0;
for (List<View> row : rows) {
final View v = row.get(0);
if (v != null) {
v.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
measureChild(v, widthMeasureSpec, heightMeasureSpec);
final int w = v.getMeasuredWidth();
if (firstColumWidth < w) {
firstColumWidth = w;
}
}
}
// Compute third column width
thirdColumWidth = 0;
for (List<View> row : rows) {
final View v = row.get(2);
if (v != null) {
v.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
measureChild(v, widthMeasureSpec, heightMeasureSpec);
final int w = v.getMeasuredWidth();
if (thirdColumWidth < w) {
thirdColumWidth = w;
}
}
}
secondColumWidth = (parentWidth - firstColumWidth - thirdColumWidth) / 2;
fourthColumnWidth = parentWidth - firstColumWidth - secondColumWidth - thirdColumWidth;
// Clear
this.rowHeights.clear();
this.cellHeights.clear();
this.firstCellsWidths.clear();
this.thirdCellsWidths.clear();
// Compute heights
int height = 0;
for (List<View> row : rows) {
final ArrayList<Integer> rowCellHeights = new ArrayList<>(4);
cellHeights.add(rowCellHeights);
int rowHeight = 0;
// First column
final View v0 = row.get(0);
if (v0 != null) {
int h = v0.getMeasuredHeight();
this.firstCellsWidths.add(v0.getMeasuredWidth());
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
} else {
this.firstCellsWidths.add(0);
}
// Second column
final View v1 = row.get(1);
if (v1 != null) {
v1.setLayoutParams(new ViewGroup.LayoutParams(secondColumWidth, LayoutParams.WRAP_CONTENT));
measureChild(v1, widthMeasureSpec, heightMeasureSpec);
int h = v1.getMeasuredHeight();
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
}
// Third column
final View v2 = row.get(2);
if (v2 != null) {
int h = v2.getMeasuredHeight();
this.thirdCellsWidths.add(v2.getMeasuredWidth());
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
} else {
this.thirdCellsWidths.add(0);
}
// Fourth column
final View v3 = row.get(3);
if (v3 != null) {
v3.setLayoutParams(new ViewGroup.LayoutParams(fourthColumnWidth, LayoutParams.WRAP_CONTENT));
measureChild(v3, widthMeasureSpec, heightMeasureSpec);
int h = v3.getMeasuredHeight();
rowCellHeights.add(h);
if (rowHeight < h) {
rowHeight = h;
}
}
height += rowHeight;
this.rowHeights.add(rowHeight);
}
setMeasuredDimension(parentWidth, height);
}
}
Have fun.
TableLayout will give expected behavior. May cause performance issue as question's author mention, but works great with simple layout. If the row is repeatable and scrollable, consider use gridview instead
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:shrinkColumns="0"
>
<TableRow>
<TextView/>
<View1/>
<View2/>
</TableRow>
</TableLayout>
I am trying to implement the layout below:
I guess GridLayout is suitable for my needs but after 2 hours of struggle I couldn't create even a similar layout.. The layout is resizing itself wrongly, it exceeds the screen of the phone and it also does not span the specified rows and columns.
Here I selected a button so you can see how it exceeds the boundaries:
and here is the associated xml code: https://gist.github.com/2834492
I have reached a similar layout with nested linearlayouts but it's not possible to properly resize it for different screen sizes.
UPDATE - approximate LinearLayout implementation:
The XML code: https://gist.github.com/cdoger/2835887
However, the problem is it does not resize itself properly here some screenshots with different screen configurations:
TLDR: Can someone show me a heterogeneous layout implementation with GridLayout like in the first picture?
The issue you are facing is due to inappropriate use of the GridLayout. The GridLayout is made to show its children in a grid and you are trying to override that without extending the GridLayout. While what you want may be accomplished in code (utilizing numcolumns and columnsize), it will not be useful for multiple screen sizes without a heck of a lot of code.
The only adequate solution that won't require a ton of hacking is judicious use of both LinearLayout and RelativeLayout. LinearLayout should not be used exclusively as it is made to drop items in a line (horizontally or vertically only). This becomes especially apparent when you try and do the bottom four buttons. While the buttons above may be done with LinearLayout with very little effort, RelativeLayout is what you need for the bottom four buttons.
Note:
RelativeLayout can be a little bit tricksy for those with little experience using them. Some pitfalls include: children overlapping, children moving off the screen, height and width rendering improperly applied. If you would like an example, let me know and I will edit my answer.
Final Note:
I'm all for utilizing the current framework objects in unique ways, and genuinely prefer to provide the requested solution. The solution, however, is not viable given the constraints of the question.
(Revision) Solution 1
After some careful thought last night, this may be accomplished with a pure LinearLayout. While I do not like this solution, it should be multi-screen friendly and requires no tooling around from me. Caution should be used with too many LinearLayouts, as according to Google's developers, it can result in slow loading UIs due to the layout_weight property. A second solution utilizing RelativeLayout will be provided when I return home. Now Tested This provides the desired layout parameters on all screen-sizes and orientations.
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<Button
android:id="#+id/Button01"
android:layout_width="0"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/Button02"
android:layout_width="0"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1.00"
android:orientation="horizontal">
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button5"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="#+id/button6"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:text="Button" />
<Button
android:id="#+id/button7"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Solution 1 Explanation
The key to LinearLayouts is to define your imperatives as separate Layouts and nest the others in them. As you apply constraints to more dimensions, more LinearLayouts must be added to encapsulate the others. For yours, it was crucial to have two more parents in order to maintain the proportion. A great indicator of when you should add another level is when you have to utilize layout_weight using anything other than an integer value. It simply becomes to hard to calculate properly. From there it was relatively simple to break it into columns.
Solution 2 (Failed)
While I was able to achieve desirable results utilizing RelativeLayout and "struts", I could only do so with layouts that were multiples of 2 buttons in height. Such a trick would be awesome as the levels of layout are greatly reduced, so I will work on a pure XML solution and post the answer here if and when I achieve it. In the meantime, the LinearLayout above should suit your needs perfectly.
I read this thread and realised that I wanted a flatter solution than those with linear layout. After some research I ended up making my own layout. It is inspired by a GridLayout but differs a bit.
Please note that if you are going to copy-paste the code you'll need to change package names in some places.
This layout has 4 layout parameters that children use to position themselves.These are layout_left, layout_top, layout_right, layout_bottom. The ICGridLayout itself has two attributes: layout_spacing and columns.
Columns tells the layout how many columns you want it to contain. It will then calculate the size of a cell with the same height as width. Which will be the layouts width/columns.
The spacing is the amount of space you want between each child.
The layout_left|top|right|bottom attributes are the coordinates for each side. The layout does no calculations in order to avoid collision or anything. It just puts the children where they want to be.
If you'd like to have smaller squares you just have to increase the columns attribute.
Keep in mind that this is a quick prototype, I will continue working on it and when I feel that it's ready I'll upload it to Github and put a comment here.
All of my code below should produce the following result:
*****EDIT*****
Added the call to measure for the children, forgot that the first time around.
END EDIT
ICGridLayout.java:
package com.risch.evertsson.iclib.layout;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import com.risch.evertsson.iclib.R;
/**
* Created by johanrisch on 6/13/13.
*/
public class ICGridLayout extends ViewGroup {
private int mColumns = 4;
private float mSpacing;
public ICGridLayout(Context context) {
super(context);
}
public ICGridLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ICGridLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
private void init(AttributeSet attrs) {
TypedArray a = getContext().obtainStyledAttributes(
attrs,
R.styleable.ICGridLayout_Layout);
this.mColumns = a.getInt(R.styleable.ICGridLayout_Layout_columns, 3);
this.mSpacing = a.getDimension(R.styleable.ICGridLayout_Layout_layout_spacing, 0);
a.recycle();
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (changed) {
int width = (int) (r - l);
int side = width / mColumns;
int children = getChildCount();
View child = null;
for (int i = 0; i < children; i++) {
child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
int left = (int) (lp.left * side + mSpacing / 2);
int right = (int) (lp.right * side - mSpacing / 2);
int top = (int) (lp.top * side + mSpacing / 2);
int bottom = (int) (lp.bottom * side - mSpacing / 2);
child.layout(left, top, right, bottom);
}
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureVertical(widthMeasureSpec, heightMeasureSpec);
}
private void measureVertical(int widthMeasureSpec, int heightMeasureSpec) {
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = 0;
int height = 0;
if (widthMode == MeasureSpec.AT_MOST || widthMode == MeasureSpec.EXACTLY) {
width = MeasureSpec.getSize(widthMeasureSpec);
} else {
throw new RuntimeException("widthMeasureSpec must be AT_MOST or " +
"EXACTLY not UNSPECIFIED when orientation == VERTICAL");
}
View child = null;
int row = 0;
int side = width / mColumns;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
child = getChildAt(i);
LayoutParams lp = (LayoutParams) child.getLayoutParams();
if (lp.bottom > row) {
row = lp.bottom;
}
int childHeight = (lp.bottom - lp.top)*side;
int childWidth = (lp.right-lp.left)*side;
int heightSpec = MeasureSpec.makeMeasureSpec(childHeight, LayoutParams.MATCH_PARENT);
int widthSpec = MeasureSpec.makeMeasureSpec(childWidth, LayoutParams.MATCH_PARENT);
child.measure(widthSpec, heightSpec);
}
height = row * side;
// TODO: Figure out a good way to use the heightMeasureSpec...
setMeasuredDimension(width, height);
}
#Override
public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new ICGridLayout.LayoutParams(getContext(), attrs);
}
#Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof ICGridLayout.LayoutParams;
}
#Override
protected ViewGroup.LayoutParams
generateLayoutParams(ViewGroup.LayoutParams p) {
return new ICGridLayout.LayoutParams(p);
}
#Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new LayoutParams();
}
public static class LayoutParams extends ViewGroup.MarginLayoutParams {
int right = 1;
int bottom = 1;
int top = 0;
int left = 0;
int width = -1;
int height = -1;
public LayoutParams() {
super(MATCH_PARENT, MATCH_PARENT);
top = 0;
left = 1;
}
public LayoutParams(int width, int height) {
super(width, height);
top = 0;
left = 1;
}
public LayoutParams(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(
attrs,
R.styleable.ICGridLayout_Layout);
left = a.getInt(R.styleable.ICGridLayout_Layout_layout_left, 0);
top = a.getInt(R.styleable.ICGridLayout_Layout_layout_top, 0);
right = a.getInt(R.styleable.ICGridLayout_Layout_layout_right, left + 1);
bottom = a.getInt(R.styleable.ICGridLayout_Layout_layout_bottom, top + 1);
height = a.getInt(R.styleable.ICGridLayout_Layout_layout_row_span, -1);
width = a.getInt(R.styleable.ICGridLayout_Layout_layout_col_span, -1);
if (height != -1) {
bottom = top + height;
}
if (width != -1) {
right = left + width;
}
a.recycle();
}
public LayoutParams(ViewGroup.LayoutParams params) {
super(params);
}
}
}
ICGridLayout.java is pretty straight forward. It takes the values provided by the children and lays them out.
attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ICGridLayout_Layout">
<attr name="columns" format="integer"/>
<attr name="layout_left" format="integer"/>
<attr name="layout_top" format="integer"/>
<attr name="layout_right" format="integer"/>
<attr name="layout_bottom" format="integer"/>
<attr name="layout_col_span" format="integer"/>
<attr name="layout_row_span" format="integer"/>
<attr name="layout_spacing" format="dimension"/>
</declare-styleable>
</resources>
example_layout.xml:
<?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/com.rischit.projectlogger"
android:id="#+id/scroller"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.risch.evertsson.iclib.layout.ICGridLayout
android:id="#+id/ICGridLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_spacing="4dp"
app:columns="4" >
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="1"
app:layout_left="0"
app:layout_right="4"
app:layout_top="0"
android:background="#ff0000"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="3"
app:layout_left="3"
app:layout_right="4"
app:layout_top="1"
android:background="#00ff00"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="4"
app:layout_left="0"
app:layout_right="3"
app:layout_top="1"
android:background="#0000ff"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="4"
app:layout_left="3"
app:layout_right="4"
app:layout_top="3"
android:background="#ffff00"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="6"
app:layout_left="0"
app:layout_right="1"
app:layout_top="4"
android:background="#ff00ff"
android:text="TextView" />
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_bottom="6"
app:layout_left="1"
app:layout_right="4"
app:layout_top="4"
android:background="#ffffff"
android:text="TextView" />
</com.risch.evertsson.iclib.layout.ICGridLayout>
</ScrollView>
-- Johan Risch
P.S
This is my first long answer, I've tried to do it in a correct way. If I've failed please tell me without flaming :)
D.S
Like this ?
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.54" >
<Button
android:id="#+id/Button01"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.00"
android:text="Button" />
<Button
android:id="#+id/Button02"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1.00"
android:text="Button" />
</LinearLayout>
<Button
android:id="#+id/button3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="99dp" >
<Button
android:id="#+id/button1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
<Button
android:id="#+id/button2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="#+id/button4"
android:layout_width="match_parent"
android:layout_height="152dp"
android:text="Button" />
<Button
android:id="#+id/button5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:id="#+id/button6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
<Button
android:id="#+id/button7"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Button" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
As many have said, nested linear layouts seem the only way to win here. Some of the solutions have not used the layout parameters in the most flexible manner. Code below seeks to do that, and in a way that's robust with aspect ratio changes. Details are in the comments.
<?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" >
<!-- First row. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Equal weights cause two columns of equal width. -->
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="A" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="B" />
</LinearLayout>
<!-- Second row. -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="C" />
<!-- Third row. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<!-- Equal weights cause two columns of equal width. -->
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="D" />
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="E" />
</LinearLayout>
<!-- Uneven fourth and fifth rows. -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:baselineAligned="false" >
<!-- Left column. Equal weight with right column gives them equal width. -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<!--
The use of weights below assigns all extra space to G. There
are other choices. LinearLayout computes sizes along its
axis as given, then divides the remaining extra space using
weights. If a component doesn't have a weight, it keeps
the specified size exactly.
-->
<!-- Fill width of layout and use wrap height (because there's no weight). -->
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="F" />
<!-- Fill width of layout and put all the extra space here. -->
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="G" />
</LinearLayout>
<!-- Right column. Equal weight with left column gives them equal width. -->
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<!-- Same as above except top button gets all the extra space. -->
<Button
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="H" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
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:
Embed your GridLayout in LinearLayout as below and try it worked for me.
<?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="horizontal" >
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnCount="2" >
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="start|end"
android:layout_row="0"
android:text="ASDFASDF" />
<Button
android:layout_column="1"
android:layout_gravity="start|end"
android:layout_row="0"
android:text="SDAVDFBDFB" />
<Button
android:layout_column="0"
android:layout_columnSpan="2"
android:layout_gravity="fill|center"
android:layout_row="1"
android:text="ASDVADFBFDAFEW" />
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="2"
android:text="FWEA AWFWEA" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill"
android:layout_row="2"
android:text="BERWEfasf" />
<Button
android:layout_width="94dp"
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="3"
android:text="SDFVBFAEVSAD" />
<Button
android:layout_column="0"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="4"
android:layout_rowSpan="2"
android:text="GVBAERWEFSD" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="3"
android:layout_rowSpan="2"
android:text="VSDFAVE SDFASDWA SDFASD" />
<Button
android:layout_column="1"
android:layout_columnSpan="1"
android:layout_gravity="fill|center"
android:layout_row="5"
android:text="FWEWEGAWEFWAE"/>
</GridLayout>
</LinearLayout>