让Android融入我的生活!
公司最近项目特别忙,难得抽时间出来写博客了,不过越忙,接触的东西越多,学的也就越多了!
本例要特别强调一下:只是对高内聚,低耦合思想的一点简单实现,重要思想,而不是代码,请广大读者朋友留意!
前段时间公司Android开发就我一个人,思维太封闭了,自己想个啥样,就写个啥样,现在呢,来了两个同事,项目由我和另外一个同事一起负责,有人交流,可以听听别人的理解,对我们的提高绝对是有益无害,我们也需要调整好自己的心态,能够接受别人的正确建议!
好了,话不多说,进入正题,大家请先看一下下面这张图片,分为以下几个部分
1:进入页面对应的Activity,红标1为RadioButton,红标2为TextView,所有控制逻辑在当前Activity中实现
2:红色大方框,标注3的部分,是一个ImageSelectFragment,对应Activity中一个Framelayout布局,控制它显示和隐藏
3:ImageSelectFragment显示的所有图片,用一个GridView显示,给GridView配置上相应的GridAdapter
4:每张图片右上角有一个删除的按钮,在GridAdapter当中实现逻辑控制
那么现在问题来了,大家想想,我们写代码,尽量要实现它的高移植性,这也许就是Android高内聚,低耦合的思想精髓吧,让我们的代码直接拿给别人就能用,那这个ImageSelectFragment怎么样作到高内聚呢?
到这里,我们就需要搞清楚,这个ImageSelectFragment到底要实现什么,它内部都需要作些什么工作,对外传递些什么,理解清楚这些,我们才有高内聚的目标。
这个ImageSelectFragment所要实现的,就是所有图片选择的逻辑控制,不管你添加、删除、把图片Uri数据传给其它Activity、退出程序后再进来添加或者删除等等所有逻辑,这就是我们要实现的目标,当进行选择、删除时,红标为2的数字肯定也要变化,就是说,你的所有操作影响到数据变化时,一定要通知当前的Activity。
好了,大家看一下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: TODO 图片选择的逻辑控制
* @author AricMiao
* @date 2014-12-16 上午9:28:59
*/
@SuppressLint("InflateParams")
public class ImageSelectFragment extends BaseFragment {
public static final int PHOTOHRAPH = 1;// 拍照
public static final int PHOTOFROMLOCAL = 2; // 取照
public static final int PHOTOODELETE = 3;// 打开相册
public static final int PHOTOLOCAORESULT = 4;// 取照结果
public static final String IMAGE_UNSPECIFIED = "image/*";
/** 在tabhost的位置 */
public static final int POSITION = 0;
private View view;
public GridView gv_photo;
private GridAdapter adapter;// 放照片
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);
// 照片容器
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,
"===点击位置===" + arg2 + "===图片路劲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, "===相片保存路径===" + Constants.cameraFile.getPath());
Uri imageUri = Uri.fromFile(Constants.cameraFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, PHOTOHRAPH);
} else {
MToast.showToast(mContext, "木有SD卡哦");
}
}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:// 本地选取
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:// 拍照
Log.d(Constants.TAG, "===图片张数===" + BitmapUtils.drr.size()
+ "===结果码===" + resultCode + "===图片路径==="
+ 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;
}
}
其实在当前ImageSelectFragment当中实现所有操作控制就不多说了,高内聚,低耦合的思想最主要的体现就在ImageSelectListener接口上:
public interface ImageSelectListener{
public void imageSelct(ArrayList<String> urls);
}
public void setImageSelectListener(ImageSelectListener listener){
mListener=listener;
}
我们可以在我们自己的Activity当中实现这个接口
ImageSelectListener mImageSelectListener=new ImageSelectListener() {
@Override
public void imageSelct(ArrayList<String> urls) {
// TODO Auto-generated method stub
mUrls=urls;
setImageTextNum();
}
};
当对图片数据进行操作时,任何导致数据变化的操作都让它回调到这个方法中,返回来的结果ArrayList<String> urls就是操作完成后,所有图片的路径了,只要能拿到这个路径,我们就可以任意设置Activity中的显示、传递逻辑了,而这样,我们根本不用关心用户对图片进行了什么操作、操作步骤是什么的、影响到什么这些经过,别人如果要移植我们的图片显示Fragment,也只需要在他自己的Activity中实现这个接口就可以了,非常方便,这样使我们的代码在一个完全封闭的环境中执行,只对外界公司一个开口就足够了,这种模式和很多朋友用的Callback回调机制基本上是相同的。
好了,就介绍到这里吧,如果有朋友愿意互相交流的话,可以加QQ:1531074759,谢谢!