編輯:關於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 Context深度剖析
android程序和java程序的區別Android程序不像Java程序一樣,隨便創建一個類,寫個main()方法就能跑了,而是要有一個完整的Android工程環境,在這
手機QQ如何截圖 手機QQ截圖方法
安卓手機QQ自帶截圖功能,iPad、iPhone則需要使用iOS系統自帶的截圖方法或者第三方APP。下面就隨小編分別來看看,安卓手機QQ和iOS系統的ipa
Android之——殺死用戶選中的進程優化
在上一篇博文《Android之——殺死用戶選中的進程(釋放進程占用的空間)》一文中,向大家介紹了如何殺死用戶選中的進程,但是,遺留了一個問題,那就
初步編寫IDEA\AndroidStudio翻譯插件
先放兩張效果圖 一、准備由於AndroidStudio不具備開發插件的功能,需要安裝IDEA 翻譯使用的是有道的翻譯接口,需要申請,接口申請的網址點這裡 json解析使用