Android MVVM框架搭建PermissionAlertDialog拍照和相册选取

Posted 初学者-Study

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MVVM框架搭建PermissionAlertDialog拍照和相册选取相关的知识,希望对你有一定的参考价值。

android MVVM框架搭建(七)Permission、AlertDialog、拍照和相册选取

前言

  在上一篇博客中完成了新闻详情数据的查看以及用户的注册登录,这篇文章中将对用户的信息进行增加和修改。会使用到文件读写、相机权限、自定义Dialog、相册选取和相机拍照。

正文

  下面先进行数据库的升级,因为我们要更换用户的头像,因此首先用户表里面是需要一个头像的字段的,之前对数据库进行升级的时候都是直接添加一个表,那么这一次升级我们往表里面增加一个字段。

一、数据库升级

  一般来说再设计数据库的时候就要想到一些因素,像增加表字段这种事情一般是出现在业务需求有改动的情况下,因此我们在设计表的时候可以想清楚有没有可能进行扩展,会怎样扩展。下面我们要往数据表User中增加一个avatar的字段,表示头像。

同时,增加get和set方法。

	public String getAvatar() 
        return avatar;
    

    public void setAvatar(String avatar) 
        this.avatar = avatar;
    

然后进行数据库的升级,打开AppDatabase,增加如下代码:

	/**
     * 版本升级迁移到5 在用户表中新增一个avatar字段
     */
    static final Migration MIGRATION_4_5 = new Migration(4, 5) 
        @Override
        public void migrate(@NonNull @NotNull SupportSQLiteDatabase database) 
            //User表中新增avatar字段
            database.execSQL("ALTER TABLE `user` ADD COLUMN avatar TEXT");
        
    ;

这表示我在User表中增加一个avatar字段,然后我们添加迁移

再把数据库版本改成5。

这样,数据库的升级迁移就完成了。

二、数据操作

UserRepository中的代码也需要更新,在里面增加如下代码:

	private static volatile UserRepository mInstance;

    public static UserRepository getInstance() 
        if (mInstance == null) 
            synchronized (UserRepository.class) 
                if (mInstance == null) 
                    mInstance = new UserRepository();
                
            
        
        return mInstance;
    

这一篇文章中将会涉及到HomeActivity中的页面数据交互,因此,我们需要一个HomeViewModel,在viewmodels包下创建它,里面的代码如下:

public class HomeViewModel extends BaseViewModel 

    public LiveData<User> user;

    public String defaultName = "初学者-Study";
    public String defaultIntroduction = "Android | Java";

    public void getUser() 
        user = UserRepository.getInstance().getUser();
    

    public void updateUser(User user) 
        UserRepository.getInstance().updateUser(user);
        failed = UserRepository.getInstance().failed;
        getUser();
    

这里我放置了两个默认值,因为在注册的时候,昵称和简介是可以不用填写的,所以在显示的时候如果没有填就显示这个默认值,如果是Kotlin的话就直接使用缺省值就好了,这两个默认值会在xml中用到的。同时这个HomeViewModel里面有一个获取用户信息和修改用户信息的方法,当我们登录成功进入的HomeActivity时是获取,当修改用户信息的时候是更新,这很好理解。这一步说清楚之后下面就要做新的操作了。

二、自定义Dialog

下面要定义一个dialog,用于App中使用,在view包下新建一个dialog包,包下新建一个DialogViewHelper类,里面的代码如下:

① DialogViewHelper

public class DialogViewHelper 

    private View mContentView;
    private SparseArray<WeakReference<View>> mViews;

    public DialogViewHelper(Context context, int layoutResId) 
        this();
        mContentView = LayoutInflater.from(context).inflate(layoutResId, null);
    

    public DialogViewHelper() 
        mViews = new SparseArray<>();
    

    public <T extends View> void setText(int viewId, CharSequence text) 
        TextView tv = getView(viewId);
        if (tv != null) 
            tv.setText(text);
        
    

    public <T extends View> T getView(int viewId) 
        WeakReference<View> weakReference = mViews.get(viewId);
        View view = null;

        if (weakReference != null) 
            view = weakReference.get();
        

        if (view == null) 
            view = mContentView.findViewById(viewId);
            if (view != null) 
                mViews.put(viewId, new WeakReference<>(view));
            
        
        return (T) view;
    

    public void setOnClickListener(int viewId, View.OnClickListener onClickListener) 
        View view = getView(viewId);
        if (view != null) 
            view.setOnClickListener(onClickListener);
        
    

    public void setIcon(int viewId, int resId) 
        ImageView iv = getView(viewId);
        if (iv != null) 
            iv.setImageResource(resId);
        
    

    public void setContentView(View contentView) 
        mContentView = contentView;
    

    public View getContentView() 
        return mContentView;
    

② AlertController

同样在dialog包下新建一个AlertController类,代码如下:

public class AlertController 
    private AlertDialog mAlertDialog;
    private Window mWindow;
    private DialogViewHelper mViewHelper;

    public AlertController(AlertDialog alertDialog, Window window) 
        mAlertDialog = alertDialog;
        mWindow = window;
    

    public void setDialogViewHelper(DialogViewHelper dialogViewHelper) 
        mViewHelper = dialogViewHelper;
    

    public void setText(int viewId, CharSequence text) 
        mViewHelper.setText(viewId, text);
    

    public void setIcon(int viewId, int resId) 
        mViewHelper.setIcon(viewId, resId);
    

    public <T extends View> T getView(int viewId) 
        return mViewHelper.getView(viewId);
    


    public void setOnClickListener(int viewId, View.OnClickListener onClickListener) 
        mViewHelper.setOnClickListener(viewId, onClickListener);
    

    public AlertDialog getDialog() 
        return mAlertDialog;
    

    public Window getWindow() 
        return mWindow;
    

//-------------------------------------------------------------------------------------------------


    public static class AlertParams 

        public Context mContext;
        //对话框主题背景
        public int mThemeResId;

        public boolean mCancelable;

        public DialogInterface.OnCancelListener mOnCancelListener;

        public DialogInterface.OnDismissListener mOnDismissListener;

        public DialogInterface.OnKeyListener mOnKeyListener;
        //文本颜色
        public SparseArray<Integer> mTextColorArray = new SparseArray<>();

        //存放文本的更改
        public SparseArray<CharSequence> mTextArray = new SparseArray<>();
        //存放点击事件
        public SparseArray<View.OnClickListener> mClickArray = new SparseArray<>();
        //存放长按点击事件
        public SparseArray<View.OnLongClickListener> mLondClickArray = new SparseArray<>();
        //存放对话框图标
        public SparseArray<Integer> mIconArray = new SparseArray<>();
        //存放对话框图片
        public SparseArray<Bitmap> mBitmapArray = new SparseArray<>();
        //对话框布局资源id
        public int mLayoutResId;
        //对话框的view
        public View mView;
        //对话框宽度
        public int mWidth;
        //对话框高度
        public int mHeight;
        //对话框垂直外边距
        public int mHeightMargin;
        //对话框横向外边距
        public int mWidthMargin;
        //动画
        public int mAnimation;
        //对话框显示位置
        public int mGravity = Gravity.CENTER;


        public AlertParams(Context context, int themeResId) 
            mContext = context;
            mThemeResId = themeResId;
        

        public void apply(AlertController alert) 
            //设置对话框布局
            DialogViewHelper dialogViewHelper = null;
            if (mLayoutResId != 0) 
                dialogViewHelper = new DialogViewHelper(mContext, mLayoutResId);
            
            if (mView != null) 
                dialogViewHelper = new DialogViewHelper();
                dialogViewHelper.setContentView(mView);
            
            if (dialogViewHelper == null) 
                throw new IllegalArgumentException("please set layout");
            
            //将对话框布局设置到对话框

            alert.getDialog().setContentView(dialogViewHelper.getContentView());

            //设置DialogViewHelper辅助类
            alert.setDialogViewHelper(dialogViewHelper);
            //设置文本
            for (int i = 0; i < mTextArray.size(); i++) 
                alert.setText(mTextArray.keyAt(i), mTextArray.valueAt(i));
            
            //设置图标
            for (int i = 0; i < mIconArray.size(); i++) 
                alert.setIcon(mIconArray.keyAt(i), mIconArray.valueAt(i));
            
            //设置点击
            for (int i = 0; i < mClickArray.size(); i++) 
                alert.setOnClickListener(mClickArray.keyAt(i), mClickArray.valueAt(i));
            
            //配置自定义效果,底部弹出,宽高,动画,全屏
            Window window = alert.getWindow();
            window.setGravity(mGravity);//显示位置

            if (mAnimation != 0) 
                window.setWindowAnimations(mAnimation);//设置动画
            
            //设置宽高
            WindowManager.LayoutParams params = window.getAttributes();
            params.width = mWidth;
            params.height = mHeight;
            params.verticalMargin = mHeightMargin;
            params.horizontalMargin = mWidthMargin;
            window.setAttributes(params);
        
    


