FrameLayout with layout_weight is considered useless - android

Consider the following layout:
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
/>
<TextView
android:id="#+id/primary_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/white"
android:textSize="24sp"
tools:text="Primary!"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<TextView
android:id="#+id/secondary_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#color/white"
android:textSize="24sp"
tools:text="Secondary!"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3"
/>
</LinearLayout>
See the screenshot below for the result. The layout works fine, but Android Studio warns me that the FrameLayouts are considered useless and should be removed. However, they're not useless. I use layout_weight here. The idea is that the space between and around the two TextViews are relative with weights 2:1:3.
How can I rewrite my layout that results in the same weighted positioning of the views without having to use empty FrameLayouts?

You can get rid of the first two FrameLayout by setting the height of your TextView to 0dp and their weight to the values you set for your FrameLayout.

FrameLayout is a container that is supposed to have children. For a gap, a View is sufficient. I replaced each empty FrameLayouts with:
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
and the linter warning was gone.

Related

Is it Possible to remove child padding In Android

I have a linear layout. In Parent's view, I have padding defined. But I want to remove the padding from the child view. Is it possible to remove middle child view padding?. I know one solution is that I need to give padding separately. But i don't want to use this solution. So any alternative solution.
Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tool="http://schemas.android.com/tools"
android:padding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:visibility="gone"
tool:text="Header text" />
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="2dp"
android:layout_marginTop="10dp"
android:background="#cccccc"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="#id/header" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/dialog_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="5dp" />
</LinearLayout>
Above code looks like this
Expected Output
This could be done adding in the LinearLayout
android:clipToPadding="false"
and setting negative horizontal margins in the View:
android:layout_marginStart="-16dp"
android:layout_marginEnd="-16dp"
This works because you have a LinearLayout, it seems that negative margins are not supported for other ViewGroups than LinearLayout and RelativeLayout as this answer says: https://stackoverflow.com/a/10673572/7794806

Android Layouts: Stick one Layout to the top of the screen and place another Layout centred below

I am working on my first android-project, a memory-game in Android Studio. The gameActivity-Frame should contain some textViews, displayed in one line (for stats) on the top of the screen and the memory-cards below. There are mutliple memory-versions, so the number of memory-cards vary - and by that the dimension of thier GridLayout.
My main Layout is a LinearLayout (vertical). I placed another LinearLayout (horizontal) on it, where the Textviews take place. To display the cards, I used a GridLayout which will be filled with cards once the game started.
The LinearLayout (with textViews) should always stick on the top of the screen. The GridLayout should be centered in the remaining space below.
What I get is that both Layouts either stick in the middle, or that the LinearLayout is correct, but the GridLayout is either on the bottom or on the top of the remaining space.
I tried to find a solution here on SO, and I think I tried every possible combination of the gravity- and layout_gravity - settings of the components. I can imagine the problem is that I can use either wrap_content or match_parent in the main Layout, but not both. Guess I'd need wrap_content to stick the first Layout to the top and match_parent to use the whole space below this Layout.
How can I stick the first Layout to the top and center the GridLayout in the remaining space?
The picture shows my current layout (see code below) and how I want it to look.
center_GridLayout
Edit to clarify:
The LinearLayout should stick to the top of the screen, the GridLayout should be
centered in the remaining space below the LinearLayout.
RelativeLayout won't do the job properly, because the layouts might overlap, depending on the amount of memory-cards and the user's device's dimensions.
I uploaded another screenshot where it's better visible what I want to achieve:
This is my .xml (deleted some unimportant textViews):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/MemoryLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textStatsPairs"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/textStatsPairs" />
</LinearLayout>
<GridLayout
android:id="#+id/gridLayoutMainActivityTEST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:columnCount="4"
android:foregroundGravity="center"
android:orientation="horizontal"
android:rowCount="4"
android:textAlignment="center"
android:useDefaultMargins="true"
tools:context=".GameActivity" />
</LinearLayout>
use relative layout or constraint layout.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:id="#+id/MemoryLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textStatsPairs"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/textStatsPairs" />
</LinearLayout>
<GridLayout
android:layout_centerInParent="true"
android:id="#+id/gridLayoutMainActivityTEST"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:columnCount="4"
android:foregroundGravity="center"
android:orientation="horizontal"
android:rowCount="4"
android:textAlignment="center"
android:useDefaultMargins="true"
tools:context=".GameActivity" />
</RelativeLayout >
You can use relative layout along with linearlayout.From your question i got that you want your linearlayout always stick to top and GridLayout always stick to center.If this is the case then i think following code snippet will help you.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true">
</GridLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentTop="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Texts Here"
android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout>
</RelativeLayout>
The ConstraintLayout was what fixed my problem... Here's the solution that finally works perfectly:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="#+id/memory_activity_4x4"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/linearLayout_4x4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<TextView
android:id="#+id/textStatsPairs"
android:layout_width="65dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/textStatsPairs" />
</LinearLayout>
<GridLayout
android:id="#+id/gridLayout4x4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:columnCount="4"
android:foregroundGravity="center"
android:orientation="horizontal"
android:rowCount="4"
android:textAlignment="center"
android:useDefaultMargins="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/linearLayout_4x4"
tools:context=".GameActivity" />
</androidx.constraintlayout.widget.ConstraintLayout>

Android: recalculate dimension of layout components

