MysteriesOfButtonsPart1
MysteriesOfButtonsPart1
com.mysteriesofbuttons.part1
/res/layout/activity_main.xml
file and replace all its contents with the following code: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" /> </RelativeLayout>
RelativeLayout
is a layout in which child elements are placed relative to each other, for example, to place a button to the left of another button, etc. You can read more about RelativeLayout
here .Button
is our button. We give it the android:id
attribute, by which we can identify it in the application. The format @+id/
means that a new identifier must be created in the resources. If we specified @id/
, it would mean that the specified identifier should already be in the resources.android:text=""
strings.xml
resources strings.xml
that the application can support more than one language, but more on this in the next part. For now we will show the text directly in the layout in order to improve the visibility of the example.RelativeLayout
and Button
have the attributes android:layout_width
and android:layout_height
. These are the required attributes of any View
. As the name implies, they denote the width and height of the elements, respectively. They can be set in different units, but we do not use specific dimensions, as you might have noticed. We use the match_parent
and wrap_content
.match_parent
means that the element must completely fill its parent horizontally or vertically, depending on whether we specify the width or height.wrap_content
means that the element size should be minimal, but such that the entire contents of the element fit into it.fill_parent
, which means exactly the same as match_parent
. Why use two identical constants? fill_parent
was introduced before API version 8, and since the eighth version is obsolete and not recommended for use. The fact is that for English-speaking developers, match_parent
more accurately reflects the meaning of a constant than fill_parent
.match_parent
and wrap_content
wherever possible, avoiding specifying fixed sizes in every possible way, since Android applications work on devices with very different screen sizes.MainActivity.java
Activity.java: package com.mysteriesofbuttons.part1; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
setContentView(R.layout.activity_main);
activity_main.xml
file in Eclipse and click the Graphical Layout
button:android:gravity
attribute to the button: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:gravity="left|center_vertical" />
|
android:textStyle
, for example, android:textStyle="bold|italic"
. If you need to change the size of the text on the button, the android:textSize
parameter android:textSize
, for example: android:textSize="24sp"
.sp
- Scale-independent Pixels is a unit of measurement based on screen density and font size settings. To make the text look equally good on different screens, it is recommended to set its size exactly in sp
. <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:gravity="left|center_vertical" android:textStyle="bold|italic" android:textSize="24sp" />
icon_phone_normal.png
file:drawable-hdpi
. To set an icon for a button, add the android:drawableLeft
attribute android:drawableLeft
: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:gravity="left|center_vertical" android:textStyle="bold|italic" android:textSize="24sp" android:drawableLeft="@drawable/icon_phone_normal" />
android:drawableLeft
, there are several other attributes that allow you to set icons by placing them in other parts of the button: android:drawableTop
, android:drawableBottom
, android:drawableRight
, android:drawableStart
, android:drawableEnd
.PNG
extension, as well as without the suffix -hdpi
. This is not a typo. The extension is never specified, as there can be no dot in the identifier name. And the -hdpi
suffix will be automatically substituted by Android, since this is the only drawable
directory with the drawable
icon. If the icon were not only in the drawable-hdpi
, but also in drawable-mdpi
, for example, Android would choose the one most suitable for the screen resolution of the device on which the application is running. So you can supply quality products that look equally good on devices with different sizes and screen densities. Google has a very good article on supporting various screens.button_normal.png
image:drawable-hdpi
. In the picture we see black stripes along each of the edges of the screen. They serve to ensure that Android correctly stretches the image to the size we need. The left and upper lines show which area of ​​the image will stretch vertically and horizontally, respectively. And the right and bottom lines show in which area of ​​the stretched image you need to enter the contents of the element, if it has children. At the same time, the black lines themselves are certainly not visible on the resulting image.button_normal.9.png
android:background
attribute to it android:background
: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:gravity="left|center_vertical" android:textStyle="bold|italic" android:textSize="24sp" android:drawableLeft="@drawable/icon_phone_normal" android:background="@drawable/button_normal" />
android:padding
attribute will suit the RelativeLayout
tag: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="6dp" >
dp
? Density-independent pixel - a measure that will automatically scale on devices with different pixel densities of the screen so that the element looks the same. Always use dp
, not px
, when you need to set a specific size, otherwise the application will look good only on your phone.android:padding
attribute sets the same indents on all sides. If we want to set different indents on each side separately, we can use the attributes android:paddingLeft
, android:paddingRight
, android:paddingTop
, android:paddingBottom
, android:paddingStart
and android:paddingEnd
.android:background
all visible elements have, android:drawableLeft
- TextEdit
and so on.state_focused
state. If you press a button with your finger, it will be in the state_pressed
state until we release the finger. How does this help us? We can set the appearance of elements for each state separately. Next we look in detail at how this is done. Please note that the state can be used to draw everything that is visible to the user: icons, images, individual colors, etc.drawable-hdpi
directory:android:background
attribute can only be set once. To get out of the situation, we will create a new selectable selectable resource that combines our 3 images.drawable-hdpi
, select New-> Android XML File. button_background
file name button_background
and select the root element selector
: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > </selector>
state_focused
and state_pressed
: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/button_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/button_focused" android:state_focused="true" /> <item android:drawable="@drawable/button_normal" /> </selector>
button_normal
state is not specified for the image. This means that such a picture will always be used if the button is not able to state_focused
or state_pressed
. In addition to the considered states, you can use several more, the full list is described here.activity_main.xml
and replace the background of the button with button_background
: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="" android:gravity="left|center_vertical" android:textStyle="bold|italic" android:textSize="24sp" android:drawableLeft="@drawable/icon_phone_normal" android:background="@drawable/button_background" />
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="6dp" android:background="#dddddd" >
drawable-hdpi
icon into drawable-hdpi
icon_phone_pressed.png
:icon_phone
selector with the following text: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/icon_phone_pressed" android:state_pressed="true" /> <item android:drawable="@drawable/icon_phone_normal" /> </selector>
drawableLeft
with our new icon_phone
selector: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:gravity="left|center_vertical" android:text="" android:textSize="24sp" android:textStyle="bold|italic" />
color
subdirectory in the res
directory, on the same level as the drawable-hdpi
:color
directory, create an Android XML File with the name text_color
and the root selector
element: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:color="@android:color/white" android:state_pressed="true" /> <item android:color="#484848" /> </selector>
state_pressed
state and the default state are set here. The colors here are defined in two ways: android:color="@android:color/white"
and android:color="#484848"
android
namespace. In the second, we specify the RGB color value in hexadecimal. In this case, we set the default color to the same color as the frame in the unpressed form.android:textColor="@color/text_color"
: <Button android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:gravity="left|center_vertical" android:text="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" />
OnClickListener
event OnClickListener
and alternately change the drawableRight
icon. It is a working option. But what to do if there are not one buttons on a page, but 10 buttons, and in general a button can be not only on this page. Then our path will lead to duplication of code that will copy-paste to wander from one Activity to another, not the most beautiful solution. And if you need to change something, you will have to change in many places. I would like to avoid this.ToggleButton
. This button can be in two states: on and off. Replace the Button
tag with a ToggleButton
in our layout: <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:gravity="left|center_vertical" android:text="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" />
ToggleButton
inherits from Button
, all Button
attributes apply to it, but there is a nuance. ToggleButton
ignores the text
attribute, but introduces two new ones: textOn
and textOff
. They set the text for the on and off states, respectively. But we want to display the state of the picture, and the text we want to leave as is. Therefore, we will prescribe our text to both attributes, and remove the text
attribute as superfluous: <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:gravity="left|center_vertical" android:textOn="" android:textOff="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" />
icon_on_normal.png
, icon_on_pressed.png
, icon_off_normal.png
and drawable-hdpi
resources into drawable-hdpi
resources (listed in the order listed):drawable
selector named icon_on_off
: <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/icon_on_pressed" android:state_checked="true" android:state_pressed="true" /> <item android:drawable="@drawable/icon_on_normal" android:state_checked="true" /> <item android:drawable="@drawable/icon_off_pressed" android:state_checked="false" android:state_pressed="true" /> <item android:drawable="@drawable/icon_off_normal" android:state_checked="false" /> </selector>
android:state_checked="true"
corresponds to the button in On mode, and android:state_checked="false"
- to the button in Off mode.android:drawableRight="@drawable/icon_on_off"
attribute to it android:drawableRight="@drawable/icon_on_off"
. For clarity, I added it immediately after android:drawableLeft
: <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:drawableRight="@drawable/icon_on_off" android:gravity="left|center_vertical" android:textOn="" android:textOff="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" />
isChecked()
button: true
- on, false
- off. Add the attribute android:onClick="onToggleButtonClick"
to our button: <ToggleButton android:id="@+id/act_main_btn_telephony" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/button_background" android:drawableLeft="@drawable/icon_phone" android:drawableRight="@drawable/icon_on_off" android:gravity="left|center_vertical" android:textOn="" android:textOff="" android:textSize="24sp" android:textStyle="bold|italic" android:textColor="@color/text_color" android:onClick="onToggleButtonClick" />
MainActivity.java
add the appropriate method: package com.mysteriesofbuttons.part1; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Toast; import android.widget.ToggleButton; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void onToggleButtonClick(View button) { Toast.makeText( getApplicationContext(), Boolean.toString(((ToggleButton) button).isChecked()), Toast.LENGTH_SHORT).show(); } }
true
/ false
text prompts at the bottom of the screen. This means that everything works.strings.xml
styles.xml
dimens.xml
Source: https://habr.com/ru/post/206012/
All Articles