I'm using android support library BottomNavigationView , it looks very bad in some versions of android .
this is my code :
<android.support.design.widget.BottomNavigationView
android:id="#+id/navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#fff"
app:theme="#style/mydrawer"
app:itemIconTint="#drawable/selector"
app:itemTextColor="#drawable/selector"
app:menu="#menu/bottom_navigation_items" />
in styles :
<style name="mydrawer">
<item name="android:textSize">14sp</item>
</style>
it looks good in my phone with android 6 but it look very bad on most of the phones , like this:
as you can see, the text size in enormous
how can I fix this ?
You specify one text size value for all devices:
<style name="mydrawer">
<item name="android:textSize">14sp</item>
</style>
Instead of 14sp , you should specify value from dimens
<style name="mydrawer">
<item name="android:textSize">#dimen/bottom_bar_item_text_size</item>
</style>
Create dimens.xml files for different screen sizes. You should create dimens.xml file for each screen size :
normal
large
xlarge
there are more of those, but those 3 are most common.
<dimen name="bottom_bar_item_text_size">14sp</dimen>
Your dimens.xml files will look like that :
Hope that helps
You can use Bottom Navigation ViewEx for more customization and better appearence , usage is similar to that of normal view
check out the github
Related
According to the documentation
A Button which supports compatible features on older versions of the
platform, including:
Allows dynamic tint of its background via the background tint methods
in ViewCompat. Allows setting of the background tint using
R.attr.backgroundTint and R.attr.backgroundTintMode. This will
automatically be used when you use Button in your layouts and the
top-level activity / dialog is provided by appcompat. You should only
need to manually use this class when writing custom views.
Now, this makes me assume that the following two buttons would look exactly the same on high level devices.
<androidx.appcompat.widget.AppCompatButton
android:text="AppCompatButton"
android:id="#+id/appcompatbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:layout_below="#id/appcompatbutton"
android:id="#+id/button"
android:layout_width="wrap_content"
android:text="Button"
android:layout_height="wrap_content" />
However, here is how it actually looks:
I ran this on the following emulator:
Galaxy Nexus, API:28 (720 x 1280 xhdpi)
And when I apply buttonStyle in my appTheme like this:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>
</style>
It changes the AppCompatButton but not the normal button like this:
(Note the slight difference in the rounded edges)
I also tried to create a custom button that both inherited from android.widget.Button and also androidx.appcompat.widget.AppCompatButton, both of these buttons show the same behaviour as using AppCompatButton in xml does. So it feels like the only outlier is Button in XML.
Question 1:
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
EDIT 1
Doing debugging I found that the Button actually gets transformed into a MaterialButton, see the following:
Question 2:
Why is this transformation happening?
EDIT 2
Question 2 answer:
The transformation of Button to MaterialButton is due to the parent theme I was using.
Question 3:
How do you implement a custom button which works just like Button in xml would?
As a side note and personal opinion, also a slight repetition, this system is not only confusing but its hard to get it right and foolproof for future changes. In addition to this, the documentation is very poor. I would appreciate if an answer to this would be included as well, or at least a discussion regarding it, how to deal with it for example.
Short answers.
This all seems incredibly confusing according to me. Can someone clarify this as either a bug or feature?
They use different styles.
Why is this transformation happening?
There is an auto-inflation enabled which will replace <Button with <com.google.android.material.button.MaterialButton at runtime.
How do you implement a custom button which works just like Button in xml would?
You can customize the attributes in xml or the theme attributes.
Long answers.
They use different styles.
The default style of MaterialButton is Widget.MaterialComponents.Button.
This style inherits from Widget.AppCompat.Button but changes some attributes.
Here you can find the differences.
The main difference is here:
<item name="shapeAppearance">?attr/shapeAppearanceSmallComponent</item>
You can read more about shaping in the official doc.
If you navigate through the style you will find:
<style name="ShapeAppearance.MaterialComponents.SmallComponent">
<item name="cornerSize">#dimen/mtrl_shape_corner_size_small_component</item>
</style>
where mtrl_shape_corner_size_small_component = 4dp.
It explains the slight difference in the rounded edges.
Also you are using
<item name="buttonStyle">#style/Widget.MaterialComponents.Button</item>.
It doesn't work for the MaterialButton. You have to use:
<item name="materialButtonStyle">#style/Widget.MaterialComponents.Button</item>
The auto-inflation is here.
The MaterialComponentsViewInflater replaces some framework widgets with Material Components ones at inflation time, provided a Material Components theme is in use.
Something similar happens also with AppCompat (you can check that MaterialComponentsViewInflater extends AppCompatViewInflater).
It means that, the <Button is replaced <com.google.android.material.button.MaterialButton at runtime, if you are using a Material Theme.
There are different options. One of these is to define a custom style for buttons.
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
...
<item name="materialButtonStyle">#style/MyButtonStyle</item>
</style>
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="cornerRadius">xxx</item>
</style>
or
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="shapeAppearanceOverlay">#style/SShapeAppearanceOverlay.MyApp.Button.Rounded</item>
</style>
<style name="ShapeAppearanceOverlay.MyApp.Button.Rounded" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">xxdp</item>
</style>
I changed the <Button> to <ImageButton>
Quick and short way.
Don't forget to check & change references in java/kotlin files. Compiler will alert you any way.
I have a lyaout and I want to change its constraints in phone vs. tablet.
I want to set the top_toTop to be in relate to viewA while in phone device
app:layout_constraintTop_toTopOf="#+id/viewA"
And I want it to relate to the aprent while in tablet device
app:layout_constraintTop_toTopOf="parent"
I thought to use resource referencing but how do i reference to the parent? it's not a resource
Option 1
Instead of using parent you can use the id of the parent view (the ConstraintLayout itself), this way you could swap just the id with a configuration-specific resource. Say your layout looks like this:
<android.support.constraint.ConstraintLayout
android:id="#+id/rootView"
...
>
<View
android:id="#+id/someView"
...
/>
<View
...
app:layout_constraintTop_toTopOf="#id/myAnchorView"/>
</android.support.constraint.ConstraintLayout>
You can then define 2 different id references in your configuration, say phone:
<resources>
<item name="anchorView" type="id">#id/rootView</item>
</resources>
And tablet:
<resources>
<item name="anchorView" type="id">#id/someView</item>
</resources>
Option 2
Define a style for your view and have 2 versions of that style, one for phone:
<style name="MyView">
<item name="layout_constraintTop_toTopOf">parent</item>
</style>
and one for tablet:
<style name="MyView">
<item name="layout_constraintTop_toTopOf">#+id/viewA</item>
</style>
the code you have app:layout_constraintTop_toTopOf="parent" is correct but you have to put in the correct layout folder
you could also create 2 dimens files with the ids
phone
<resources>
<dimen name="view_parent">#id/viewA</dimen>
</resources>
tablet
<resources>
<dimen name="view_parent">#id/parentId</dimen>
</resources>
layout
app:layout_constraintTop_toTopOf="#dimen/view_parent"
So I was able to successfully modify what my text tabs look like by using the following code, and it looks as expected on most devices including my Nexus
Styles:
<style name="AppTabLayout" parent="Widget.Design.TabLayout">
<item name="tabIndicatorColor">#color/white</item>
<item name="android:background">#color/colorPrimary</item>
<item name="tabSelectedTextColor">#color/white</item>
<item name="tabTextColor">#color/whiteTransparent</item>
</style>
<style name="TabTextStyle" parent="TextAppearance.AppCompat.Widget.ActionMode.Title.Inverse">
<item name="android:textSize">14sp</item>
<item name="android:textAllCaps">true</item>
</style>
Layout:
<android.support.design.widget.TabLayout
android:id="#+id/toolbar_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:tabTextAppearance="#style/TabTextStyle"
style="#style/AppTabLayout">
</android.support.design.widget.TabLayout>
The problem is that on Samsung devices (S5 and S7 have been tested) the sizes appear to be overwritten so that they expand or shrink based on the length of text in the tab - i.e. short strings are made larger to filler the space.
I've seen no mention of this anywhere and can't seem to make the device respect my choice to set the text to the same size no matter the length of the tab title.
Any advice on how to stop Samsungs doing this?
In Samsung phones there is an option called font size change in settings.
Always use dp instead of sp so that text size is set based on density pixel.
ur value in dp
u can check the same by playing around font size change in settings of ur samsumg phone
I'm building an app now and I want it to work well across multiple screen sizes (phones, 7inch tablets and 10inch tablets). I've looked at the document on Supporting Multiple Screens but i still have some questions.
Right now I have 5 different layout folders, layout-: normal, large, xlarge, sw600dp and sw720dp. Is this the best way to build for all screen sizes?
And when i try to optimize each layout say the normal size which covers some 3 and 4 inch screens I get issues where I can't get my layout to look right on all of them.
What am I doing right and what could I change?
I don't believe that there's any best way, it will be just your way to do it. If you are planing to make the Images, buttons, textview smaller or bigger you can use the method you use or style.xml.
Style.xml example:
You will have some folders like:
values
values-large
values-normal
values-small
values-xlarge
where inside the folders you have a styles.xml with different values:
<style name="BigTextStyle">
<item name="android:textSize">60dp</item>
</style>
<style name="SmallTextStyle">
<item name="android:textSize">48dp</item>
</style>
<style name="ImageSize">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">100dp</item>
</style>
just change the size depending on the screen you are working with, then in the layout.xml add this:
<ImageView
android:id="#+id/imageSD"
style="#style/ImageSize" />
<TextView
android:id="#+id/imageNameSD"
style="#style/BigTextStyle" />
I believe you can use this resource alias sir.
Suppose you have two different images for sw320dp and sw600dp.
image1_sw320dp.png
image1_sw600dp.png
Put all image resource to folder drawable.
The in the folder values-sw320dp, create an xml resource. (also maybe you need for values-small, just copy the xml from values-320dp)
<resources>
<item type="drawable" name="image1">#drawable/image1_sw320dp</item>
</resources>
In folder values-sw600dp, create an xml resource.
<resources>
<item type="drawable" name="image1">#drawable/image1_sw600dp</item>
</resources>
Then use on the activity with R.drawable.image1. This can prevent for creating duplicate resources for example sw320dp, small, and normal.
Mr Rotary has a good way to work with multiple screen size.
Furthermore You can use Fragment in your application.
You can learn how to use fragment here : http://developer.android.com/guide/components/fragments.html
here's my issue. I have defined custom themes and styles, so as to customize various Views, in the relevant .xml files. Here are some code extracts:
themes.xml:
...
<style name="Legacy" parent="android:Theme.NoTitleBar">
<item name="android:buttonStyle">#style/Legacy.Button</item>
...
</style>
styles.xml:
...
<style name="Legacy.Button" parent="#android:style/Widget.Button">
<item name="android:textColor">#ffffff</item>
<item name="android:background">#drawable/button_selector_blue</item>
<item name="android:textSize">15dp</item>
</style>
Let's say I set my application's theme to Legacy. If I use a Button in a layout, it will get my custom default parameters (white text, background is #drawable/button_selector_blue, etc).
Now let's say I want to keep those parameters save for the text size: I'd like to have some buttons with a larger text size, which would be defined in an titleSize attribute in attrs.xml:
...
<attr name="titleSize" format="reference|dimension" />
and which value is set for each theme in my themes.xml file.
So my layout would contain something like:
<Button
android:id="#+idmyButtonId"
android:drawableRight="#drawable/aDrawable"
android:text="#string/someText"
android:textSize="?titleSize"
android:layout_width="fill_parent" android:layout_height="wrap_content">
</Button>
When launching my app I get the following error:
java.lang.UnsupportedOperationException: Can't convert to dimension: type=0x2
So it seems I cannot tweak custom styles using attributes - at least not this way. Is such a thing possible ? If not, what would you use to achieve such a result ?
I'd like to give the user the ability to select among different themes, so I can't just define an additionnal ButtonWithLargeText style and directly use it in my layout.
Thanks for your help !
I finally got it to work. Instead of defining my titles' size in attrs.xml, I used dimens.xml. So now the following works:
<Button
android:id="#+idmyButtonId"
android:drawableRight="#drawable/aDrawable"
android:text="#string/someText"
android:textSize="#dimen/titleSize"
android:layout_width="fill_parent" android:layout_height="wrap_content">
</Button>
While I get my regular text size (which I defined in my styles.xml) on the Button by using this:
<Button
android:id="#+id/idRegularButton"
android:text="#string/regularSizeText"
android:layout_width="wrap_content" android:layout_height="wrap_content">
</Button>