facebook廣告





123

2016年9月19日 星期一

玩转Android---UI篇---ImageButton(带图标的按钮)

除了Android系统自带的Button按钮一万,还提供了带图标的按钮ImageButton

要制作带图标的按钮,首先要在布局文件中定义ImageButton,然后通过setImageDrawable方法来设置要显示的图标。
注意:
我们可以在布局文件中就直接设置按钮的图标,如
android:src="@drawable/icon1"
我们也可以在程序中设置自定义图标
imgbtn3.setImageDrawable(getResources().getDrawable(R.drawable.icon2));
我们还可以使用系统自带的图标
imgbtn4.setImageDrawable(getResources().getDrawable(android.R.drawable.sym_call_incoming));

设置完按钮的图标后,需要为按钮设置监听setOnClickListener,以此捕获事件并处理

下面的例子讲述的是由4个图标按钮组成的布局,其中三个按钮的图标是自定义的,第四个按钮的图标是系统的,当点击按钮1的时候,弹出dialog,当点击按钮2的时候,点击确定后,可以将按钮2的图标变成按钮3的图标,当点击按钮3的时候,按钮3的图标变成了系统打电话的图标,点击按钮4,显示一个提示dialog

ImageButtonTest.java源代码
Java代码  收藏代码
  1. package org.loulijun.imagebutton;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.AlertDialog;  
  5. import android.app.Dialog;  
  6. import android.content.DialogInterface;  
  7. import android.os.Bundle;  
  8. import android.view.View;  
  9. import android.widget.Button;  
  10. import android.widget.ImageButton;  
  11. import android.widget.TextView;  
  12.   
  13. public class ImageButtonTest extends Activity {  
  14.     /** Called when the activity is first created. */  
  15.     TextView textview;  
  16.     ImageButton imgbtn1;  
  17.     ImageButton imgbtn2;  
  18.     ImageButton imgbtn3;  
  19.     ImageButton imgbtn4;  
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.           
  25.         textview=(TextView)findViewById(R.id.textview);  
  26.         //分别取得4个ImageButton对象  
  27.         imgbtn1=(ImageButton)findViewById(R.id.imagebutton1);  
  28.         imgbtn2=(ImageButton)findViewById(R.id.imagebutton2);  
  29.         imgbtn3=(ImageButton)findViewById(R.id.imagebutton3);  
  30.         imgbtn4=(ImageButton)findViewById(R.id.imagebutton4);  
  31.           
  32.         //分别为ImageButton设置图标  
  33.         //imgbtn1已经在main.xml布局中设置了图标,所以就不在这里设置了(设置图标即可在程序中设置,也可在布局文件中设置)  
  34.         imgbtn2.setImageDrawable(getResources().getDrawable(R.drawable.icon));//在程序中设置图标  
  35.         imgbtn3.setImageDrawable(getResources().getDrawable(R.drawable.icon2));  
  36.         imgbtn4.setImageDrawable(getResources().getDrawable(android.R.drawable.sym_call_incoming));//设置系统图标  
  37.           
  38.         //下面为各个按钮设置事件监听  
  39.         imgbtn1.setOnClickListener(new Button.OnClickListener()  
  40.         {  
  41.             @Override  
  42.             public void onClick(View v) {  
  43.                 // TODO Auto-generated method stub  
  44.                 Dialog dialog=new AlertDialog.Builder(ImageButtonTest.this)  
  45.                 .setTitle("提示")  
  46.                 .setMessage("我是ImageButton1")  
  47.                 .setPositiveButton("确定",new DialogInterface.OnClickListener() {  
  48.                       
  49.                     @Override  
  50.                     public void onClick(DialogInterface dialog, int which) {  
  51.                         // TODO Auto-generated method stub  
  52.                         //相应的处理操作  
  53.                     }  
  54.                 }).create();  
  55.                 dialog.show();  
  56.             }  
  57.               
  58.         });  
  59.           
  60.         imgbtn2.setOnClickListener(new Button.OnClickListener()  
  61.         {  
  62.             @Override  
  63.             public void onClick(View v) {  
  64.                 // TODO Auto-generated method stub  
  65.                 Dialog dialog=new AlertDialog.Builder(ImageButtonTest.this)  
  66.                 .setTitle("提示")  
  67.                 .setMessage("我是ImageButton2,我要使用ImageButton3的图标")  
  68.                 .setPositiveButton("确定",new DialogInterface.OnClickListener() {  
  69.                       
  70.                     @Override  
  71.                     public void onClick(DialogInterface dialog, int which) {  
  72.                         // TODO Auto-generated method stub  
  73.                         imgbtn2.setImageDrawable(getResources().getDrawable(R.drawable.icon2));  
  74.                     }  
  75.                 }).create();  
  76.                 dialog.show();  
  77.             }  
  78.               
  79.         });  
  80.           
  81.         imgbtn3.setOnClickListener(new Button.OnClickListener()  
  82.         {  
  83.             @Override  
  84.             public void onClick(View v) {  
  85.                 // TODO Auto-generated method stub  
  86.                 Dialog dialog=new AlertDialog.Builder(ImageButtonTest.this)  
  87.                 .setTitle("提示")  
  88.                 .setMessage("我是ImageButton3,我想使用系统打电话的图标")  
  89.                 .setPositiveButton("确定",new DialogInterface.OnClickListener() {  
  90.                       
  91.                     @Override  
  92.                     public void onClick(DialogInterface dialog, int which) {  
  93.                         // TODO Auto-generated method stub  
  94.                         imgbtn3.setImageDrawable(getResources().getDrawable(android.R.drawable.sym_action_call));  
  95.                     }  
  96.                 }).create();  
  97.                 dialog.show();  
  98.             }  
  99.               
  100.         });  
  101.           
  102.         imgbtn4.setOnClickListener(new Button.OnClickListener()  
  103.         {  
  104.             @Override  
  105.             public void onClick(View v) {  
  106.                 // TODO Auto-generated method stub  
  107.                 Dialog dialog=new AlertDialog.Builder(ImageButtonTest.this)  
  108.                 .setTitle("提示")  
  109.                 .setMessage("我是使用的系统图标")  
  110.                 .setPositiveButton("确定",new DialogInterface.OnClickListener() {  
  111.                       
  112.                     @Override  
  113.                     public void onClick(DialogInterface dialog, int which) {  
  114.                         // TODO Auto-generated method stub  
  115.                         //相应的处理操作  
  116.                     }  
  117.                 }).create();  
  118.                 dialog.show();  
  119.             }  
  120.               
  121.         });  
  122.     }  
  123. }  
 布局文件main.xml
