目錄
- 簡介
- 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();
}
...
}
...
}
歡迎指正