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