Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android常用實例——實現修改用戶頭像功能

Android常用實例——實現修改用戶頭像功能

編輯:關於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;

    }

}

這些都寫好了。這個功能也就可基本實現了。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved