Android - a toolbar layout with a static background designed only for the icon

I am trying to create a panel layout. It differs from the google i / o toolbar in that the background of the image icon and the text under the icon are different.

In other words, the icon (image only) has a StateListDrawable for its background, while the text has a transparent background. One way to do this is to put this combination of image and text in a LinearLayout and use it in the toolbar layout for each item that seems not so simple. Is this the only way to do this? or is there a better and simpler solution?

Refresh . You can customize the project here and experiment.

  • The dashboard2.xml layout file uses the google class DashboardLayout . In the main action, I just set the contents of the dashboard2 view

  • In this project you will find the style pulled out in the drawable folder drawable name dashboard_icon_bg_selector.xml . I want the background of all the toolbar icons to be available for this article.

Any suggestion is appreciated.

+4
source share
3 answers

One possible solution that I can think of is to use LayerDrawable as your TextView topDrawable. I will describe this idea, list some details and attach a link to the draft modified example below.

Code for the button (in the layout file):

 <Button android:id="@+id/home_btn_schedule" style="@style/DPDashBoardButton" android:text="button 1" android:drawableTop="@drawable/dashboard_icon_bg_selector" /> 

Two LayerDrawables, one for the β€œpress / focus / select” state and one for each other state (rest):

dashboard_icon_layer_background_selected.xml:

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/dashboard_icon_background_selected" /> <item android:bottom="14dip"> <bitmap android:src="@drawable/btn_star_big_on_pressed" android:gravity="center" /> </item> </layer-list> 

dashboard_icon_layer_background_rest.xml:

 <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/dashboard_icon_background_rest" /> <item android:bottom="14dip"> <bitmap android:src="@drawable/btn_star_big_on_rest" android:gravity="center" /> </item> </layer-list> 

Some features for this particular example:

  • The reason star images are referred to as bitmaps is to prevent Android from scaling them to the full width and height of the container. A lower distance is added to actually center the star relative to the background image (textSize = 12, plus 2 to fill), which, to be honest, is pretty ugly for hard code like this. Without this displacement, centered gravity will place a star-shaped image in the center of the entire container, so that it will add space to which the text is added.
  • Thus, replacing an element with a raster image with <item android:drawable="@drawable/btn_star_big_on_rest" /> will cause the star image to be enlarged. Just try once to understand the effect.
  • This phenomenon is rather unfortunate, since we could refer to another xml, which could be used above, using all the already defined states! That's why I really had to copy two star images from the Android repository: you cannot reference the xml drawable as the source of the bitmap, and the actual images also cannot be publicly referenced. Try replacing the definition of the bitmap with <item android:drawable="@android:drawable/btn_star" /> to see the scalable image, but do not save the predefined states.
  • Perhaps you will encounter the problem of scaling by creating 9 images from star images, creating a StateListDrawable for different states and referring to the resulting xml-object, which can be selected as an element of the layer. Although Android will still stretch the entire image to the full size of the container, 9-ports can only scale transparent pixels.
  • // Edit: I realized that there is another limitation of this approach, since clicking on the text will not change the state of the icon. Perhaps this may be what you need, but personally, I would say that from the point of view of the user it would be reasonable for all this to respond to touch events ...

Hope this makes sense! Just to show you the result: left - everything is at rest, right - the topleft button is pressed.

Project with zip file here

Modified example project

+1
source

Can't you use only TextView and set its background as StateListDrawable ? If you need space for the "icon" above, you can set Gravity of TextView to Bottom and set a fixed height for it.

Edit: Even better, you can use the drawableTop property:

  <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="bottom|center" android:text="Example" android:drawableTop="@drawable/statelist" android:drawablePadding="5dp"/> 

Edit 2: Following the example of Google, you can set the style for Button / TextView. He changed the background color since this is the default system behavior. Try the following:

main_layout.xml

 <?xml version="1.0" encoding="utf-8"?> <org.demo.DashboardLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item1" /> <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item2" /> <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item3" /> <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item4" /> <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item5" /> <TextView style="@style/DashboardTextView" android:drawableTop="@drawable/state_list_drawable" android:text="Item6" /> </org.demo.DashboardLayout> 

And add this to your values/styles.xml :

 <style name="DashboardTextView"> <item name="android:layout_gravity">center_vertical</item> <item name="android:layout_width">wrap_content</item> <item name="android:layout_height">wrap_content</item> <item name="android:gravity">center_horizontal</item> <item name="android:drawablePadding">2dp</item> <item name="android:background">@null</item> <item name="android:clickable">true</item> <item name="android:textColor">#ffffff</item> <!-- White, you can change your text color here --> </style> 
0
source

It seems that this would be easy to solve using 9patch images as resources for your different states and a list of states as your wallpaper or TextView with drawableTop for the icon ... if you don't want the icon to change as well as the background?

0
source

Source: https://habr.com/ru/post/1380868/


All Articles