我正在构建一个Android应用程序,并且有五个Activity
类,或者如果您熟悉MVC模式,它们通常是Controller
类。
具体而言,User
将进入这5个Activity
课程中的一个(通过在整个应用中导航),有时他们可能会上传照片。现在,上传照片的代码遵循非常相似的模式。请注意所有这5个等级(YUCK)中所有这些代码重复5次。
全局变量:
/*
Tracking
*/
private static final int TAKE_PHOTO_REQUEST = 1;
private static final int GET_FROM_GALLERY = 2;
private Uri mUri;
private String mCurrentPhotoPath;
private File mFile;
private TypedFile mTypedFile; // For Retrofit
用户点击照片上传按钮,会弹出AlertDialog:
private void showFileOptions() {
new AlertDialog.Builder(this)
.setItems(R.array.uploadOptions, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
dispatchTakePicture();
break;
case 1:
dispatchUploadFromGallery();
break;
}
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.show();
}
dispatchTakePicture:
/*
Take picture from your camera
*/
private void dispatchTakePicture() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Make sure that there is a camera activity to handle the intent
if (intent.resolveActivity(getPackageManager()) != null) {
// Create the File where the mTypedFile would go
File picFile = null;
try {
picFile = createImageFile();
mFile = picFile;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
// Continue only if the file was successfully created
if (picFile != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picFile));
startActivityForResult(intent, TAKE_PHOTO_REQUEST);
}
}
}
dispatchUploadFromGallery:
/*
Take a mTypedFile from your gallery
*/
private void dispatchUploadFromGallery() {
// Launch gallery intent
startActivityForResult(new Intent(Intent.ACTION_PICK, MediaStore
.Images.Media.INTERNAL_CONTENT_URI), GET_FROM_GALLERY);
}
请注意,在这两种方法中都会调用startActivityForResult
。如果用户想要从createImageFile()
API中拍照,则可以使用Camera
方法:
private File createImageFile() throws IOException {
// Create the Image File name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, // Prefix
".jpg", // Suffix
storageDir // Directory
);
// Save the file, path for ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
mUri = Uri.fromFile(image);
return image;
}
现在终于我们的startActivityForResult(...)
方法:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == TAKE_PHOTO_REQUEST && resultCode == RESULT_OK) {
startUploadProgress();
showContainer();
mTypedFile = new TypedFile("image/*", mFile);
RotatePictureHelper.rotatePicture(mFile, ExampleActivity.this, mAttachment); // Helper class to rotate pictures
mBus.post(new LoadUploadFileEvent(mTypedFile));
} else if (requestCode == GET_FROM_GALLERY && resultCode == RESULT_OK) {
startUploadProgress();
showContainer();
mUri = data.getData();
mTypedFile = UriHelper.handleUri(mUri, this); // Helper class to handle bitmap manipulation
mFile = mTypedFile.file();
mBus.post(new LoadUploadFileEvent(mTypedFile));
} else if (resultCode != Activity.RESULT_CANCELED) {
Toast.makeText(this, R.string.generalError, Toast.LENGTH_LONG).show();
}
}
请注意,我已经创建了帮助程序类来处理位图操作和图片旋转问题。
但是,这是一个非常难看的丑陋代码,并且在5个类中重复这个。
我现在想到了一些想法:
AlertDialog
选项移至帮助程序类,并根据AlertDialogs
调用instanceOf
调用不同的Activity
。Activity
类,然后扩展5个Activity
子类并调用这些方法吗?答案 0 :(得分:0)
创建一个扩展DialogFragment的片段(例如UploadPhotoFragment),覆盖onCreateDialog和onActivityResult方法。当需要时,请致电
{{1}}
Ps:如果您使用的是支持库,请使用支持库的DialogFragment和FragmentManager。
答案 1 :(得分:0)
要解决这个问题,我选择了第三个选项:
我创建了一个名为lookup = {}
b.each_with_index { |el, i| lookup[el] = i }
a.sort_by { |el| lookup.fetch(el.first) }
# => [["A", 1075000], ["B", 0], ["C", 1750000], ["D", 0], ["E", 0]]
的活动,然后在我的其他5个CameraActivity
课程中扩展了此Activity
。这些类中的每个类的代码都是95%相似,每个类别的差异可能分别为5%。
我的Activity
会有以下代码:
CameraActivity
现在,我可以在我的其他public class CameraActivity extends Activity {
/*
Tracking
*/
private static final int TAKE_PHOTO_REQUEST = 1;
private static final int GET_FROM_GALLERY = 2;
private Uri mUri;
private String mCurrentPhotoPath;
private File mFile;
private TypedFile mTypedFile; // For Retrofit
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
startProgress();
switch (requestCode) {
case TAKE_PHOTO_REQUEST:
if (resultCode == RESULT_OK) {
mTypedFile = new TypedFile("image/*", mFile);
}
break;
case GET_FROM_GALLERY:
if (resultCode == RESULT_OK) {
mUri = data.getData();
mTypedFile = UriHelper.handleUri(mUri, this);
}
break;
default:
stopProgress();
Toast.makeText(this, R.string.generalError, Toast.LENGTH_LONG).show();
break;
}
}
protected void showFileOptions() {
new AlertDialog.Builder(this)
.setItems(R.array.uploadOptions, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case 0:
dispatchTakePicture();
break;
case 1:
dispatchUploadFromGallery();
break;
default:
dispatchUploadFromGallery();
break;
}
}
})
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.show();
}
// Other code for handling Uri and File goes here....
}
课程中扩展此Activity
,并实现其余的5%差异。请注意Activity
已更改为showFileOptions()
状态,因此我可以从孩子protected
拨打该电话。举个例子就是一个活动。
Activity
现在我可以简单地扩展我的5个孩子public class PhotoUploadActivity extends CameraActivity {
// Initialize methods
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
showFileOptions(); // Calling AlertDialog from Parent Activity
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Super call executes code in CameraActivity
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PHOTO_REQUEST:
if (resultCode == RESULT_OK) {
// Implement logic if user take a photo, do something with mUri or mTypedFile
}
break;
case GET_FROM_GALLERY:
if (resultCode == RESULT_OK) {
// Implement logic if user gets something from gallery, do something with mUri or mTypedFile
}
break;
default:
break;
}
}
}
课程,在这些课程中调用Activity
,并考虑剩余的5%代码,而super.onActivityResult(...)
处理其余的代码。