Java代码  收藏代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:orientation="vertical"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     >  
  7. <TextView    
  8.     android:id="@+id/textview"  
  9.     android:layout_width="fill_parent"   
  10.     android:layout_height="wrap_content"   
  11.     android:text="ImageButton测试案例"  
  12.     />  
  13. <ImageButton  
  14.     android:id="@+id/imagebutton1"  
  15.     android:layout_width="wrap_content"  
  16.     android:layout_height="wrap_content"  
  17.     android:src="@drawable/icon1"  
  18. />  
  19. <ImageButton  
  20.     android:id="@+id/imagebutton2"  
  21.     android:layout_width="wrap_content"  
  22.     android:layout_height="wrap_content"  
  23. />  
  24. <ImageButton  
  25.     android:id="@+id/imagebutton3"  
  26.     android:layout_width="wrap_content"  
  27.     android:layout_height="wrap_content"  
  28. />  
  29. <ImageButton  
  30.     android:id="@+id/imagebutton4"  
  31.     android:layout_width="wrap_content"  
  32.     android:layout_height="wrap_content"  
  33. />  
  34. </LinearLayout>  
 运行效果如下:


 点击第一个按钮后


 点击确定后,点击第二个按钮


 点击确定,此时会看到按钮二的图标编程和按钮三的图标一样了


 点击按钮三


 点击确定后,发现按钮三的图标变成了系统打电话的图标


 点击按钮四

Android Interface的使用

Android应用程序采用Java语言编写,Java语法和C/C++有很大的相似性,但也有一些特别之处。Android中Interface的使用,从名字上看,Interface即为接口的意思,多用于实现回调(Call Back)方法。在Interface的定义中,一般的代码架构如代码清单1-1所示。
代码清单1-1 InterfaceServer.java
public class InterfaceServer {
      public interface OnClickListener{
        public void onClick();
      }
      private OnClickListener mOnClickListener=null;
      public void onClick(){
        if(mOnClickListener!=null)
        mOnClickListener.onClick();
      }
      public void setOnClickListener(OnClickListener l){
        mOnClickListener = l;
      }
    }
