編輯:關於Android編程
首先祝大家周末愉快!前幾天發表了幾個項目中常用的實例,讀者反映不錯,可以看出大家還是希望技術能夠在項目得到實際的應用,那麼這篇博客就來聊聊實現用戶修改頭像的功能。
現在的APP,無論是大型的APP還是小型的項目,都或多或少的跟修改頭像相關聯,這個功能可以說在哪兒都用的說,所以有必要掌握這門技術。
先說說這個功能所需要掌握的知識點:
1.對startActivityForResult()方法要有一定的掌握;
文件存儲的掌握;3.PopupWindow的使用。
如果對這些知識點都比較了解的話,那看這篇博客就毫無壓力了。
我這裡為了方便,單獨寫了一個PopupWindow,用於封裝我們想要的功能和實現PopupWindow的顯示。先看看代碼:
public class MPoPuWindow extends PopupWindow implements OnClickListener { public Context mContext; private Type type; public Activity mActivity; private File file; private Uri ImgUri; private TextView mTakePhoto, mAlbumPhoto, mCancel; public MPoPuWindow(Context context, Activity mActivity) { initView(context); this.mActivity = mActivity; } private void initView(Context mContext) { this.mContext = mContext; View v = LayoutInflater.from(mContext).inflate(R.layout.activity_popu, null); setContentView(v); mTakePhoto = (TextView) v.findViewById(R.id.photo_take); mAlbumPhoto = (TextView) v.findViewById(R.id.photo_album); mCancel = (TextView) v.findViewById(R.id.photo_cancel); mTakePhoto.setOnClickListener(this); mAlbumPhoto.setOnClickListener(this); mCancel.setOnClickListener(this); // 設置SelectPicPopupWindow彈出窗體的寬 this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); // 設置SelectPicPopupWindow彈出窗體的高 this.setHeight(ScreenUtils.getScreenHeight(mContext)); // 設置SelectPicPopupWindow彈出窗體可點?? this.setTouchable(true); this.setFocusable(true); this.setOutsideTouchable(true); // 刷新狀?? this.update(); // 設置SelectPicPopupWindow彈出窗體動畫效果 this.setAnimationStyle(R.style.popuwindow_from_bottom); // 實例化一個ColorDrawable顏色為半透明 ColorDrawable dw = new ColorDrawable(0x50000000); // 設置SelectPicPopupWindow彈出窗體的背景 this.setBackgroundDrawable(dw); } public void showPopupWindow(View parent) { if (!this.isShowing()) { this.showAtLocation(parent, Gravity.BOTTOM, 0, 0); } else { this.dismiss(); } } @Override public void onClick(View arg0) { switch (arg0.getId()) { case R.id.photo_take: Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis() + ".jpg"); ImgUri = Uri.fromFile(file); intent.putExtra(MediaStore.EXTRA_OUTPUT, ImgUri); mActivity.startActivityForResult(intent, 1); type = Type.CAMERA; if (listener != null) { listener.getType(type); listener.getImgUri(ImgUri, file); } this.dismiss(); break; case R.id.photo_album: Intent intent2 = new Intent("android.intent.action.PICK"); intent2.setType("image/*"); mActivity.startActivityForResult(intent2, 2); type = Type.PHONE; if (listener != null) { listener.getType(type); } this.dismiss(); break; case R.id.photo_cancel: this.dismiss(); break; default: break; } } public void onPhoto(Uri uri, int outputX, int outputY) { Intent intent = null; intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/*"); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", outputX); intent.putExtra("outputY", outputY); intent.putExtra("scale", true); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); intent.putExtra("return-data", true); intent.putExtra("circleCrop", true); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); // no face detection mActivity.startActivityForResult(intent, 3); } public interface onGetTypeClckListener { void getType(Type type); void getImgUri(Uri ImgUri, File file); } private onGetTypeClckListener listener; public void setOnGetTypeClckListener(onGetTypeClckListener listener) { this.listener = listener; } }
重點的內容我都加上了注釋,所以就不再贅述,值得注意的是我這裡為了能跟外面交互,我定義了一個接口,然後對外暴露出兩個方法,傳遞我們選擇圖片的時候產生的file和類型。另外我這裡還用到了樣式:
anim文件下的popu_hiden_from_top.xml
還有一個popu_show_from_bottom.xml
這個樣式主要是給popuwindow添加一個彈出的樣式,使它更好看一些。接下來就看看Activity怎麼寫的:
public class MainActivity extends Activity { private ImageView mIvThumb; private File file; private Uri ImgUri; private Type type; private MPoPuWindow puWindow; public enum Type { PHONE, CAMERA } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mIvThumb=(ImageView) findViewById(R.id.btn_change); mIvThumb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { puWindow = new MPoPuWindow(MainActivity.this, MainActivity.this); puWindow.showPopupWindow(findViewById(R.id.set_act_parent)); puWindow.setOnGetTypeClckListener(new onGetTypeClckListener() { @Override public void getType(Type type) { MainActivity.this.type = type; } @Override public void getImgUri(Uri ImgUri, File file) { MainActivity.this.ImgUri = ImgUri; MainActivity.this.file = file; } }); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); Log.e("requestCode", type + ""); if (requestCode == 1) { if (ImgUri != null) { puWindow.onPhoto(ImgUri, 300, 300); } } else if (requestCode == 2) { if (data != null) { Uri uri = data.getData(); puWindow.onPhoto(uri, 300, 300); } } else if (requestCode == 3) { if (type == Type.PHONE) { if (data != null) { Bundle extras = data.getExtras(); Bitmap bitmap = (Bitmap) extras.get("data"); if (bitmap != null) { mIvThumb.setImageBitmap(bitmap); } } } else if (type == Type.CAMERA) { mIvThumb.setImageBitmap(BitmapFactory.decodeFile(file.getPath())); } } } }
其他都好理解,重點看看onActivityResult()方法裡面的內容,這裡分別使用了三個判斷語句,也就是說返回的時候有三種情況,從相機裡面返回的、從相冊裡面返回的、從切圖界面返回的,對應不同的返回進行不一樣的操作。代碼再popuwindow裡面都封裝好了。
最後看到用到的兩個工具類,這兩個工具類都是項目中常用到的,可以保存下來以後用
第一個:DensityUtils
import android.content.Context; import android.util.TypedValue; /** * 常用單位轉換的輔助類 * * * */ public class DensityUtils { private DensityUtils() { /* cannot be instantiated */ throw new UnsupportedOperationException("cannot be instantiated"); } /** * dp轉px * * @param context * @param val * @return */ public static int dp2px(Context context, float dpVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, context.getResources().getDisplayMetrics()); } /** * sp轉px * * @param context * @param val * @return */ public static int sp2px(Context context, float spVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, context.getResources().getDisplayMetrics()); } /** * px轉dp * * @param context * @param pxVal * @return */ public static float px2dp(Context context, float pxVal) { final float scale = context.getResources().getDisplayMetrics().density; return (pxVal / scale); } /** * px轉sp * * @param fontScale * @param pxVal * @return */ public static float px2sp(Context context, float pxVal) { return (pxVal / context.getResources().getDisplayMetrics().scaledDensity); } }
第二個:ScreenUtils
import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.util.DisplayMetrics; import android.view.View; import android.view.WindowManager; /** * 獲得屏幕相關的輔助類 * * * */ public class ScreenUtils { private ScreenUtils() { /* cannot be instantiated */ throw new UnsupportedOperationException("cannot be instantiated"); } /** * 獲得屏幕寬度 * * @param context * @return */ public static int getScreenWidth(Context context) { WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.widthPixels; } /** * 獲得屏幕高度 * * @param context * @return */ public static int getScreenHeight(Context context) { WindowManager wm = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics outMetrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(outMetrics); return outMetrics.heightPixels; } /** * 獲得狀態欄的高度 * * @param context * @return */ public static int getStatusHeight(Context context) { int statusHeight = -1; try { Class clazz = Class.forName("com.android.internal.R$dimen"); Object object = clazz.newInstance(); int height = Integer.parseInt(clazz.getField("status_bar_height") .get(object).toString()); statusHeight = context.getResources().getDimensionPixelSize(height); } catch (Exception e) { e.printStackTrace(); } return statusHeight; } /** * 獲取當前屏幕截圖,包含狀態欄 * * @param activity * @return */ public static Bitmap snapShotWithStatusBar(Activity activity) { View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bmp = view.getDrawingCache(); int width = getScreenWidth(activity); int height = getScreenHeight(activity); Bitmap bp = null; bp = Bitmap.createBitmap(bmp, 0, 0, width, height); view.destroyDrawingCache(); return bp; } /** * 獲取當前屏幕截圖,不包含狀態欄 * * @param activity * @return */ public static Bitmap snapShotWithoutStatusBar(Activity activity) { View view = activity.getWindow().getDecorView(); view.setDrawingCacheEnabled(true); view.buildDrawingCache(); Bitmap bmp = view.getDrawingCache(); Rect frame = new Rect(); activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame); int statusBarHeight = frame.top; int width = getScreenWidth(activity); int height = getScreenHeight(activity); Bitmap bp = null; bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight); view.destroyDrawingCache(); return bp; } }
這些都寫好了。這個功能也就可基本實現了。
android程序和java程序的區別Android程序不像Java程序一樣,隨便創建一個類,寫個main()方法就能跑了,而是要有一個完整的Android工程環境,在這
安卓手機QQ自帶截圖功能,iPad、iPhone則需要使用iOS系統自帶的截圖方法或者第三方APP。下面就隨小編分別來看看,安卓手機QQ和iOS系統的ipa
在上一篇博文《Android之——殺死用戶選中的進程(釋放進程占用的空間)》一文中,向大家介紹了如何殺死用戶選中的進程,但是,遺留了一個問題,那就
先放兩張效果圖 一、准備由於AndroidStudio不具備開發插件的功能,需要安裝IDEA 翻譯使用的是有道的翻譯接口,需要申請,接口申請的網址點這裡 json解析使用