目录
- 简介
- Button的创建
-
- 使用XML布局创建
- 使用Java代码创建
-
- 在.xml文件已有的ViewGroup中添加Button:
- 动态创建ViewGroup并添加Button:
- Button的监听
-
- View.OnClickListener
- View.OnLongClickListener
- View.OnTouchListener
- 设置监听器的方式
- Button的继承
简介
Button继承自
TextView
。Button提供的基本响应有:
单击(Click)
和
长按(LongClick)
。可以通过触摸事件管理实现自定义响应,例如双击、滑动等。
Button的创建
使用XML布局创建
使用XML布局创建Button的核心在于
XML布局文件
和
findviewById()
方法。
activity_main.xml
<LinearLayout ...>
<Button
android:id="@+id/btn_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android_background="#50ff00ff"
android:text="Button1"
android:gravity="center"
android:textAllCaps="false"
android:clickable="true"/>
</LinearLayout>
MainActivity.java
import...
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_1=(Button)findviewById(R.id.btn_1);
}
}
代码中使用
findviewById()
方法创建了一个名为
btn_1
的Button对象。可以使用此对象的各种方法为按钮设置监听器(例如
btn_1.setOnClickListener(this)
);改变按钮的背景、文字、位置等(例如
btn_1.setBackgroundColor(0x50ff00ff)
)。
使用
findviewById()
注意进行强制类型转换。
使用Java代码创建
使用Java代码可以动态地创建Button。可以使用Java代码在.xml文件已有的ViewGroup中创建Button;也可以使用Java代码创建一个新的ViewGroup,将Button添加至新的ViewGroup中。
在.xml文件已有的ViewGroup中添加Button:
步骤:
①为.xml文件中的目标ViewGroup添加
android:id
属性。
<LinearLayout
android:id="@+id/linearlayout_1"
...>
...
</LinearLayout>
②使用
findviewById()
获得目标ViewGroup对象。注意进行强制类型转换。
LinearLayout linearlayout_1=
(LinearLayout)findviewById(R.id.linearlayout_1);
③使用构造函数
Button(Context context)
创建Button对象。由于
Width
和
Height
等是View的必须属性,需要先使用ViewGroup.LayoutParams创建布局参数对象,再使用
setLayoutParams()
方法为Button设置
Width
和
Height
等必须属性。例如:
Button btn_1=new Button(this);
LinearLayout.LayoutParams params_btn =
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params_btn.topMargin=200;
params_btn.bottomMargin=200;
btn_1.setLayoutParams(params_btn);
④使用
addView()
方法向目标ViewGroup中添加Button
对于
LinearLayout
而言,最先被
addView(View v)
方法添加到ViewGroup的View摆放在最上面,也就是View的拜访顺序遵循View的添加顺序。
⑤设置Button的外观。到这一步,可以使用Button对象的各种方法为按钮设置监听器、改变外观等。
btn_1.setText("Button1");
btn_1.setBackgroundColor(0x50ff00ff);
btn_1.setOnClickListener(this);
⑥为Button设置id。使用Java代码为新创建的Button设置id,需要在
res/values/
路径下创建一个
Values resource
xml资源文件,并创建id值。使用
R.id.name
引用id值。例:
<resources>
<item name="btn_1" type="id"/>
<item name="btn_2" type="id"/>
</resources>
使用Button对象的
setId(int id)
方法设置id。例:
⑦移除Button。可以使用ViewGroup对象中的
removeView(View view)
方法动态地移除指定View,也可以使用
removeAllViews()
方法移除ViewGroup中的所有View。例:
linearlayout_1.removeView(btn_1);
linearlayout_1.removeAllViews();
完整代码:
button_id.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="btn_1" type="id"/>
<item name="btn_2" type="id"/>
</resources>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/linearlayout_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="linearlayout_2"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_margin="20dp"/>
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//find ViewGroup in activity_main.xml
LinearLayout linearlayout_1=
(LinearLayout)findviewById(R.id.linearlayout_1);
LinearLayout linearlayout_2=
(LinearLayout)findviewById(R.id.linearlayout_2);
//create new buttons
Button btn_1=new Button(this);
Button btn_2=new Button(this);
LinearLayout.LayoutParams params_btn=
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params_btn.topMargin=200;
params_btn.bottomMargin=200;
btn_1.setLayoutParams(params_btn);
btn_2.setLayoutParams(params_btn);
//add button to ViewGroup
linearlayout_1.addView(btn_1);
linearlayout_2.addView(btn_2);
//set button's look
btn_1.setId(R.id.btn_1);
btn_1.setText("Button1");
btn_1.setBackgroundColor(0x50ff00ff);
btn_2.setId(R.id.btn_2);
btn_2.setText("Button2");
btn_2.setBackgroundColor(0x5000ffff);
}
}
动态创建ViewGroup并添加Button:
动态创建ViewGroup的方法与动态创建Button同理,例如:
LinearLayout linearlayout_1=new LinearLayout(this);
LinearLayout.LayoutParams params=
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
linearlayout_1.setLayoutParams(params);
使用ViewGroup对象的
addView(View view)
方法向父ViewGroup中添加新创建的子ViewGroup。例:
使用ViewGroup对象的
addView(View view)
方法向新创建的子ViewGroup中添加Button。例:
完整代码:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="@+id/linearlayout_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//find ViewGroup in activity_main.xml
LinearLayout linearlayout_main=
(LinearLayout)findviewById(R.id.linearlayout_main);
//create a new ViewGroup
LinearLayout linearlayout_1=new LinearLayout(this);
LinearLayout.LayoutParams params=
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
params.topMargin=200;
linearlayout_1.setLayoutParams(params);
Button btn_1=new Button(this);
Button btn_2=new Button(this);
LinearLayout.LayoutParams params_btn=
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
btn_1.setLayoutParams(params_btn);
btn_1.setText("Button1);
btn_2.setLayoutParams(params_btn);
btn_1.setText("Button2);
//add views
linearlayout_main.addView(btn_1);
linearlayout_main.addView(linearlayout_1);
linearlayout_1.addView(btn_2);
}
}
Button的监听
View.OnClickListener
View.OnClickListener
是按钮点击监听器。充当
OnClickListener
的对象类需要实现
View.OnClickListener
接口并重写
onClick()
方法。例:
public class MyCLickListener implements View.OnClickListener {
...
@Override
public void onClick(View v) {
...
}
}
Button对象通过
setOnClickListener()
方法设置点击监听器。例:
在重写的
onClick()
方法中使用
getId()
方法判断响应点击的按钮。例:
@Override
public void onClick(View v) {
if(v.getId()==R.id.btn_1) {...}
else if(v.getId()==R.id.btn_2) {...}
...
}
View.OnLongClickListener
View.OnLongClickListener
是按钮长按监听器。充当
OnLongClickListener
的对象类需要实现
View.OnLongClickListener
接口并重写
onLongClick()
方法。例:
public class MyLongClickListener implements View.OnLongClickListener {
...
@Override
public boolean onLongClick(View v) {
...
return true/false;
}
}
Button对象通过
setOnLongClickListener()
方法设置长按监听器。例:
在重写的
onLongClick()
方法中使用
getId()
方法判断响应长按的按钮。例:
@Override
public boolean onLongClick(View v) {
if(v.getId()==R.id.btn_1) {...}
else if(v.getId()==R.id.btn_2) {...}
return true/false;
}
onLongClick()
返回
false
则长按之后继续响应点击,即
onLongClick()
调用后会继续调用
onClick()
;返回
true
则长按之后不响应点击,即
onLongClick()
调用后不会再调用
onClick()
。
View.OnTouchListener
View.OnTouchListener
是按钮触摸监听器。充当
OnTouchListener
的对象类需要实现
View.OnTouchListener
接口并重写
onTouch()
方法。例:
public class MyTouchListener implements View.OnTouchListener {
...
@Override
public boolean onTouch(View v,MotionEvent event) {
...
return true/false;
}
}
Button对象通过
setOnTouchListener()
方法设置触摸监听器。例:
在重写的
onTouch()
方法中使用
getId()
方法判断响应触摸的按钮。使用
getAction()
方法判断触摸事件的类型,触摸事件的类型有
ACTION_DOWN(手指按下)
、
ACTION_MOVE(手指移动)
、
ACTION_UP(手指离开)
、
ACTION_CANCEL(触摸事件被拦截)
。例:
@Override
public boolean onTouch(View v,MotionEvent event) {
if(v.getId()==R.id.btn_1) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {...}
else if(event.getAction()==MotionEvent.ACTION_MOVE) {...}
else if(event.getAction()==MotionEvent.ACTION_UP) {...}
else if(event.getAction()==MotionEvent.ACTION_CANCEL) {...}
}
else if(v.getId()==R.id.btn_2) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {...}
else if(event.getAction()==MotionEvent.ACTION_MOVE) {...}
else if(event.getAction()==MotionEvent.ACTION_UP) {...}
else if(event.getAction()==MotionEvent.ACTION_CANCEL) {...}
}
...
}
onTouch()
返回
false
,系统调用完
onTouch()
后会继续调用
onLongClick()
和
onClick()
;返回
true
则系统调用完
onTouch()
后不会调用
onLongClick()
和
onClick()
。
系统调用监听方法的先后顺序:
onTouch()
⇨
onLongClick()
⇨
onClick()
。
设置监听器的方式
①使用
当前Activity对象
作为按钮监听器:
MainActivity.java
public class MainActivity extends Activity
implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button btn_1=(Button)findviewById(R.id.btn_1);
btn_1.setOnClickListener(this);
...
}
@Override
public void onCLick(View v) {
...
}
}
②使用
内部类对象
作为按钮监听器:
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button btn_1=(Button)findviewById(R.id.btn_1);
btn_1.setOnClickListener(new MyClickListener());
...
}
private class MyClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
...
}
}
}
③使用
匿名内部类对象
作为按钮监听器:
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button btn_1=(Button)findviewById(R.id.btn_1);
btn_1.setOnClickListener(new View.OnClickListener(){
...
@Override
public void onClick(View v) {
...
}
});
...
}
}
④使用
外部类对象
作为按钮监听器:
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button btn_1=(Button)findviewById(R.id.btn_1);
btn_1.setOnCLickListener(new MyClickListener());
...
}
...
}
MyClickListener.java
public class MyClickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
...
}
...
}
⑤使用xml属性设置Click监听方法:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout...>
...
<Button
...
android:id="@+id/btn_1"
android:onClick="MyClick"
.../>
...
</LinearLayout>
MainActivity.java
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
Button btn_1=(Button)findviewById(R.id.btn_1);
...
}
public void MyClick(View v) {
if(v.getId()==R.id.btn_1) {...}
...
}
...
}
说明:
activity_main.xml
中的
android:onClick="MyClick"
表示使用Button的
android:onClick
属性为Button设置了一个名为
MyClick
的监听方法。使用这种方式必须定义一个同名方法,在本例中即为:
public void MyClick(View v) {...}
。在这个方法中可以使用
getId()
方法判断响应点击的按钮。
注意:只有Click可以使用Button的xml属性设置监听,LongClick和Touch没有这种设置方式。
android:onClick
属性的系统采用优先级低于其它监听方式,即一个Button同时设置
android:onClick
属性与其它监听方式时,系统会优先采用其它监听方式。
Button的继承
自定义Button时会用到Button的继承。AndroidStudio要求使用
AppCompatButton
代替
Button
用以自定义Button类的继承。对于开发者而言,自定义Button中最有意义的方法是
构造函数
和
onTouchEvent()
。
以下将以简单实例代码展示Button继承的用法。代码实现:触摸按钮时按钮颜色改变,松开按钮后按钮颜色恢复。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
...
android:id="@+id/linearlayout_main">
...
</LinearLayout>
button_id.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="btn_1" type="id"/>
...
</resources>
MyButton.java
import...
import androidx.appcompat.widget.AppCompatButton;
public class MyButton extends AppCompatButton {
//constructors
public MyButton(Context context) {
super(context);
//init button's background color
this.setBackgroundColor(0x50ff00ff);
}
public MyButton(Context context,AttributeSet attrs) {
super(context,attrs);
//init button's background color
this.setBackgroundColor(0x50ff00ff);
}
public MyButton(Context context,AttributeSet attrs,int defStyleAttr) {
super(context,attrs,defStyleAttr);
//init button's background color
this.setBackgroundColor(0x50ff00ff);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction()==MotionEvent.ACTION_DOWN) {
//color change
this.setBackgroundColor(0x90ff00ff);
}
else if(event.getAction()==MotionEvent.ACTION_UP) {
//color recover
this.setBackgroundColor(0x50ff00ff);
}
return super.onTouchEvent(event);
}
}
MainActivity.java
public class MainActivity extends Activity
implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout linearlayout_main=
(LinearLayout)findviewById(R.id.linearlayout_main);
MyButton btn_1=new MyButton(this);
LinearLayout.LayoutParams params=
new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT);
btn_1.setLayoutParams(params);
linearlayout_main.addView(btn_1);
btn_1.setText("Button1");
btn_1.setId(R.id.btn_1);
btn_1.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.btn_1) {
Toast.makText(this,"Test success!",Toast.LENGTH_SHORT).show();
}
...
}
...
}
欢迎指正