Android Application Development: Automatic Margin? - java

How can I assign each view an automatic margin?
Example:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button ... />
<Button ... />
<Button ... />
<Button ... />
</LinearLayout>
I want each of these buttons to have the same amount of space between them.
Now I could just put a layout_marginTop and a layout_marginBottom attribute in each of the tags and set their values to what I want them to be, but isn't there an easier way to do this?
Can I somehow automatically set each view's margin in my LinearLayout to a specific value without having to type it in every tag?

You can use the layout weight of the object
Set each of the buttons to have an equal layout weight and then set each of their heights to match_parent
That should resolve your issue.

Related

Android doesn't resize with different screen layouts

I am trying to resize my layouts, based on which device I am using.
I am testing on two differents phones (Samsung Galaxy S8+ and Sony Xperia Z2 (and even two different emulators)).
I've added some code into the Manifest file.
I've created different folders with the right (supposedly) names (layout, layout-small, layout-large, layout-xlarge).
I put my code into the values folder, file "dimens.xml" and call it from my layouts.
But nothing seems to work.
The only time my screens are changing is when I am modifying the corresponding file into the "layout" folder.
I would love any help or advice. Thank you!
I've read many times the documentation on Android Developer and Stack Overflow and I can't seem to find a solution.
Snippet of AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.applicationpro">
<supports-screens android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:anyDensity="true"
android:resizeable="true" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
Snippet of res/layout-large/my_layout.xml
<?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:id="#+id/mainLL"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg4"
android:orientation="vertical"
tools:context=".activity.LoginActivity">
<ProgressBar
android:id="#+id/loginPG"
android:theme="#style/FragmentsProgressBar"
style="#style/Widget.AppCompat.ProgressBar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:layout_marginTop="100dp"/>
<android.support.design.widget.TextInputLayout
android:id="#+id/loginTIY"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_top_large">
<AutoCompleteTextView
android:id="#+id/loginTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/prompt_login"
android:maxLines="1"
android:singleLine="true" />
</android.support.design.widget.TextInputLayout>
dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="standard_55">65dp</dimen>
<dimen name="standard_105">135dp</dimen>
<dimen name="standard_155">155dp</dimen>
<!-- Small Dimensions = "Medium Dimensions * 0.75" For Example: 210*.75 = 157.5-->
<dimen name = "margin_top_small">150dp</dimen>
<!-- Medium Dimensions -->
<dimen name = "margin_top_medium">200dp</dimen>
<!-- Large Dimensions = "Medium Dimensions * 1.5" For Example: 210*1.5 = 315 -->
<dimen name = "margin_top_large">300dp</dimen>
<!-- XLarge Dimensions = "Medium Dimensions * 2" For Example: 210*1.5 = 420 -->
<dimen name = "margin_top_xLarge">400dp</dimen>
</resources>
TL;DR
This is another approach using ConstraintLayout and not a single layout for every screen size
You can support different screen sizes by using ConstraintLayout:
ConstraintLayout allows you to create large and complex layouts with a flat view hierarchy (no nested view groups). It's similar to RelativeLayout in that all views are laid out according to relationships between sibling views and the parent layout, but it's more flexible than RelativeLayout and easier to use with Android Studio's Layout Editor.
You can use those attributes to specify your views size in precents:
app:layout_constraintWidth_percent=".5"
app:layout_constraintHeight_percent=".5"
For example, single button that is equal to 50% of the screen both in height and width:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_percent=".5"
app:layout_constraintHeight_percent=".5"/>
</androidx.constraintlayout.widget.ConstraintLayout>
And it will look something like this:
I can recommend using ConstraintLayout with guidelines and Chains to support different screen sizes (In addition to what I mentioned above - app:layout_constraintWidth_percent and app:layout_constraintHeight_percent).
At first look this may look like a lot of work and some may wonder if this is really worth the effort but here is why I believe ConstraintLayout is the proper way to build your UI:
It's really user-friendly.
ConstraintLayout is very easy and simple to learn.
once you have learned it you will see that you are saving a lot of development time because making your UI is simply fast.
Constraint layout is meant to support different screen sizes so no need to build a layout for every screen size (this also connect to the previous advantage- saving development time).

