編輯:關於Android編程
在android應用的開發過程中,經常會出現啟動一個界面後填寫部分內容後帶著數據返回啟動前的界面,最典型的應用就是登錄過程。在很多應用程序的模塊中,都有“我的”這個模塊,在未登錄狀態下點擊其中的某一項,就會彈出登錄界面,登錄完成後回到我的界面,會顯示一些登錄後的數據,這個功能的實現就要用到startActivityForResult.
下面通過一個小demo來說明一下startActivityForResult的使用,以及在實際開發中的一些應用。
demo的效果圖如下:


<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+1ve958Pmsry+1qO6PC9wPgo8cD7I/bj2sLTFpaOs0ru49nRleHR2aWV3PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">
主界面java代碼
public void onClick(View v) {
Intent intent ;
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.btn_a:
intent = new Intent(MainActivity.this, ActivityA.class);
intent.putExtra("data", "傳遞給A的數據");
startActivityForResult(intent, A);
break;
case R.id.btn_b:
intent = new Intent(MainActivity.this, ActivityB.class);
intent.putExtra("data", "傳遞給B的數據");
startActivity(intent);
break;
case R.id.btn_login:
intent = new Intent(MainActivity.this,LoginActivity.class);
intent.putExtra("data", "傳遞給登錄界面的數據");
startActivityForResult(intent, LOGIN);
break;
case R.id.btn_logout:
btnLogin.setClickable(true);
logout.setVisibility(View.GONE);
btnLogin.setText("登錄");
break;
default:
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case A:
Bundle bundle = data.getExtras();
String back = bundle.getString("back");
Toast.makeText(getApplicationContext(), "A界面傳回來的數據為:::::::"+back, 0).show();
content.setText("A界面傳回來的數據"+back);
break;
case LOGIN:
Bundle loginBundle = data.getExtras();
String username = loginBundle.getString("username");
String passwrod = loginBundle.getString("password");
content.setText("登錄界面傳回來的數據"+username+":::::::"+passwrod);
btnLogin.setText("已登錄");
btnLogin.setClickable(false);
logout.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), username+"::::::::"+passwrod, 0).show();
break;
default:
break;
}
}
}其中主要的地方有兩個,一個是在啟動activity時,如果要帶結果返回,則需要使用startActivityForResult(intent, requestcode)這個方法,該方法兩個參數一個是帶數據的Intent,另一個就是請求碼,這個請求碼是用於給activity識別是哪個activity返回的數據,因為在一個activity中可能會出現多個startActivityForResult,因此返回的時候,activity為了識別是哪個activity返回的數據就要利用requestcode來進行區分。
上面還有一個很重要的方法onActivityResult(int requestCode, int resultCode, Intent data) 該方法在startActivityForResult啟動的activity結束後返回數據時調用,其中第二個參數是結果碼,結果碼為RESULT_OK時,說明activity順便結束並返回結果。
第一個參數requestcode就是被啟動的activity的識別碼,在startActivityForResult方法時傳入。
第三個參數data 是Intent型的數據,該數據就是從activity返回回來的數據,可以使用data.getExtras()方法得到bundle,然後從bundle中取出一些基本數據。
通過不同的結果碼,對不同的activity返回的數據進行相應的操作,就可以合理的完成一些特定的功能效果。
那麼,是不是所有的startActivityForResult啟動的activity都回返回數據呢?答案是否定的,要想要activity返回數據,在activity中也要進行響應的一些設置,請看activity的代碼
ActivityA的代碼如下:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
LinearLayout ll = new LinearLayout(this);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
ll.setLayoutParams(params);
ll.setOrientation(LinearLayout.VERTICAL);
TextView tv = new TextView(this);
tv.setText("我是A界面");
ll.addView(tv);
Button close = new Button(this);
close.setText("關閉界面並返回");
close.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("back", "我是A界面返回的數據");
setResult(RESULT_OK, intent);
finish();
}
});
ll.addView(close);
setContentView(ll);
Toast.makeText(getApplicationContext(),
getIntent().getExtras().getString("data"), 0).show();
}
注意其中有一段代碼,是setResult(RESULT_OK, intent); 之後緊接著 finish();
activity要能成功返回數據,就必須在結束finish()之前調用setResult方法,該方法的兩個參數,第一個為結果碼,也就是onActivityResult方法中的第二個參數resultcode,一般情況下我們都設置該值為RESULT_OK