下面自定义Dialog

③ AlertDialog

在dialog包下新建一个AlertDialog,里面的代码如下:

public class AlertDialog extends Dialog 

    private AlertController mAlert;

    public AlertDialog(@NonNull Context context, @StyleRes int themeResId) 
        super(context, themeResId);
        mAlert = new AlertController(this, getWindow());
    

    public void setText(int viewId, CharSequence text) 
        mAlert.setText(viewId, text);
    

    public <T extends View> T getView(int viewId) 
        return mAlert.getView(viewId);
    

    public void setOnClickListener(int viewId, View.OnClickListener onClickListener) 
        mAlert.setOnClickListener(viewId, onClickListener);
    


//----------------------------------------------------------------------------------------------

    public static class Builder 
        private final AlertController.AlertParams P;

        public Builder(Context context) 
            this(context, R.style.dialog);
        


        public Builder(Context context, int themeResId) 
            P = new AlertController.AlertParams(context, themeResId);
        

        /**
         * 设置对话框布局
         *
         * @param view
         * @return
         */
        public Builder setContentView(View view) 
            P.mView = view;
            P.mLayoutResId = 0;
            return this;
        

        /**
         * @param layoutId
         * @return
         */
        public Builder setContentView(int layoutId) 
            P.mView = null;
            P.mLayoutResId = layoutId;
            return this;
        

        /**
         * 设置文本
         *
         * @param viewId
         * @param text
         * @return
         */
        public Builder setText(int viewId, CharSequence text) 
            P.mTextArray.put(viewId, text);
            return this;
        

        /**
         * 设置文本颜色
         *
         * @param viewId
         * @param color
         * @return
         */
        public Builder setTextColor(int viewId, int color) 
            P.mTextColorArray.put(viewId, color);
            return this;
        

        /**
         * 设置图标
         *
         * @param iconId
         * @return
         */
        public Builder setIcon(int iconId, int resId) 
            P.mIconArray.put(iconId, resId);
            return this;
        

        /**
         * 设置图片
         *
         * @param viewId
         * @return
         */
        public Builder setBitmap(int viewId, Bitmap bitmap) 
            P.mBitmapArray.put(viewId, bitmap);
            return this;
        

        /**
         * 设置对话框宽度占满屏幕
         *
         * @return
         */
        public Builder fullWidth() 
            P.mWidth = ViewGroup.LayoutParams.MATCH_PARENT;
            return this;
        

        /**
         * 对话框底部弹出
         *
         * @param isAnimation
         * @return
         */
        public Builder fromBottom(boolean isAnimation) 
            if (isAnimation) 
                P.mAnimation = R.style.dialog_from_bottom_anim;
            
            P.mGravity = Gravity.BOTTOM;
            return this;
        

        /**
         * 对话框右部弹出
         *
         * @param isAnimation
         * @return
         */
        public Builder fromRight(boolean isAnimation) 
            if (isAnimation) 
                P.mAnimation = R.style.dialog_scale_anim;
            以上是关于Android MVVM框架搭建PermissionAlertDialog拍照和相册选取的主要内容,如果未能解决你的问题,请参考以下文章

Android MVVM框架搭建ViewModel + LiveData + DataBinding

Android MVVM框架搭建ViewModel + LiveData + DataBinding

Android MVVM框架搭建高德地图定位天气查询BottomSheetDialog

Android MVVM框架搭建HiltViewBindingActivity Result API

Android MVVM框架搭建HiltViewBindingActivity Result API

Android MVVM框架搭建Navigation + Fragment + BottomNavigationView