天天看點

Button的建立、監聽與繼承簡介Button的建立Button的監聽Button的繼承

目錄

  • 簡介
  • 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();
        }
        ...
    }
    ...
}
           

歡迎指正