ActivityB由於使用的是startActivity 因此無需返回數據
ActivityB的代碼如下:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activityb);
Button close = (Button) findViewById(R.id.btn_close);
close.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
finish();
}
});
Toast.makeText(getApplicationContext(),
getIntent().getExtras().getString("data"), 0).show();
}
LoginActivity的代碼:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
etUsername = (EditText) findViewById(R.id.et_username);
etPassword = (EditText) findViewById(R.id.et_password);
Button login = (Button) findViewById(R.id.btn_login);
login.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String password = etPassword.getText().toString().trim();
String username = etUsername.getText().toString().trim();
Toast.makeText(getApplicationContext(), "登錄成功,返回原來界面", 0)
.show();
Intent intent = new Intent();
intent.putExtra("username", username);
intent.putExtra("password", password);
setResult(RESULT_OK, intent);
finish();
}
});
Toast.makeText(getApplicationContext(),
getIntent().getExtras().getString("data"), 0).show();
}
該界面登錄成功後,將用戶名和密碼返回到主頁面,並顯示,同時主頁面不能再次登錄,可以使用注銷操作。


到這裡,這個小demo就完成了。
主要演示二個功能,一個是啟動activity並帶結果返回,將結果顯示在頁面上。
一個是啟動activity不帶結果返回,這種操作比較常用和簡單。
完整的代碼:http://download.csdn.net/download/yanglfree/7503139
下面再來說下startActivityForResult另一個比較常用的應用場景:上傳頭像
效果圖如下:


點擊頭像後,彈出選擇對話框,選擇相冊或者拍照,完成後會出現裁剪界面,裁剪完成後,會將頭像顯示在界面上,如果有服務器的話,會將頭像上傳到服務器。
看下幾段關鍵的代碼:
頭像的點擊事件:
public void onClick(View v) {
CharSequence[] items = { "查看頭像", "手機相冊", "手機拍照" };
new AlertDialog.Builder(MainActivity.this).setTitle("上傳照片")
.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
if (which == SELECT_PICTURE) {
Intent intent = new Intent(
Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent,
PHOTO_REQUEST_GALLERY);
} else if (which == SELECT_CAMERA) {
Intent intent = new Intent(
"android.media.action.IMAGE_CAPTURE");
// 判斷存儲卡是否可以用,可用進行存儲
if (hasSdcard()) {
intent.putExtra(
MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(
Environment
.getExternalStorageDirectory(),
PHOTO_FILE_NAME)));
}
startActivityForResult(intent,
PHOTO_REQUEST_CAMERA);
} else if (which == SELECT_SCAN) {
// TODO 查看頭像
}
}
}).create().show();
}
});
其中,啟動相冊和拍照都是采用的startAcitivityForResult方法,並且,由於相冊和拍照都是系統應用,因此,intent使用指定的intent
拍照: "android.media.action.IMAGE_CAPTURE"
相冊:Intent.ACTION_PICK
在activityResult方法中:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == PHOTO_REQUEST_GALLERY) {// 圖庫
if (data == null) {
return;
}
Uri uri = data.getData();
crop(uri);
} else if (requestCode == PHOTO_REQUEST_CAMERA) {// 拍照
if (hasSdcard()) {
file = new File(Environment.getExternalStorageDirectory(),
PHOTO_FILE_NAME);
crop(Uri.fromFile(file));
} else {
Toast.makeText(this, "未找到存儲卡,無法存儲照片!", 0).show();
}
} else if (requestCode == PHOTO_REQUEST_CUT) {// 裁剪
try {
bmp = data.getParcelableExtra("data");
photo.setImageBitmap(bmp);
File tempFile = BitmapUtils.saveBitmapFile(bmp,
PHOTO_FILE_NAME);
upload(tempFile);//上傳到服務器
pd = new ProgressDialog(this);
pd.setMessage("頭像正在上傳中請稍後");
pd.show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
淺析android事件分發機制
我覺得android中的事件分發機制的懵懂期應該是Listview中對於item的點擊和長按事件,那個時候知道item的長按事件是返回boolean值的方法,我們知道要把
android組合控件Titlebar的定制過程
前言:我相信”天生我才必有用”這句話,每個人都有他的作用,也許他的作用相對其他人來不是很明顯,也許他的作用也就是取悅別人,但是請不要忘記,可以通過
簡單實現一個android listview分類!
最近在做一個關於招聘的APP,裡面有選擇城市一項,是用listview分類,有的人說兩個listview嵌套,但是感覺太麻煩了,比較listview底層太復雜,有的人用e
Android游戲開發之碰撞檢測(矩形碰撞、圓形碰撞、像素碰撞)
本文為大家分享了Android游戲開發之碰撞檢測,供大家參考,具體內容如下矩形碰撞 原理: 兩個矩形位置 的四種情況 不是這四中情況 則碰撞圓形碰撞 原理: 利用兩個圓心