Talking about the logical control of callback using interfaces in Android, And the android callback
Integrate Android into my life!
Recently, the company has been very busy with projects. It is rare to take time out to write a blog. But the more busy it is, the more things it has to learn!
In this example, we need to emphasize that it is just a simple implementation of the high cohesion and low coupling idea. It is an important idea, not code. Please pay attention to it!
Some time ago, I was alone in Android development. My mind was too closed. I wanted to write something about it. Now, I have two colleagues who are responsible for the project together with my other colleagues, when someone communicates with us, we can hear what others understand. It is definitely beneficial and harmless to our improvement. We also need to adjust our mentality to accept others' correct suggestions!
Well, let's not talk much about it. Let's start with the question. Let's take a look at the picture below, which is divided into the following parts:
1: Enter the Activity corresponding to the page, marked with red 1 as RadioButton, and marked with red 2 as TextView. All control logics are implemented in the current Activity.
2: The red box marked with 3 is an ImageSelectFragment, which corresponds to a Framelayout layout in the Activity and controls its display and hiding.
3: all the images displayed by ImageSelectFragment are displayed in a GridView, and the corresponding GridAdapter is configured for the GridView.
4: There is a delete button in the upper-right corner of each image to implement logical control in GridAdapter.
Now let's look at the problem. We should write code and try to implement high portability. This may be the essence of the idea of high Android cohesion and low coupling, so that our code can be used directly by others. How can this ImageSelectFragment be highly cohesive?
At this point, we need to figure out what the ImageSelectFragment is to achieve, what it should do internally, what it should be passed out, and what it should be understood, so that we can have a high cohesion goal.
This ImageSelectFragment is the logical control of all image selection, whether you add, delete, send the image Uri data to other activities, exit the program, and then add or delete all the logics, this is what we want to achieve. When selecting and deleting, the number marked with red 2 will certainly change. That is to say, when all your operations affect data changes, be sure to notify the current Activity.
Let's take a look at the implementation code of ImageSelectFragment:
Import java. io. File;
Import java. io. Serializable;
Import java. util. ArrayList;
Import net. tsz. afinal. FinalBitmap;
Import android. annotation. SuppressLint;
Import android. content. Context;
Import android. content. Intent;
Import android.net. Uri;
Import android. OS. Bundle;
Import android. OS. Environment;
Import android. provider. MediaStore;
Import android. support. annotation. Nullable;
Import android. util. Log;
Import android. view. LayoutInflater;
Import android. view. View;
Import android. view. ViewGroup;
Import android. view. inputmethod. InputMethodManager;
Import android. widget. AdapterView;
Import android. widget. AdapterView. OnItemClickListener;
Import android. widget. GridView;
Import com. uhuibao. hupeng. BaseFragment;
Import com. uhuibao. hupeng. R;
Import com. uhuibao. hupeng. adapter. GridAdapter;
Import com. uhuibao. hupeng. adapter. GridAdapter. DeleteImageListener;
Import com. uhuibao. hupeng. config. Constants;
Import com. uhuibao. hupeng. selectpic. BitmapUtils;
Import com. uhuibao. hupeng. selectpic. ImageGridActivity;
Import com. uhuibao. hupeng. selectpic. TestPicActivity;
Import com. uhuibao. hupeng. utils. MToast;
/**
*
* @ ClassName: ImageSelectFragment
* @ Description: Logical Control of TODO Image Selection
* @ Author AricMiao
* @ Date 2014-12-16 9:28:59 AM
*/
@ SuppressLint ("InflateParams ")
Public class ImageSelectFragment extends BaseFragment {
Public static final int PHOTOHRAPH = 1; // photograph
Public static final int PHOTOFROMLOCAL = 2; // take the photo
Public static final int PHOTOODELETE = 3; // open the album
Public static final int PHOTOLOCAORESULT = 4; // obtain the result
Public static final String IMAGE_UNSPECIFIED = "image /*";
/** Location in tabhost */
Public static final int POSITION = 0;
Private View view;
Public GridView gv_photo;
Private GridAdapter adapter; // Save the photo
Private FinalBitmap friendsFb;
Private Context mContext;
Private ArrayList <String> urls = new ArrayList <String> ();
Private ImageSelectListener mListener;
@ Override
Public View onCreateView (LayoutInflater inflater,
@ Nullable ViewGroup container, @ Nullable Bundle savedInstanceState ){
// TODO Auto-generated method stub
MContext = this. getActivity ();
View = inflater. inflate (R. layout. image_select, null );
Return view;
}
@ Override
Public void onActivityCreated (@ Nullable Bundle savedInstanceState ){
// TODO Auto-generated method stub
Super. onActivityCreated (savedInstanceState );
FriendsFb = FinalBitmap. create (this. getActivity ());
FriendsFb. configDiskCachePath (Constants. picSavePath );
FriendsFb. configLoadingImage (R. drawable. user );
FriendsFb. configLoadfailImage (R. drawable. user );
// Photo container
Gv_photo = (GridView) view. findViewById (R. id. gv_photo );
Adapter = new GridAdapter (this. getActivity (), friendsFb );
Gv_photo.setAdapter (adapter );
Adapter. notifyDataSetChanged ();
Gv_photo.setOnItemClickListener (new OnItemClickListener (){
Public void onItemClick (AdapterView <?> Arg0, View arg1, int arg2,
Long arg3 ){
Log. d (Constants. TAG,
"=== Click position ===" + arg2 + "=== picture path list ===" + urls. size ());
If (arg2 = urls. size ()){
InputMethodManager imm = (InputMethodManager) mContext. getSystemService (Context. INPUT_METHOD_SERVICE );
Imm. hideSoftInputFromWindow (arg1.getWindowToken (), 0 );
New PopupWindows (ImageSelectFragment. this. getActivity (), gv_photo, new ImageCallback (){
@ Override
Public void onSelectResult (String method ){
// TODO Auto-generated method stub
Intent intent = new Intent ();
If ("camera". equals (method )){
String state = Environment. getExternalStorageState ();
If (state. equals (Environment. MEDIA_MOUNTED )){
Intent = new Intent (
MediaStore. ACTION_IMAGE_CAPTURE );
Constants. cameraFile = new File (Environment. getExternalStorageDirectory (),
String. valueOf (System. currentTimeMillis () + ". jpg ");
Log. d (Constants. TAG, "= photo storage Path =" + Constants. cameraFile. getPath ());
Uri imageUri = Uri. fromFile (Constants. cameraFile );
Intent. putExtra (MediaStore. EXTRA_OUTPUT, imageUri );
StartActivityForResult (intent, PHOTOHRAPH );
} Else {
MToast. showToast (mContext, "wood SD card ");
}
} Else if ("local". equals (method )){
Intent = new Intent (getActivity (),
TestPicActivity. class );
StartActivityForResult (intent, PHOTOFROMLOCAL );
} Else if ("no". equals (method )){
}
}
});
}
}
});
Adapter. setDeleteListener (deleteListener );
}
DeleteImageListener deleteListener = new DeleteImageListener (){
@ Override
Public void deleteImage (int position, String url ){
// TODO Auto-generated method stub
Urls. remove (url );
If (mListener! = Null ){
MListener. imageSelct (urls );
}
}
};
Public void onActivityResult (int requestCode, int resultCode, Intent data ){
Switch (requestCode ){
Case PHOTOFROMLOCAL: // select local
If (resultCode =-1 ){
Return;
}
If (Constants. photoFiles! = Null ){
Intent intent = new Intent (getActivity (),
ImageGridActivity. class );
Intent. putExtra (TestPicActivity. EXTRA_IMAGE_LIST,
(Serializable) Constants. photoFiles );
StartActivityForResult (intent, PHOTOLOCAORESULT );
}
Break;
Case PHOTOHRAPH: // take a photo
Log. d (Constants. TAG, "=== image size =" + BitmapUtils. drr. size ()
+ "= Result code =" + resultCode + "= image Path ="
+ Constants. cameraFile. getPath ());
If (BitmapUtils. drr. size () <Constants. photoNum ){
If (Constants. cameraFile. exists ()){
BitmapUtils. drr. add (Constants. cameraFile. getPath ());
}
}
Break;
Case PHOTOODELETE:
Break;
Case PHOTOLOCAORESULT:
Break;
}
Urls = BitmapUtils. drr;
If (mListener! = Null ){
MListener. imageSelct (urls );
}
Super. onActivityResult (requestCode, resultCode, data );
}
@ Override
Public void onResume (){
// TODO Auto-generated method stub
Adapter. notifyDataSetChanged ();
Super. onResume ();
}
@ Override
Public void onDestroyView (){
// TODO Auto-generated method stub
View = null;
Super. onDestroyView ();
}
Public interface ImageSelectListener {
Public void imageSelct (ArrayList <String> urls );
}
Public void setImageSelectListener (ImageSelectListener listener ){
MListener = listener;
}
}
In fact, in the current ImageSelectFragment, there is not much to say about implementing all operation control. The idea of High Cohesion and low coupling is mainly embodied in the ImageSelectListener interface:
Public interface ImageSelectListener {
Public void imageSelct (ArrayList <String> urls );
}
Public void setImageSelectListener (ImageSelectListener listener ){
MListener = listener;
}
We can implement this interface in our own Activity.
ImageSelectListener mImageSelectListener = new ImageSelectListener (){
@ Override
Public void imageSelct (ArrayList <String> urls ){
// TODO Auto-generated method stub
MUrls = urls;
SetImageTextNum ();
}
};
When you perform operations on image data, any operation that causes data changes calls back to this method. The returned result ArrayList <String> urls is after the operation is completed, the path of all images. As long as we can get this path, we can set the display and transfer logic in the Activity at will, we don't need to worry about what operations the user has performed on the image, what the operation procedure is, and what these processes are affected. If someone else wants to transplant our image to display Fragment, it is convenient to implement this interface in his own Activity, so that our code can be executed in a completely closed environment, it is enough to open an opening to external companies. This mode is basically the same as the Callback mechanism used by many friends.
Now, let's introduce it here. If you have friends who want to communicate with each other, you can add QQ: 1531074759. Thank you!