Make Spinner dropdown to match screen width

I'd like my Spinner dropdown items to fill the entire screen width even tho my 'title' does not. Problem is the dropdown menu width seems to be limited the Spinner's title width.
My goal is to make it fill the entire screen width, with no spacing left or right, right below the action bar. A similar one to what I'm trying to do would be Instagram's menu to change profile.
I looked to similar questions but didn't find a solution that worked here. Also tried to create a custom adapter and making sure its views had match_parent attribute on their width. But didn't work either.
main.java (only relevant part of the code for legibility)
mMyListsSpinner = (Spinner) findViewById(R.id.spinner_mylists);
ArrayAdapter<String> snipperAdapter = new ArrayAdapter<String>(
FamilistActivity.this, R.layout.layout_spinner_title, dummyLists);
snipperAdapter.setDropDownViewResource(R.layout.layout_spinner_dropdown);
mMyListsSpinner.setAdapter(snipperAdapter);
mMyListsSpinner.setOnItemSelectedListener(this);
layout_spinner_title.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/spinner_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#color/color_white_bright"
android:maxLines="1"
style="#style/OverflowMenu"
android:text="this is my list"/>
layout_spinner_dropdown.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout_spinner_dropdown"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_actionbar_height"
android:maxLines="1"
android:textSize="18sp"
android:textColor="#color/color_green_dark"
android:background="#color/color_white_bright"/>
styles.xml (only the relevant part)
<style name="OverflowMenu" parent="Widget.AppCompat.PopupMenu.Overflow">
<item name="overlapAnchor">false</item>
<item name="android:dropDownVerticalOffset">16dp</item>
<item name="android:dropDownHorizontalOffset">-15dp</item>
</style>
my toolbar:
toolbar.xml
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/bar_appbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_actionbar_height"
app:layout_collapseMode="pin"
android:background="#color/color_green_bright">
<Spinner
android:id="#+id/spinner_mylists"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:spinnerMode="dropdown"
android:dropDownWidth="match_parent"
style="#style/OverflowMenu"/>
By looking into AppCompatSpinner.java and running the debugger I saw in this line in computeContentWidth()
else if (mDropDownWidth == MATCH_PARENT) {
setContentWidth(spinnerWidth - spinnerPaddingLeft - spinnerPaddingRight);
}
that SpinnerPaddingRight has a value that is not 0. I solved it by setting
android:paddingEnd="0dp"
in the Spinner view.

Selected cardview no foreground

I need to do what google does with notes like this.
This happens when I select a note and not just when I press one, even if my finger isn't on the note, the card view is selected and grey.
I tried with a custom foreground but without results.
I am not sure it can be done with foreground.
If I understand you correctly, you want to implement color change and add stroke on long click?
Than you can use one trick:
set your card layout like so:
<android.support.v7.widget.CardView
android:id="#+id/card"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
...>
<LinearLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
...>
...
</LinearLayout>
</android.support.v7.widget.CardView>
Set LinearLayout background color
<android.support.v7.widget.CardView
android:id="#+id/card"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/your_color"
...>
...
</LinearLayout>
</android.support.v7.widget.CardView>
Than change card and layout background color at runtime, layout margins to reveal card beneath
layout.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View l) {
card.setCardBackgroundColor(Color.parseColor("#939393")); //darker gray
layout.setBackgroundColor(Color.parseColor("#d4d4d4")) //gray
// use this to define margins in dp, not px
int dp8 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, getResources().getDisplayMetrics());
// get layout's parent (card is parent of layout)
CardView.LayoutParams params = (CardView.LayoutParams) card.getLayoutParams();
// set margins in dp
params.setMargins(dp8, dp8, dp8, dp8);
// apply them to your layout
layout.setLayoutParams(params);
}
});
I haven't tested this code yet, but I think it should do the trick.
Tried toggling the background of the cardview via code with a white gray color depending on the state that you would prefer. Ie if it's selected etc?
Use duplicateParentState on note.
The childView will get parentView's state.
When you press parentView,the childView will get the pressed state.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="123"
android:background="#drawable/bg_txt"
android:duplicateParentState="true"
android:textSize="15sp" />
</FrameLayout >
Add
<color name="color_1">#4b14b1</color>
<color name="color_0">#ffffff</color>
in colors.xml.
Add bg_txt.xml in drawable folder.
bg_txt.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#color/color_1"></item>
<item android:state_pressed="true" android:drawable="#color/color_1"></item>
<item android:drawable="#color/color_0"></item>
</selector>

