按钮触控
Button
由TextView演变而来
- Button拥有默认的按钮背景,而TextView默认无背景
- Button的内部文本默认居中对齐,而TextView的内部文本默认靠左对齐
- Button会默认将英文字母转为大写,而TextView保持原始的英文大小写
Button新增属性
- textAllCaps属性,它指定了是否将英文字母转为大写,为true是表示自动转为大写,为false表示不做大写转换。
- onClick属性,它用来接管用户的点击动作,指定了点击按钮时要触发哪个方法
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/blue" android:gravity="center" android:text="原始的TextView" android:textColor="@color/red" android:textSize="20sp"> </TextView> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="doClick" android:text="dianji" android:textAllCaps="false" android:textColor="@color/red" android:textSize="20sp" /> <TextView android:id="@+id/view_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/gray" android:text="点击结果" android:textColor="@color/red" android:textSize="20sp"> </TextView>
获取当前时间工具类
public class DataUtil { public static String getNowTime(){ //获取当前的时间 SimpleDateFormat sdf = new SimpleDateFormat("yy/mm/dd HH:mm:ss"); return sdf.format(new Date()); } }
public class ButtomStyleActivity extends AppCompatActivity { private TextView time_result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_buttom_style); time_result = findViewById(R.id.view_time); } /** * 点击的方法 * @param view */ public void doClick(View view){ String str = String.format("%s 点击了 %s", DataUtil.getNowTime(), ((Button) view).getText()); time_result.setText(str); } }
时间不是本机时间,二十虚拟手机时间
点击事件和长按事件
- 监听器,意思是专门监听控件的动作行为。只有控件发生了指定的动作,监听器才会触发开关去执行对应的代码逻辑。
- 按钮控件两种常用的监听器
- 点击监听器,通过 setOnClickListener 方法设置。按钮被按住少于500毫秒时,会触发点击事件。
public class ButtonClickActivity extends AppCompatActivity implements View.OnClickListener{ private TextView result; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_click); result = findViewById(R.id.tv_result); Button b1 = findViewById(R.id.single_button); b1.setOnClickListener(new MyOnClickListener(result)); Button public_button = findViewById(R.id.public_button); public_button.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.public_button){ String str = String.format("%s 点击了 %s", DataUtil.getNowTime(), ((Button) v).getText()); result.setText(str); } } /** * 实现监听方法 静态内部类:减少内存泄露 */ static class MyOnClickListener implements View.OnClickListener{ private final TextView result; public MyOnClickListener(TextView result) { this.result = result; } @Override public void onClick(View v) { String str = String.format("%s 点击了 %s", DataUtil.getNowTime(), ((Button) v).getText()); result.setText(str); } } }
<Button android:id="@+id/single_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="公共事件" android:background="@color/blue" android:layout_margin="5dp" android:textSize="20sp" /> <Button android:id="@+id/public_button" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/blue" android:layout_margin="5dp" android:text="指定点击监听器" android:textSize="20sp" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:padding="2dp" android:text="显示内容结果" android:textColor="@color/black" android:textSize="20sp" />
长按监听器,通过 setOnLongClickListener 方法设置。按钮被按住超过500毫秒时,会触发长按事件。
public class ButtonLongClickActivity extends AppCompatActivity { @SuppressLint("WrongViewCast") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_long_click); Button long_click = findViewById(R.id.long_click); TextView result = findViewById(R.id.tv_result); //lambda表达式 long_click.setOnLongClickListener(v -> { String str = String.format("%s 点击了 %s", DataUtil.getNowTime(), ((Button) v).getText()); result.setText(str); return true; }); } }
按钮恢复与禁用
两种状态
- 可以状态按钮:按钮允许点击,点击按钮会触发点击事件,同时按钮文字为正常的黑色
- 不可以状态按钮:按钮不允许点击,即使点击也没反应,同时按钮文字为灰色
是否允许点击
- enable属性:true:可以点击,false:不可以点击
public class ButtonEanbleActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_test; private TextView tv_result1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_button_eanble); Button btn_enable = findViewById(R.id.btn_enable); Button btn_disable = findViewById(R.id.btn_disable); btn_test = findViewById(R.id.btn_test); tv_result1 = findViewById(R.id.tv_result1); //监控事件 btn_enable.setOnClickListener(this); btn_disable.setOnClickListener(this); btn_test.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ //启动按钮 case R.id.btn_enable: btn_test.setEnabled(true); btn_test.setTextColor(Color.BLACK); break; //禁用按钮 case R.id.btn_disable: btn_test.setEnabled(false); btn_test.setTextColor(Color.GRAY); break; //测试按钮 case R.id.btn_test: String str = String.format("%s 点击了 %s", DataUtil.getNowTime(), ((Button) v).getText()); tv_result1.setText(str); break; } } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:id="@+id/btn_enable" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:layout_weight="1" android:text="启动测试按钮" android:textColor="@color/black" android:textSize="20sp" /> <Button android:id="@+id/btn_disable" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_margin="5dp" android:layout_weight="1" android:text="禁用测试按钮" android:textColor="@color/black" android:textSize="20sp" /> </LinearLayout> <Button android:id="@+id/btn_test" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:enabled="false" android:text="测试按钮" android:textColor="@color/gray" android:textSize="20sp" /> <TextView android:id="@+id/tv_result1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="5dp" android:gravity="center" android:text="查看测试结果" android:textColor="@color/black" android:textSize="20sp" /> </LinearLayout>
图像显示
ImageView
图片位置:
设置方式
- 在XML文件中,通过属性 android:src 设置图片资源,属性值格式形如:@drawable/ 不含扩展名的图片名称
在Java代码中,调用 setlmageResource 方法设置图片资源,方法参数格式形如:R.drawable.不含扩展名的图片名称
scaleType属性
默认是居中显示
ImageButton
图片显示按钮,继承于ImageVIew
ImageButton与Button区别
Button 既可显示文本也可显示图片,lmageButton 只能显示图片不能显示文本
ImageButton 上的图像可按比例缩放,而 Button 通过背景设置的图像会拉伸变形
Button 只能靠背景显示一张图片,而 lmageButton 可分别在前景和背景显示图片,从而实现两张图片叠加的效果
imageButton与ImageView区别
lmageButton有默认的按钮背景,ImageView默认无背景。
lmageButton默认的缩放类型为center,而ImageView默认的缩放类型为fitCenter。
同时展示文本和图像
利用LinearLayout对 ImageView 和 TextView 组合布局。
通过按钮控件Button的 drawable *** 属性设置文本周围的图标
drawableTop:指定文字上方的图片
drawableBottom:指定文字下方的图片
drawableLeft:指定文字左边的图片
drawableRight:指定文字右边的图片
drawablePadding:指定图片与文字的间距。
取消掉按钮的默认背景颜色
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/white" android:drawableLeft="@drawable/info" android:drawablePadding="5dp" android:text="图标左边" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/white" android:drawableRight="@drawable/waring" android:drawablePadding="5dp" android:text="警告" android:textColor="@color/red" android:textSize="20sp" />
计算器项目实战
计算器的界面分为两大部分,第一部分是上方的计算表达式,既包括用户的按键输入,也包括计算结果数字;第二部分是下方的各个按键,例如:从0到9的数字按钮、加减乘除与等号、正负号按钮、小数点按钮、求倒数按钮、平方按钮、开方按钮以及退格、清空、取消等控制按钮
分析
线性布局LinearLayout:计算器的整体布局是从上到下排列着的
网格布局GridLayout:计算器下半部分的几排按钮,正好成五行四列表格分布,适合采用GridLayout
滚动视图ScrollView:计算器界面如果超出屏幕大小,就要支持滚动
文本视图TextView:计算结果文本需要使用TextView,且文字靠下靠右显示
按钮Button:用于0-9的数字按键,以及加减乘除等运算按键
图像按钮ImageButton:开根号的运算符虽然能够打出来,但是右上角少了一横,所以该按钮要用一张标准的开根号图片显示
Activity
启停活动
- 从当前页面跳转到新页面
startActivity(new Intent(源页面.this,目标页面.class))
- 从当前页面回到上一个页面,相当于关闭当前页面
finish();结束当前活动页面
public class ActStartActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act_start); findViewById(R.id.next_page).setOnClickListener(this); } @Override public void onClick(View v) { startActivity(new Intent(this, ActFinishActivity.class)); } }
public class ActFinishActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act_finish); findViewById(R.id.back_button).setOnClickListener(this); findViewById(R.id.back_jiantou).setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.back_button ||v.getId() == R.id.back_jiantou ){ finish(); } } }
Activity 生命周期
生命周期图
- onCreate:创建活动。把页面布局加载进内存,进入了初始状态。
onStart:开始活动。把活动页面显示在屏幕上,进入了就绪状态。
onResume:恢复活动。活动页面进入活跃状态,能够与用户正常交互,例如允许响应用尸的点击动作、允许用户输入文字等等。
onPause:暂停活动。页面进入暂停状态,无法与用户正常交互。
onStop:停止活动。页面将不在屏幕上显示。
onDestroy:销毁活动。回收活动占用的系统资源,把页面从内存中清除。
onRestart:重启活动。重新加载内存中的页面数据。
onNewlntent:重用已有的活动实例。
如果一个Activity已经启动过,并且存在当前应用的Activity任务栈中,启动模式为singleTask,singleInstance或singleTop(此时已在任务栈顶端),那么在此启动或回到这个Activity的时候,不会创建新的实例,也就是不会执行onCreate方法,而是执行
onNewlntent方法。
活动状态变迁
- 打开新页面流程
- onCreate ==> onStrat ==> onResume
- 关闭页面流程图
- onPause ==> onStop ==> onDestroy
Activity 启动模式
- 打开两个活动,活动栈的变动(先进后出)
- 依次结束已打开的两个活动,活动栈变动情况
启动模式在清单文件中设置
<android:launchMode="standard">
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u0fzjFcH-1665663924472)(AndroidApp.assets/image-20220808105436837.png)]
默认启动模式 standard
- Activity 依次启动,依次被压入栈中
栈顶复用模式 singleTop
- 栈顶新建Activity(目标Activity),就不会复建新的Activity
应用场景
开启渠道多,多应用开启调用的 Activity ,可以避免已建的Activity被复用。
栈内复用模式 singleTask
singleTask模式下,如果 task栈内存在目标Activity实例,则将task内的对应Activity实例之上的所有Activity 弹出栈,并将对应Activity置于栈顶,获得焦点。
应用场景
- 程序主页面,比希望被创建多次
- 耗费系统资源的Activity
全局唯一模式 singleInstance
在该模式下,我们会为目标Activity创建一个新的Task栈,将目标Activity放入新的Task,并让目标Activity获得焦点。新的Task有且只有这一个Activity 实例。
如果已经创建过目标Activity实例,则不会创建新的Task,而是将以前创建过的Activity 唤醒。
动态启动模式
Intent.FLAG_ACTIVITY_NEW_TASK:开辟一个新的任务栈
Intent.FLAG_ACTIVITY_SINGLE_TOP:当栈顶为待跳转的活动实例之时,则重用栈顶的实例
Intent.FLAG_ACTIVITY_CLEAR_TOP:当栈中存在待跳转的活动实例时,则重新创建一个新实例, 并清除原实例上方的所有实例 l
Intent.FLAG_ACTIVITY_NO_HISTORY:栈中不保存新启动的活动实例
Intent.FLAG_ACTIVITY_CLEAR_TASK:跳转到新页面时,栈中的原有实例都被清空
传递信息
Intent
- Intent是各个组件之间信息沟通的桥梁,用于组件之间进行通信
- 标明本次通信请求从哪里来、到哪里去、要怎么走。
- 发起方携带本次通信需要的数据内容,接收方从收到的意图中解析数据。
- 发起方若想判断接收方的处理结果,意图就要负责让接收方传回应答的数据内容
Inten组成部分
显示Intent
三种构造方法:
- 在Intent的构造函数中指定
- 调用意图对象的setClass方法指定
- 调用意图对象的setComponent方法指定
@Override public void onClick(View v) { //1. startActivity(new Intent(this, ActFinishActivity.class)); //2. Intent intent = new Intent(); intent.setClass(this,ActFinishActivity.class); //3. Intent intent = new Intent(); ComponentName componentName = new ComponentName(this, ActFinishActivity.class); intent.setComponent(componentName); startActivity(intent); }
隐式Intent
- 没有明确指定跳转目标,给出动作字符系统自动匹配:模糊匹配
常用动作
@Override public void onClick(View v) { String phoneNo = "11112515"; Intent intent = new Intent(); switch (v.getId()) { case R.id.jump_call_page: //设置意图作为动作准备拨号 intent.setAction(Intent.ACTION_DIAL); //声明一个拨号的Uri Uri uri = Uri.parse("tel" + phoneNo); intent.setData(uri); startActivity(intent); break; case R.id.jump_info_page: //设置意图作为动作准备拨号 intent.setAction(Intent.ACTION_SENDTO); //声明一个拨号的Uri Uri uri_sen_info = Uri.parse("info" + phoneNo); intent.setData(uri_sen_info); startActivity(intent); break; case R.id.jump_accpect_info_page: //设置意图作为动作准备拨号 intent.setAction(Intent.ACTION_ANSWER); //声明一个拨号的Uri Uri uri_answer = Uri.parse("info" + phoneNo); intent.setData(uri_answer); startActivity(intent); break; } }
向下一个发送数据
- Intent使用Bundle对象存放待传递的数据信息
- Bundle 对象的数据类型
- 在代码中发送消息包裹,调用意图对象的putExtras方法,即可存入消息包裹。
- 在代码中接收消息包裹,调用意图对象的getExtras方法,即可取出消息包裹。
@Override public void onClick(View v) { Intent intent = new Intent(this, ActReceiveActivity.class); Bundle bundle = new Bundle(); //发送的数据 bundle.putString("request_time", DataUtil.getNowTime()); bundle.putString("request_content",sent_text.getText().toString()); //存入包裹 intent.putExtras(bundle); startActivity(intent); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act_receive); TextView receive_text = findViewById(R.id.receive_text); //从上一个页面中传来的意图中获取包裹 Bundle bundle = getIntent().getExtras(); String request_time = bundle.getString("request_time"); String request_content = bundle.getString("request_content"); String format = String.format("收到消息:\n请求时间:%s\n请求内容:%s", request_time, request_content); receive_text.setText(format); }
向上一个Activity 返回数据
上一个页面打包好请求数据,调用 startActivityForResult 方法执行跳转动作
下一个页面接收并解析请求数据,进行相应处理
下一个页面在返回上一个页面时,打包应答数据并调用 setResult 方法返回数据包裹
上一个页面重写方法 onActivityResult,解析获得下一个页面的返回数据
请求信息
import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.TextView; import com.example.activity.utils.DataUtil; public class ActRequestActivity extends AppCompatActivity implements View.OnClickListener { private String Request = " 可以去你家睡吗?"; private ActivityResultLauncher<Intent> register; private TextView response_show; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act_request); TextView request_text = findViewById(R.id.request_text); request_text.setText("待发送的消息:" + Request); response_show = findViewById(R.id.response_show); //按钮监听 findViewById(R.id.request_but).setOnClickListener(this); //response回调方法 register = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result != null) { Intent intent = result.getData(); if (intent != null && result.getResultCode() == Activity.RESULT_OK) { Bundle bundle = intent.getExtras(); String request_time = bundle.getString("request_time", DataUtil.getNowTime()); String request_content = bundle.getString("request_content"); String desc = String.format("request收到的消息:\n请求时间:%s\n请求内容:%s", request_time, request_content); //把返回消息的详细信息显示 response_show.setText(desc); } } }); } @Override public void onClick(View v) { //构建显示意图 Intent intent = new Intent(this, ActResponseActivity.class); Bundle bundle = new Bundle(); //发送的数据 bundle.putString("request_time", DataUtil.getNowTime()); bundle.putString("request_content", Request); intent.putExtras(bundle); //存入包裹 intent.putExtras(bundle); register.launch(intent); } }
响应信息
public class ActResponseActivity extends AppCompatActivity implements View.OnClickListener { private static final String Response_back = "不可以!!"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_act_response); TextView request_text = findViewById(R.id.request_text); //从上一个页面中传来的意图中获取包裹 Bundle bundle = getIntent().getExtras(); String request_time = bundle.getString("request_time"); String request_content = bundle.getString("request_content"); String format = String.format("response收到的消息:\n请求时间:%s\n请求内容:%s", request_time, request_content); //请求的信息显示在指定的文本上 request_text.setText(format); findViewById(R.id.response_but).setOnClickListener(this); TextView back_text = findViewById(R.id.response_back); back_text.setText("要返回给request的消息:" + Response_back); } @Override public void onClick(View v) { Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putString("request_time", DataUtil.getNowTime()); bundle.putString("request_content", Response_back); intent.putExtras(bundle); setResult(Activity.RESULT_OK, intent); //结束 finish(); } }
附加信息
资源文件配置字符串
- res\values\strings.xml 可用来配置字符串形式的参数。
- 在活动页面的Java代码中,调用 getString 方法即可根据 R.string.参数名称 获得指定 参数的字符串值。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_read_sourse_striing); TextView resource_string = findViewById(R.id.string_source); //从string.xml文件中获取字符串值 String go_home = getString(R.string.go_home); resource_string.setText(go_home); }
<resources> <string name="app_name">Activity</string> <string name="go_home">我想和你回家!!!</string> </resources>
利用元数据传递配置信息
- 在activity节点内部添加meta-data标签,通过属性name指定元数据的名称,通过属性 value 指定元数据的值
<meta-data android:name="go" android:value="和你回家"/>
- 调用 getPackageManager 方法获得当前应用的包管理器;
- 调用包管理器的 getActivityInfo 方法获得当前活动的信息对象;
- 活动信息对象的 metaData 是 Bundle 包裹类型,调用包裹对象的 getString 即可获得指 定名称的参数值;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_meta_data); TextView meta_source_value = findViewById(R.id.meta_source_value); //获取包管理器 PackageManager packageManager = getPackageManager(); // try { ActivityInfo packageInfo = packageManager.getActivityInfo(getComponentName(), PackageManager.GET_META_DATA); Bundle bundle = packageInfo.metaData; String go = bundle.getString("go"); meta_source_value.setText(go); } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); } }
创建图标长安快捷菜单
新建 xml文件夹
shortcut.xml
<?xml version="1.0" encoding="utf-8"?> <shortcuts xmlns:android="http://schemas.android.com/apk/res/android"> <shortcut android:enabled="true" android:icon="@mipmap/ic_launcher" android:shortcutId="first" android:shortcutLongLabel="@string/first_long" android:shortcutShortLabel="@string/first_short"> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.activity.ActStartActivity" android:targetPackage="com.example.activity" /> <categories android:name="android:shortcuts.conversation" /> </shortcut> <shortcut android:enabled="true" android:icon="@mipmap/ic_launcher" android:shortcutId="second" android:shortcutLongLabel="@string/second_long" android:shortcutShortLabel="@string/second_short"> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.activity.ActSentActivity" android:targetPackage="com.example.activity" /> <categories android:name="android:shortcuts.conversation" /> </shortcut> <shortcut android:enabled="true" android:icon="@mipmap/ic_launcher" android:shortcutId="third" android:shortcutLongLabel="@string/third_long" android:shortcutShortLabel="@string/third_short"> <intent android:action="android.intent.action.VIEW" android:targetClass="com.example.activity.JumpFirstActivity" android:targetPackage="com.example.activity" /> <categories android:name="android:shortcuts.conversation" /> </shortcut> </shortcuts>
strings.xml
<string name="first_short">first</string> <string name="first_long">启停活动</string> <string name="second_short">second</string> <string name="second_long">发送数据</string> <string name="third_short">third</string> <string name="third_long">跳转页面</string>
要的页面必须存在(配置文件中,列表清单文件 AndroidManifest.xml
),才可以进行操作
中级控件
系统框架
图形定制 Drawable
- 图片文件一般存放在 drawable 目录下
- 视图的 background 属性、ImageView 和 ImageButton 的 src 属性、TextView 和 Button 四个方向的 drawable 系列属性都可以引用图形文件
形状图形
几何图形
Shape的主要包括四种图形
rectangle:矩形。默认值
oval:椭圆。此时corners节点会失效
line:直线。此时必须设置stroke节点,不然会报错
ring:圆环
图形的规格定义
size(尺寸),它描述了形状图形的宽高尺寸。
height:像素类型,图形高度。
width:像素类型,图形宽度。
stroke(边框),它描述了形状图形的描边规格
color:颜色类型,描边的颜色。 dashGap:像素类型,每段虚线之间的间隔。
dashWidth:像素类型,每段虚线的宽度。若dashGap和dashWidth有一个值为0,则描边为实 线。
width:像素类型,描边的厚度。
corners(圆角),它描述了形状图形的圆角大小。
bottomLeftRadius:像素类型,左下圆角的半径。
bottomRightRadius:像素类型,右下圆角的半径。
topLeftRadius:像素类型,左上圆角的半径。
topRightRadius:像素类型,右上圆角的半径。
radius:像素类型,4个圆角的半径(若有上面4个圆角半径的定义,则不需要radius定义)
solid(填充),它描述了形状图形的填充色彩。
color:颜色类型,内部填充的颜色。
padding(间隔),它描述了形状图形与周围边界的间隔
top:像素类型,与上方的间隔。
bottom:像素类型,与下方的间隔
left:像素类型,与左边的间隔
right:像素类型,与右边的间隔
gradient(渐变),它描述了形状图形的颜色渐变。
angle:整型,渐变的起始角度:为0时表示时钟的9点位置,值增大表示往逆时针方向旋转。
type:字符串类型,渐变类型
public class DrawableShapeActivity extends AppCompatActivity implements View.OnClickListener { private View view; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawable_shape); view = findViewById(R.id.v_content); findViewById(R.id.circular).setOnClickListener(this); findViewById(R.id.ellipse).setOnClickListener(this); //默认情况下,为圆角矩形 view.setBackgroundResource(R.drawable.shape_circular); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.circular: view.setBackgroundResource(R.drawable.shape_circular); break; case R.id.ellipse: view.setBackgroundResource(R.drawable.shape_ellipse); break; } } }
shape_circular.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <!--指定形状内部的填充颜色--> <solid android:color="@color/gold"/> <!--指定形状轮廓(边框大小、颜色)的颜色--> <stroke android:width="2dp" android:color="@color/red" /> <!--指定圆角半径--> <corners android:radius="50dp"/> </shape>
shape_ellispce.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <!--指定形状内部的填充颜色--> <solid android:color="@color/purple_500" /> <!--指定形状轮廓(边框大小、颜色)的颜色--> <stroke android:width="2dp" android:color="@color/red" /> </shape>
九宫格图片
- 尺寸太小,则系统会自动拉伸图片使之填满背景
- 防止拉伸图片变形变模糊
必须的 .png 格式的图片
状态列表图形
- 按钮按下形状、颜色改变
- 不仅适用于Button,还有其它的控件也可以
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <!--按钮按下之后改变的样式--> <item android:drawable="@drawable/view1" android:state_pressed="true" /> <!--没按时显示的样式--> <item android:drawable="@drawable/btn1" /> </selector>