How to avoid nested LinearLayout or RelativeLayout - android

i am trying to create something like a list inside a cardview in a recyclerview.
It is a detail box which should be filled programatically in the getholderview function of the recycler adapter.
Now i came up with the following code, but somehow i get a feeling this is not very performant.
How can i avoid a lot of nested layouts to realize this and should i even try to avoid it in this case?
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
<RelativeLayout ...>
... Other content Title
<ImageView
android:id="#+id/profileImage"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#drawable/ic_loyalty_black_24dp"
/>
<TextView
android:id="#+id/cell_textView"
android:layout_toRightOf="#id/profileImage"
android:layout_toEndOf="#id/profileImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:focusable="true"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:textAppearance="?android:attr/textAppearanceMedium"/>
<TextView
android:id="#+id/fat_bar_text"
android:layout_toRightOf="#id/profileImage"
android:layout_toEndOf="#id/profileImage"
android:layout_below="#id/cell_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fett:"
android:layout_marginTop="3dp"
android:textAppearance="?android:attr/textAppearanceSmall"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/detailBox"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_below="#id/fat_bar_text"
android:gravity="bottom">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Value:"/>
<TextView
android:layout_weight="0.5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="500€"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Test:"/>
<TextView
android:layout_weight="0.5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="blah"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</LinearLayout>

The root LinearLayout is unnecessary, use the CardView as the root element.
the second LinearLayout is unnecessary too if you don't have touch event or style on it. replace it with layout_below attr in the child element
you can put the innermost LinearLayout which contain two TextView into an another xml file, and include them with <include> tags, this can make your code more simple and clean. and easy to reuse. like this
mytext.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_gravity="start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0.5"
android:text="Value:"/>
<TextView
android:layout_weight="0.5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="500€"/>
</LinearLayout>
cardview.xml
<include
layout="#layout/mytext"
android:id="#+id/mytext1"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include
layout="#layout/mytext"
android:id="#+id/mytext2"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Please, consider to use Constraint Layout. It was created to provide flexibility of building layouts of any complexity. It reduces number of nested layout. One more link

Related

Put two views in the center of the screen

I have two views (com.github.mikephil.charting.charts.BarChart and LinearLayout), the content inside one view is approx 600 dp high, the other once has 500 dp. Width of both views is fill_parent.
I would like to position them both into the center of the screen (so they overlaps).
Unfortunately, Android's layout alignment is very unintuitive and hit or miss for me and I'm not able to achieve that.
Can you please help?
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:orientation="vertical"
android:background="#11FFFFFF">
<com.github.mikephil.charting.charts.BarChart
android:id="#+id/chart"
android:layout_width="match_parent"
android:layout_height="500dp"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="50dp"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="150dp"
android:includeFontPadding="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="HITS"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50dp"
android:orientation="vertical"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:textSize="150dp"
android:includeFontPadding="false"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="MISSED"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I want to position both Views inside this RelativeLayout in the center of the screen, overlapping
Put in the 2 views you wanna to place in center inside a RelativeLayout, then add android:layout_centerInParent="true" into the 2 views.
For example it look like this:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.BarChart
....all other stuff
android:layout_centerInParent="true" > //..add this
<LinearLayout
..... all other stuff
android:layout_centerInParent="true" > //..add this
</LinearLayout>
</RelativeLayout>
Define your main layout as ConstraintLayout and then constraint all sides of both elements to their parent.
Something like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="600dp"
android:layout_height="600dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</LinearLayout>
<com.github.mikephil.charting.charts.BarChart
android:layout_width="500dp"
android:layout_height="500dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</com.github.mikephil.charting.charts.BarChart>
</android.support.constraint.ConstraintLayout>
With this code your BarChart is above your LinearLayout.
In my experience it's most of the times best practice to use the lightest container possible, which in this case is probably a FrameLayout, so I would use that instead of RelativeLayout and use android:layout_gravity="center" in the subviews like this for example:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.BarChart
android:layout_gravity="center" >
<LinearLayout
android:layout_gravity="center" >
</LinearLayout>
</FrameLayout>

ScrollView with weight not working for me

I have a parent linearlayout with two scrollview inside it and I am using weight attribute inside scroll vies but this is not working for me I mean it's not providing any scrolling. Here is the code, how can I make it work?
LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<ScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginRight="8dp">
<LinearLayout
android:id="#+id/linearLayoutSizes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="#dimen/product_detail_items_margin_left"
>
</LinearLayout>
</ScrollView>
<ScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginLeft="8dp">
<LinearLayout
android:id="#+id/linearLayoutColors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/colorsGroup"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioGroup>
</LinearLayout>
</ScrollView>
</LinearLayout>
Experimented your code and found the issue.
From your code, it does seems like what you want is a Horizontal Scroll. But you are using normal ScrollView which is by default Vertical Scroll. Consider changing ScrollView to HorizontalScrollView.
i.e. from
<ScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginRight="8dp">
to
<HorizontalScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginRight="8dp">
Do change on both your scroll view. Cheers!
Since you are fixing weight for the scrollView it thinks that the data should never exceed the height and hence it doesnt scroll. Just cover the scrollviews with frame layouts like below and try.
LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="2">
<FrameLayout android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginRight="8dp">
<LinearLayout
android:id="#+id/linearLayoutSizes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="#dimen/product_detail_items_margin_left"
>
</LinearLayout>
</ScrollView>
<FrameLayout>
<FrameLayout android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="horizontal"
android:fillViewport="true"
android:layout_weight="1"
android:layout_marginLeft="8dp">
<LinearLayout
android:id="#+id/linearLayoutColors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/colorsGroup"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</RadioGroup>
</LinearLayout>
</ScrollView>
</FrameLayout>
</LinearLayout>
See if this works.
See if the following code works for you:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:weightSum="2">
<ScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:fillViewport="true"
android:scrollbars="horizontal">
<LinearLayout
android:id="#+id/linearLayoutSizes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"></LinearLayout>
</ScrollView>
<ScrollView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:fillViewport="true"
android:scrollbars="horizontal">
<LinearLayout
android:id="#+id/linearLayoutColors"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RadioGroup
android:id="#+id/colorsGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</RadioGroup>
</LinearLayout>
</ScrollView>
</LinearLayout>
your XML looks ok to me so why dont you try and add a couple of buttons or images to the layouts and try to scroll them?
also dont forget to add this line of code to the very top of your XML file:
<?xml version="1.0" encoding="utf-8"?>
let me know how you get on.