对于Interface内部的方法而言,只需要声明,而不需要具体实现。从编译器的角度来看,Interface会被认为是一个指向方法的指针。
使用InterfaceServer的代码一般如代码清单1-2所示。
代码清单1-2 使用InterfaceServer
public void addToButton {
      Button b = (Button)findViewById(R.id.button);
      onClickListener l = new OnClickListener(){
        public void onClick(View v){
          TextView tv1 = (TextView) findViewById(R.id.tv1);
          tv1.setText("The Button has been clicked");
        }
      };
      b.setOnClickListener(l);
    }
Interface和Class的区别?
Interface接口:可以理解成一种特殊的类,由常量和抽象方法组成的特殊类;接口不可以实例化;接口中的方法没有方法体;继承接口的类一定要实现接口中定义的方法。
Class类:可以实例化;可以定义自己的字段,属性,方法等;类可以实现多个接口,但只能继承一个类。
"interface"(接口)关键字使抽象的概念更深入了一层。我们可将其想象为一个"纯"抽象类。它允许创建者规定一个类的基本形式:方法名、自变量列表以及返回类型,但不规定方法主体。接口也包含了基本数据类型的数据成员,但它们都默认为static和final。接口只提供一种形式,并不提供实施的细节。
接口这样描述自己:"对于实现我的所有类,看起来都应该象我现在这个样子"。因此,采用了一个特定接口的所有代码都知道对于那个接口可能会调用什么方法。这便是接口的全部含义。所以我们常把接口用于建立类和类之间的一个"协议"。有些面向对象的程序设计语言采用了一个名为"protocol"(协议)的关键字,它做的便是与接口相同的事情。
为创建一个接口,请使用interface关键字,而不要用class。与类相似,我们可在interface关键字的前面增加一个public关键字(但只有接口定义于同名的一个文件内);或者将其省略,营造一种"友好的"状态。
为了生成与一个特定的接口(或一组接口)相符的类,要使用implements(实现)关键字。我们要表达的意思是"接口看起来就象那个样子,这儿是它具体的工作细节"。除这些之外,我们其他的工作都与继承极为相似。

java作用域public ,private ,protected 及不寫時的區別

在說明這四個關鍵字之前,我想就class之間的關係做一個簡單的定義,對於繼承自己的class,base class可以認為他們都是自己的子女,而對於和自己一個目錄下的classes,認為都是自己的朋友。 

1、public:public表明該數據成員、成員函數是對所有用戶開放,所有用戶都可以直接進行調用 

2、private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有財產神聖不可侵犯嘛,即便是子女,朋友,都不可以使用。 

3、protected:protected對於子女、朋友來說,就是public的,可以自由使用,沒有任何限制,而對於其他的外部class,protected就變成private。 

作用域   當前類 同一package 子孫類 其他package 

公共           √        √                 √        √ 

保護           √        √                 √        × 

友好           √        √                 ×        × 

私人           √        ×                 ×        × 

不寫時默認為friendly 

private 只有 跟他同一隻的 java 可以
proteced 同一個 packge 的都可以
public 都可以

設成 private 是為了不要讓別人可以直接對它做存取
設 getter setter 是為了讓別人能夠透過這個 對 private 的 field 做存取

Java 入門指南 - 建構子

引用:http://pydoing.blogspot.tw/2011/05/java-constructor.html
Java 中建立物件 (object) 需要建構子 (constructor) ,如果類別 (class) 沒有定義建構子,編譯器 (compiler) 就會提供一個預設的建構子 (default constructor)




我們現在要來詳細討論建構子的作用與功能,建構子的主要目的在於建立物件的過程中,也就是使用 new 關鍵字 (keyword) 的時候,程式 (program) 建立物件所執行的工作,這些工作通常就是初始化物件的屬性 (field) 。


如果類別沒有定義建構子,編譯器會提供預設預購子,預設建構子為沒有參數 (parameter) 的版本
public Encrypt() {}


須注意,如果我們有在類別中定義建構子,編譯器便不會提供沒有參數版本的預設建構子。建構子可以依需求而有不同的參數版本,例如 Encrypt 中我們需要這些屬性
char[] cArray;
int a;
int b;
int n;
char c;
int diff;


