天天看点

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

欢迎指正