Distribute grids evenly to fit screen

i am trying to get three rows in my recyclerview to fit the screen perfectly. In other words distributed evenly with no scrolling. I have a toolbar and a recyclerview with two columns/three rows. As of now i have just set the items height to fit the screen close enough but there has to be a better way?
activity_main.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_below="#id/toolbar"
android:background="#CCCC"
android:layout_width= "match_parent"
android:layout_height = "match_parent"/>
</RelativeLayout>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/colorBlock"
android:layout_width="match_parent"
android:layout_height="170dp"
android:background="#CCCCCC" />
<ImageView
android:id="#+id/item"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_centerHorizontal="true"
android:padding="16dp"
/>
<TextView
android:id="#+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:textColor="#android:color/white"
android:textSize="16sp"/>
</RelativeLayout>
By definition, the RecyclerView is supposed to be used in situations where recycling views can happen - a.k.a. scrollable because large amount of views. I don't mean to say it can not be used for smaller collections, but there's no value in using it upon other layouts. As a matter of fact, not being built for such scenarios, it becomes very difficult to make use of it in scenarios like in this question. If you absolutely want to use RecyclerView, I am not aware of any way to do it in xml only. I think you'll have to implement your own layout manager for this.
If you are open to using other layouts, here's a solution involving a bunch of linear layouts and weights. Not optimal, having to use nested weights, but a solution nevertheless:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_below="#id/toolbar"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#ff0000"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#fff000"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff0f00"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#ff00f0"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#00ff00"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#f0ff00"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#0fff00"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#00fff0"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#0000ff"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#f000ff"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#0f00ff"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#00f0ff"/>
</LinearLayout>
</LinearLayout>

Scrollable layout in FrameLayout

I've a FrameLayout on my android app but I can't make to scrollable a part of this layout...I've tried some solutions to fix this problem, but I can't find a patch!
Pratically, I would like to see scrollable the linearlayout (maybe, linearlayout is not necessary) between Scrollview tags.
This is my xml:
<FrameLayout 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="com.robertot.timereport.com.robertot.timereport.Pages.YearlyStatFragment">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
// Some views to scroll
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/bottom_linear"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:layout_gravity="bottom"
style="#android:style/Widget.Holo.Light.ActionBar.Solid">
<Spinner
android:id="#+id/spnYearY"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"/>
<ImageButton
android:id="#+id/btnFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_search"
android:background="#null"
android:layout_weight="1"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</FrameLayout>
Thanks!! :)
In a FrameLayout all the content views are one on top of the other, so the normal behaviour is that the Linear Layout hides part of the previous Scrollview. Why don't you use a LinearLayout or a Relative Layout instead of the FrameLayout?
Thanks to #Fernando! I've solved my problem, as is:
<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"
android:orientation="vertical"
tools:context="com.robertot.timereport.com.robertot.timereport.Pages.YearlyStatFragment">
<ScrollView
android:id="#+id/scrollyear"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//Some views
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/bottom_linear"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
android:layout_gravity="bottom"
style="#android:style/Widget.Holo.Light.ActionBar.Solid">
<Spinner
android:id="#+id/spnYearY"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"
android:layout_marginLeft="8dp"/>
<ImageButton
android:id="#+id/btnFilter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_search"
android:background="#null"
android:layout_weight="1"
android:layout_gravity="center_vertical"/>
</LinearLayout>
</LinearLayout>
You can surround the view that you want to be scrollable with a ScrollView, as below:
<ScrollView android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff">
// the views here that you want to make scrollable
</ScrollView>

Android GUI Layout

I am currently trying to work out how to align certain elements within my Android app's GUI.
Please see the image link below, the first layout is the current one, and the second is what I am aiming for.
Currently, I am using two linear Layouts. I have tried to use relative and table layouts for the right hand buttons and EditText, but always the EditText is shrunk, or overflows the tablet's screen size.
Thanks for your help!
Image Link: (http://postimage.org/image/pptkdkomx/)
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="match_parent"
android:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5" android:text="Button1"/>
<Button
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.5" android:text="Button2"/>
</LinearLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
Why don't you use RelativeLayout and on your EditText use android:layout_alignBottom="myImage"
Just brought together a quick template, you may need to fix + add your own attributes since I used only notepad:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="50">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"/>
<Button android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="50"/>
</LinearLayout>
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</LinearLayout>

Categories

Resources