I've a linear layout with few compononents, most of them have setted specific dimensions, but 1 is set to 0dp in other to fill the remaining space.
The thing is after inflate the xml layout i programatically add one more component, and the 0dp view doesn't shrink to fit this new component so it makes the layout to appear wrongly.
There are enough space for all components, if i try for example to add the "dinamic" component on the xml (just for test) and inflate it, all will appear well.
How can i force a LinearLayout to re-calculate the views height?
what i get:
here goes the code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="#+id/mainView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingLeft="#dimen/smallMargin"
android:paddingRight="#dimen/smallMargin"
android:visibility="visible">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="5dp"
android:layout_weight="1"
android:scrollbars="vertical" />
<LinearLayout
android:id="#+id/giveawayResult"
android:layout_width="match_parent"
android:layout_height="#dimen/giveawayCardHeight"
android:layout_marginBottom="#dimen/smallMargin"
android:layout_marginTop="#dimen/smallMargin"
android:visibility="invisible">
<RelativeLayout
android:layout_width="160dp"
android:layout_height="#dimen/giveawayCardHeight">
<ImageView
android:id="#+id/raffleThumbnail"
android:layout_width="160dp"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#drawable/asd" />
<TextView
android:id="#+id/raffleOwner"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:alpha="0.7"
android:background="#color/colorPrimaryDark"
android:gravity="center_horizontal|bottom"
android:text="viajandocomgabi"
android:textColor="#color/cardview_light_background"
android:textSize="16sp" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/smallMargin"
android:orientation="vertical">
<EditText
android:id="#+id/raffleDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:focusable="false"
android:hint="#string/raffle_date_label"
android:inputType="date"
android:longClickable="false"
android:textSize="#dimen/discreteFont" />
<EditText
android:id="#+id/amountToIndicate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:hint="#string/prompt_friends_to_indicate"
android:inputType="number"
android:lines="1"
android:textSize="#dimen/discreteFont" />
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/save" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
=========UPDATE==========
To make things clear:
1- the adview is added dynamically
2- the recycleview is 0dp because i want it to fill the left space
3- after inflating the layout the recycleview is dimentioned by android api, after that i add the adview, and IT DOESN'T GET RESIZED, so the result is what you see on the photo
i need to know how to force android to redimensionate recycleview to shrink to fit the space
To refresh the LinearLayout, or any view, you use its invalidate() method.
Edit: If you wish to remeasure the view, call it's requestLayout() method. Don't forget to invalidate it too.
Also, your Admob Banner Ad is breaking their Policy. Banner Ads can't overlap on app content.

Cannot see textview

I am trying to make a layout with this code :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:card_view="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
>
<android.support.v7.widget.CardView
app:cardCornerRadius="#dimen/cardview_corner_radius"
app:cardElevation="2dp"
card_view:cardUseCompatPadding="true"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#f27181"
android:id="#+id/charity_overview_card"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.sharesmile.share.views.LBTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#color/white"
android:padding="9dp"
android:text="Women Empowerment"
android:id="#+id/iv_charity_category_title"
/>
<ImageView
android:background="#color/colorPrimaryDark"
android:layout_width="128dp"
android:layout_height="126dp"
android:id="#+id/iv_charity_overview"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<com.sharesmile.share.views.LBTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tv_charity_amount"
android:textColor="#color/black"
android:textSize="15sp"
android:text="Test"
/>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
but the last textview is not visible, even in the preview it is not showing, it shows like this :
As you can see the textview is not visible, i haven't given any weight, still facing this issue.
Also when i increase the size of the textview the value is visible as you can see here :
LinearLayout inside other parent LinearLayout with dynamic size will produce this type of issues. You should avoid nesting layout inside layout as much as possibile.
This issue can be simply fixed by removing the parent layout orientation.
For improvement
<CardView>
<LinearLayout> vertical
//Add 'N' child items here
</LinearLayout>
</CardView>
Change the following properties of your main LinearLayout, Make height and width to match_parent
android:layout_width="match_parent"
android:layout_height="match_parent"

How can I create a 50/50 vertical layout with stacked GridViews?

One of my DialogFragments implements two equal-sized GridViews, one stacked on top of the other. Ideally, my layout would look like this (as seen in Android Studio):
Unfortunately, when I load up the layout on an actual Android device, I get something like this:
When the Kanji GridView is empty, it's completely invisible. Additionally, its height varies depending on the number of elements it has to display. How can I force the bottom GridView to fill 50% of the height as per the layout seen in Android Studio, even when it's empty?
Here is the XML for this particular layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/kanji_lookup_root"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:focusableInTouchMode="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ProgressBar
android:layout_width="32dp"
android:layout_height="32dp"
android:id="#+id/progress_bar"
android:layout_toStartOf="#+id/search_box_kanji"
android:visibility="gone"
android:indeterminate="true"
android:layout_centerVertical="true"/>
<SearchView
android:layout_width="300dp"
android:layout_height="wrap_content"
android:id="#id/search_box_kanji"
android:queryHint="#string/menu_search_hint"
android:iconifiedByDefault="false"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
style="#style/EntryDetailsHeader"
android:text="#string/components" />
<com.tonicartos.widget.stickygridheaders.StickyGridHeadersGridView
android:id="#+id/grid_components"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="9"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
style="#style/EntryDetailsHeader"
android:text="#string/kanji" />
<GridView
android:id="#+id/grid_kanji"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:numColumns="9"/>
</LinearLayout>
</LinearLayout>
(By the way I'm using the StickyGridHeaders library for the upper Components GridView)
Change the '0dp' layout_height on your two LinearLayouts to 'match_parent'.
You're missing a weightSum attribute on your outermost LinearLayout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/kanji_lookup_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:weightSum="2" > <!-- This line is what you were missing -->
...
</LinearLayout>
Tested this as working on device (assuming your EntryDetailsHeader style sets match_parent width and wrap_content height).

Categories

Resources