How to fix the layout in OnConfigurationChanged when i do not want the activity to restart

So i fixed my activity restart on changing orientation (i needed to do that for client requirement) but now i am having issues fixing the display layouts.I have tried a lot of combinations of layout_height and layout_weight but failed.
I just need some guidance in how to fix this.
My layout xml:
<?xml version="1.0" encoding="UTF-8"?>
<!--
/*
Session screen layout
Copyright 2013 Thincast Technologies GmbH, Author: Martin Fleisz
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/session_root_view"
android:background="#F7FE2E"
>
<!-- childs are specified bottom-up so that we have a correct z-order in our final layout -->
<android.inputmethodservice.KeyboardView
android:id="#+id/extended_keyboard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone"
/>
<com.freerdp.freerdpcore.presentation.ScrollView2D
android:id="#+id/sessionScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#id/extended_keyboard"
android:scrollbars="horizontal|vertical"
android:layout_alignParentTop="true"
android:fillViewport="true"
android:background="#FF0040"
android:drawingCacheQuality="high"
android:isScrollContainer="true"
>
<com.freerdp.freerdpcore.presentation.SessionView
android:id="#+id/sessionView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:focusable="true"
android:focusableInTouchMode="true"
android:drawingCacheQuality="high"
/>
</com.freerdp.freerdpcore.presentation.ScrollView2D>
<com.freerdp.freerdpcore.presentation.TouchPointerView
android:id="#+id/touchPointerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/touch_pointer_default"
android:visibility="invisible"
/>
<android.widget.ZoomControls
android:id="#+id/zoomControls"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/sessionScrollView"
android:layout_centerHorizontal="true"
/>
<android.inputmethodservice.KeyboardView
android:id="#+id/extended_keyboard_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:visibility="gone"
android:layout_centerHorizontal="true"
/>
</RelativeLayout>
The relevant code which i use in onConfigurationChanged:
RelativeLayout.LayoutParams params = (android.widget.RelativeLayout.LayoutParams) new RelativeLayout.LayoutParams(
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT,
android.widget.RelativeLayout.LayoutParams.MATCH_PARENT);
scrollView.setLayoutParams(params);
sessionView.setLayoutParams(new FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT,
android.widget.FrameLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER));
scrollView.requestLayout();
sessionView.requestLayout();
Screenshot when initially in Portrait:
Screenshot when in landscape:
thanks.
Try this
LayoutParams p = scrollView.getLayoutParams();
LayoutParams p1 = sessionView.getLayoutParams();
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
p.width = outMetrics.widthPixels;
p.height = outMetrics.heightPixels
p1.width = outMetrics.widthPixels;
p1.height = outMetrics.heightPixels
your view may be filling the screen with fill_parent. But the portrait aspect ratio image will not fit in as background in landscape layout.
use a different image of landscape width and height and use it in drawable-land folder (name of the image should be same)
image from drawable-land will be automatically picked for landscape layout

Android ScrollView not working

I have a layout which I want to be scrollable when content is overflowing the screen.
I have the following layout xml set up.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:id="#+id/ScrlView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:isScrollContainer="false"
android:id="#+id/home_root"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/backrepeat">
<!-- Include Header -->
<include layout="#layout/main_header"/>
<!-- Include dashboard -->
<include layout="#layout/dashboard"/>
</LinearLayout>
</ScrollView>
A dashboard is a collection of icons serving as a menu. Example: click me
Unfortunately, the second include (dashboard) shows 'broken' now. See screen:
Click here
As you can see it doesn't look like it's suposed to. When I delete the scrollview, everything is fine.
What I want is for my dashboard to still look good, but be scrollable if needed.
I tried several setups but all give the same result. What am I doing wrong?
Any help would be appreciated :)
Remove the android:isScrollContainer="false", and add android:fillViewport="true" to scrollView

Categories