1. 程式人生 > >Android:Activity:開啟另外的Activity、引數傳遞

Android:Activity:開啟另外的Activity、引數傳遞

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    public void openActivity(View v){//這個按鈕的點選註冊事件
        //開啟新的Activity,可以明確指定開啟哪個,就是顯式意圖,不指定哪個只是指定Action、Category、Data的由系統匹配的就是隱式意圖。
        Intent intent = new Intent(this, OtherActivity.class);//啟用元件,顯示意圖:明確指定了元件名稱的意圖叫顯示意圖
        //關於指定元件名稱,還有很多寫法
        //1> intent.setClass(this, OtherActivity.class);//指定要啟用的元件名稱
        //2> intent.setClassName(this, "cn.itcast.activitys.OtherActivity");
        //3> intent.setComponent(new ComponentName(this, OtherActivity.class));
        /*
        intent.putExtra("company", "傳智播客");
        intent.putExtra("age", 5);
        */
        Bundle bundle = new Bundle();
        bundle.putString("company", "CSDN");
        bundle.putInt("age", 11);
        intent.putExtras(bundle);
        
        //startActivity(intent);//不需要返回資料的

        startActivityForResult(intent, 100);//需要返回資料的,onActivityResult中接收資料

}

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        String result = data.getStringExtra("result");
        Toast.makeText(getApplicationContext(),result, 1).show();
        
        super.onActivityResult(requestCode, resultCode, data);
    }
    
    

}

public class OtherActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.other);
        
        TextView textView = (TextView) this.findViewById(R.id.textView);
        
        Intent intent = getIntent();//獲取用於啟用它的意圖物件
    /*    String company = intent.getStringExtra("company");
        int age = intent.getIntExtra("age", 0);
    */
        Bundle bundle = intent.getExtras();
        String company = bundle.getString("company");
        int age = bundle.getInt("age");
        
        textView.setText("公司名稱:"+ company+ ",年限:"+ age);
    }

    public void closeActivity(View v){
        Intent intent = new Intent();
        intent.putExtra("result", "老方與麗麗的故事,後面省略2000字");
        setResult(20, intent);//設定返回資料
        finish();//關閉Activity(關閉視窗)
    }
}

元件就必須在AndroidManifest.xml中註冊

Bundle的作用

Bundle類用作攜帶資料,它類似於Map,用於存放key-value名值對形式的值。相對於Map,它提供了各種常用型別的putXxx()/getXxx()方法,如:putString()/getString()putInt()/getInt()putXxx()用於往Bundle物件放入資料,getXxx()方法用於從Bundle物件裡獲取資料。Bundle的內部實際上是使用了HashMap<String,Object>型別的變數來存放putXxx()方法放入的值:

public final class Bundle implements Parcelable, Cloneable {

......

Map<String,Object> mMap;

public Bundle() {

mMap= new HashMap<String,Object>();

......

}

public void putString(String key, String value) {

mMap.put(key,value);

}

public String getString(String key) {

Objecto = mMap.get(key);

return (String) o;

........//型別轉換失敗後會返回null,這裡省略了型別轉換失敗後的處理程式碼

}

}

在呼叫Bundle物件的getXxx()方法時,方法內部會從該變數中獲取資料,然後對資料進行型別轉換,轉換成什麼型別由方法的Xxx決定,getXxx()方法會把轉換後的值返回。

Intent附加資料的兩種寫法

第一種寫法用於批量新增資料到Intent

Intent intent = new Intent();

Bundle bundle = new Bundle();//該類用作攜帶資料

bundle.putString("name", "傳智播客");

intent.putExtras(bundle);//為意圖追加額外的資料,意圖原來已經具有的資料不會丟失,但key同名的資料會被替換

第二種寫法:這種寫法的作用等價於上面的寫法,只不過這種寫法是把資料一個個地新增進Intent,這種寫法使用起來比較方便,而且只需要編寫少量的程式碼。

Intent intent = new Intent();

intent.putExtra("name", "傳智播客");

Intent提供了各種常用型別過載後的putExtra()方法,如:putExtra(String name, String value)putExtra(String name, long value),在putExtra()方法內部會判斷當前Intent物件內部是否已經存在一個Bundle物件,如果不存在就會新建Bundle物件,以後呼叫putExtra()方法傳入的值都會存放於該Bundle物件,下面是IntentputExtra(String name, String value)方法程式碼片斷:

public class Intent implementsParcelable {

private Bundle mExtras;

public Intent putExtra(String name, String value) {

if (mExtras== null) {

mExtras = new Bundle();

}

mExtras.putString(name, value);

return this;

}


Inflate由資源xml解析成View

1.獲取LayoutInflater物件有三種方法

LayoutInflaterinflater=LayoutInflater.from(this);
LayoutInflaterinflater=getLayoutInflater();
LayoutInflaterinflater=(LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);

2.使用inflater或者View生成介面View

View.inflate

得到新開啟Activity關閉後返回的資料

如果你想在Activity中得到新開啟Activity關閉後返回的資料,你需要使用系統提供的startActivityForResult(Intent intent,int requestCode)方法開啟新的Activity,新的Activity關閉後會向前面的Activity 傳回資料,為了得到傳回的資料,你必須在前面的Activity中重寫onActivityResult(int requestCode, intresultCode, Intent data)方法:

publicclass MainActivity extends Activity {

@Override protectedvoid onCreate(Bundle savedInstanceState){

.......

Buttonbutton =(Button) this.findViewById(R.id.button);

button.setOnClickListener(new View.OnClickListener(){//點選該按鈕會開啟一個新的Activity

publicvoid onClick(View v) {

//第二個引數為請求碼,可以根據業務需求自己編號

startActivityForResult (new Intent(MainActivity.this, NewActivity.class),  1);

}});

}

//第一個引數為請求碼,即呼叫startActivityForResult()傳遞過去的值

//第二個引數為結果碼,結果碼用於標識返回資料來自哪個新Activity

@Override protected voidonActivityResult(int requestCode, int resultCode, Intent data) {

String result = data.getExtras().getString(“result”));//得到新Activity 關閉後返回的資料

}

}當新Activity關閉後,新Activity返回的資料通過Intent進行傳遞,android平臺會呼叫前面ActivityonActivityResult()方法,把存放了返回資料的Intent作為第三個輸入引數傳入,在onActivityResult()方法中使用第三個輸入引數可以取出新Activity返回的資料。

使用startActivityForResult(Intent intent, intrequestCode)方法開啟新的Activity,新Activity關閉前需要向前面的Activity返回資料需要使用系統提供的setResult(intresultCode, Intent data)方法實現:

public class NewActivityextendsActivity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {

......

        button.setOnClickListener(new View.OnClickListener(){

public void onClick(View v) {

Intentintent = new Intent();//資料是使用Intent返回

intent.putExtra(“result”, “傳智播客的學生很可愛”);//把返回資料存入Intent

NewActivity.this.setResult(RESULT_OK,intent);//設定返回資料

 NewActivity.this.finish();//關閉Activity

}});

}

}

setResult()方法的第一個引數值可以根據業務需要自己定義,上面程式碼中使用到的RESULT_OK是系統Activity類定義的一個常量值為-1,程式碼片斷如下:

public class android.app.Activityextends......{

public static final int RESULT_CANCELED = 0;

public staticfinal intRESULT_OK = -1;

public static final int RESULT_FIRST_USER = 1;

}

請求碼的作用請求來自哪兒?

使用startActivityForResult(Intent intent, intrequestCode)方法開啟新的Activity,我們需要為startActivityForResult()方法傳入一個請求碼(第二個引數)。請求碼的值是根據業務需要由自已設定,用於標識請求來源。例如:一個Activity有兩個按鈕,點選這兩個按鈕都會開啟同一個Activity,不管是那個按鈕開啟新Activity,當這個新Activity關閉後,系統都會呼叫前面ActivityonActivityResult(intrequestCode, intresultCode, Intent data)方法。在onActivityResult()方法如果需要知道新Activity是由那個按鈕開啟的,並且要做出相應的業務處理,這時可以這樣做:

@Override public void onCreate(Bundle savedInstanceState) {

....

button1.setOnClickListener(new View.OnClickListener(){

  public void onClick(Viewv) {

startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 1);

   }});

button2.setOnClickListener(new View.OnClickListener(){

  public void onClick(Viewv) {

startActivityForResult (new Intent(MainActivity.this, NewActivity.class), 2);

   }});

@Override protected void onActivityResult(intrequestCode, intresultCode, Intent data) {

switch(requestCode){

case 1:

//來自按鈕1的請求,作相應業務處理

case 2:

   //來自按鈕2的請求,作相應業務處理

}

}

}

結果碼的作用回覆來自哪兒?

在一個Activity中,可能會使用startActivityForResult()方法開啟多個不同的Activity處理不同的業務,當這些新Activity關閉後,系統都會呼叫前面ActivityonActivityResult(intrequestCode, intresultCode, Intent data)方法。為了知道返回的資料來自於哪個新Activity,在onActivityResult()方法中可以這樣做(ResultActivityNewActivity為要開啟的新Activity)

public class ResultActivity extends Activity {

.....

ResultActivity.this.setResult(1, intent);

ResultActivity.this.finish();

}

public class NewActivity extends Activity {

......

NewActivity.this.setResult(2, intent);

NewActivity.this.finish();

}

public class MainActivity extends Activity { // 在該Activity會開啟ResultActivityNewActivity

@Override protected void onActivityResult(intrequestCode, intresultCode, Intent data) {

switch(resultCode){

case 1:

// ResultActivity的返回資料

case 2:

  // NewActivity的返回資料

}

}

}