其中 a 、 b 、 n 、 c 、 diff ,我們需要提供這五個屬性值,然後呼叫 setArray() 計算出 cArray 的值
public Encrypt(int a, int b, int n, char c, int dif) {
    this.a = a;
    this.b = b;
    this.n = n;
    this.c = c;
    this.diff = dif;
    setArray();
}


當然,有些屬性值也可以用預設的,這就是形成不同參數版本的建構子
public Encrypt(int a, int b) {
    this(a, b, 26, 'a', 97);
}


這是利用 this 呼叫最多參數版本的建構子, a 、 b 為此建構子所需要提供的參數,其餘三個 n 、 c 、 diff ,我們直接以字面常數 (literal) 代入預設值, 也就是 n 為 26 , c 為 'a' , diff 為 97 。


可是 Encrypt 不是要 a 、 b 都為 0 到 9 隨機整數的隨機值嗎?我們仍得在 EncryptDemo 中進行設定嗎?不,不需要,我們可以設計沒有參數版本的建構子 
public Encrypt() {
    int ta = 0;
    int tb = 0;
         
    while (ta % 2 == 0) {
        ta = (int) (Math.random() * 10);
        tb = (int) (Math.random() * 10);
    }
         
    this.a = ta;
    this.b = tb;
    this.n = 26;
    this.c = 'a';
    this.diff = 97;
    setArray();
}


這裡,屬性設定的部份也可以這樣寫
a = ta;
b = tb;
n = 26;
c = 'a';
diff = 97;
setArray();


我們並沒有用到與屬性名稱相同的區域變數 (local variable) ,所以可以直接以屬性名稱設定數性質。我們仍使用 this 的原因很簡單,就是既然前兩個建構子都有用到 this ,我們這裡維持一致性,所以也用 this 來設定屬性。


完整的 Encrypt 如下
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class Encrypt {
    // 屬性
    char[] cArray = new char[26];
    int a;
    int b;
    int n;   
    char c; 
    int diff;
     
    // 建構子
    public Encrypt(int a, int b, int n, char c, int dif) {
        this.a = a;
        this.b = b;
        this.n = n;
        this.c = c;
        this.diff = dif;
        setArray();
    }
 
    public Encrypt(int a, int b) {
        this(a, b, 26, 'a', 97);
    }
 
    public Encrypt() {
        int ta = 0;
        int tb = 0;
         
        while (ta % 2 == 0) {
            ta = (int) (Math.random() * 10);
            tb = (int) (Math.random() * 10);
        }
         
        this.a = ta;
        this.b = tb;
        this.n = 26;
        this.c = 'a';
        this.diff = 97;
        setArray();
    }   
     
    // setter 方法
    public void setArray() {
        int i, y, x, m;
        char r;
         
        x = c;
        for (i = 0; i < n; i++) {
            y = x * a + b;
            m = y % n;
            r = (char) (m + diff);
            cArray[i] = r;
            x++;
        }       
    }
}
 
/* 《程式語言教學誌》的範例程式
    檔名:Encrypt.java
    功能:示範 Java 程式
    作者:張凱慶
    時間:西元 2011 年 4 月 */


然後修改 EncryptDemo 進行測試
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 測試 Encrypt 的類別
public class EncryptDemo {
    public static void main(String[] args) {
        System.out.println();
        for (int i = 0; i < 16; i++) {
            Encrypt t = new Encrypt();
            System.out.println(t.cArray);
        }
        System.out.println();
    }
}
 
/* 《程式語言教學誌》的範例程式
    檔名:EncryptDemo.java
    功能:示範 Java 程式
    作者:張凱慶
    時間:西元 2011 年 4 月 */


記得 Encrypt 與 EncryptDemo 都修改過,因此執行前都要先進行編譯,如下



這裡,我們在 EncryptDemo 中直接用句點運算子存取屬性 cArray ,其實不一個好習慣,因為如此物件的資料就曝光在世人面前,任何人都可以透過句點運算子存取,甚至更改屬性值,造成難以彌補的後果,從而失去資訊隱藏 (information hiding) 的意義。


因此,我們應該將屬性設成 private ,然後以 getter 與 setter 進行操作哩!


中英文術語對照
物件object
建構子constructor
類別class
編譯器compiler
建構子default constructor
關鍵字keyword
程式program
屬性field
參數parameter
字面常數literal
區域變數local variable
資訊隱藏information hiding