Github地址:美食分享平台,欢迎star和fork
注:本文只包括活动的设计和头像组件的引用,不包括界面xml的设计,界面设计具体详见Android开发(3):个人信息界面设计
在上面的界面设计的基础上,这次任务主要分成两个大方面:照片和信息选择框。
在开始之前,首先要去学习一个开源库OptionPickerView的使用方法,这种库可以很简单是实现那个选择框的样式。
这一步就是每个人应该修改的地方,就是点击之后弹出来的信息不同。然后将下面的initOptionData加入到onCreate方法中。
//初始化性别、地址和生日的数据
private void initOptionData(){
//性别选择器数据
optionsItems_gender.add(new String("保密"));
optionsItems_gender.add(new String("男"));
optionsItems_gender.add(new String("女"));
//地址选择器数据
String province_data = readJsonFile("province.json");
String city_data = readJsonFile("city.json");
Gson gson = new Gson();
options1Items = gson.fromJson(province_data, new TypeToken>(){}.getType());
ArrayList cityBean_data = gson.fromJson(city_data, new TypeToken>(){}.getType());
for(ProvinceBean provinceBean:options1Items){
ArrayList temp = new ArrayList<>();
for (CityBean cityBean : cityBean_data){
if(provinceBean.getProvince().equals(cityBean.getProvince())){
temp.add(cityBean.getName());
}
}
options2Items.add(temp);
}
}
其中用到的readjson函数如下。但是在使用的时候需要主要把这两个json文件放在assets文件夹之中,如果不需要选地址或者json文件格式不同,可以自行修改读取方式。我使用的json文件可以在这个参考链接中下载,两个文件名字分别对应的文件。https://juejin.im/post/5de5f42cf265da05c621133a
//传入:asset文件夹中json文件名
//返回:读取的String
private String readJsonFile(String file){
StringBuilder newstringBuilder = new StringBuilder();
try {
InputStream inputStream = getResources().getAssets().open(file);
InputStreamReader isr = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(isr);
String jsonLine;
while ((jsonLine = reader.readLine()) != null) {
newstringBuilder.append(jsonLine);
}
reader.close();
isr.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
String data = newstringBuilder.toString();
return data;
}
性别栏的点击事件Onclick:
//点击修改性别逻辑
case R.id.ig_gender:
//性别选择器
pvOptions = new OptionsPickerBuilder(PersonInfo.this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int option2, int options3 ,View v) {
//选择了则显示并暂存LoginUser,退出时在保存至数据库
String tx = optionsItems_gender.get(options1);
ig_gender.getContentEdt().setText(tx);
loginUser.setGender(tx);
}
}).setCancelColor(Color.GRAY).build();
pvOptions.setPicker(optionsItems_gender);
pvOptions.show();
break;
//点击修改生日逻辑
case R.id.ig_brithday:
//时间选择器
//修改打开的默认时间,如果选择过则是选择过的时间,否则是系统默认时间
Calendar selectedDate = Calendar.getInstance();
if (loginUser.getBrithday() != null){
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
selectedDate.setTime(sdf.parse(loginUser.getBrithday()));
}catch (ParseException e){
e.printStackTrace();
}
}
//初始化picker并show
TimePickerView pvTime = new TimePickerBuilder(PersonInfo.this, new OnTimeSelectListener() {
@Override
public void onTimeSelect(Date date, View v) {
//选择了则显示并暂存LoginUser,退出时在保存至数据库
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
ig_brithday.getContentEdt().setText(sdf.format(date));
loginUser.setBrithday(sdf.format(date));
}
}).setDate(selectedDate).setCancelColor(Color.GRAY).build();
pvTime.show();
break;
//点击修改地区逻辑
case R.id.ig_region:
pvOptions = new OptionsPickerBuilder(this, new OnOptionsSelectListener() {
@Override
public void onOptionsSelect(int options1, int options2, int options3, View v) {
//选择了则显示并暂存LoginUser,退出时在保存至数据库
String tx = options1Items.get(options1).getPickerViewText()
+ options2Items.get(options1).get(options2);
ig_region.getContentEdt().setText(tx);
loginUser.setRegion(tx);
}
}).setCancelColor(Color.GRAY).build();
pvOptions.setPicker(options1Items, options2Items);//二级选择器
pvOptions.show();
break;
修改头像一般是两个方式:拍照和从相册中选取。这一部分在第一行代码第二版中有详细讲,这里就简略一些,方法很固定,一般直接使用即可,有兴趣的可以细读代码了解。
样式就不用多讲,可以根据自己喜欢改。photo_select.xml:
不会用popup方法的可以看这个链接Android PopupMenu and PopupWindow。
我就把展示的代码放在一个函数,看起来美观点:
//点击修改头像的逻辑
case R.id.ll_portrait:
//展示选择框,并设置选择框的监听器
show_popup_windows();
break;
下面代码看起来就很有难度,可以直接把里面的文件名字和按钮名字改成自己的名字,或者把调用逻辑修改即可。但是需要注意,调用相册和拍照都需要回调函数去处理返回的图片。
//展示修改头像的选择框,并设置选择框的监听器
private void show_popup_windows(){
RelativeLayout layout_photo_selected = (RelativeLayout) getLayoutInflater().inflate(R.layout.photo_select,null);
if(popupWindow==null){
popupWindow = new PopupWindow(layout_photo_selected, ActionBar.LayoutParams.MATCH_PARENT, ActionBar.LayoutParams.WRAP_CONTENT, true);
}
//显示popupwindows
popupWindow.showAtLocation(layout_photo_selected, Gravity.CENTER, 0, 0);
//设置监听器
TextView take_photo = (TextView) layout_photo_selected.findViewById(R.id.take_photo);
TextView from_albums = (TextView) layout_photo_selected.findViewById(R.id.from_albums);
LinearLayout cancel = (LinearLayout) layout_photo_selected.findViewById(R.id.cancel);
//拍照按钮监听
take_photo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(popupWindow != null && popupWindow.isShowing()) {
imageUri = photoUtils.take_photo_util(PersonInfo.this, "com.foodsharetest.android.fileprovider", "output_image.jpg");
//调用相机,拍摄结果会存到imageUri也就是outputImage中
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO);
//去除选择框
popupWindow.dismiss();
}
}
});
//相册按钮监听
from_albums.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//申请权限
if(ContextCompat.checkSelfPermission(PersonInfo.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(PersonInfo.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}else {
//打开相册
Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
startActivityForResult(intent, FROM_ALBUMS);
}
//去除选择框
popupWindow.dismiss();
}
});
//取消按钮监听
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (popupWindow != null && popupWindow.isShowing()) {
popupWindow.dismiss();
}
}
});
}
这就是处理回调的图片的代码,其中的TAKE_PHOTO这些变量,可以在类中设置为private final int类型,从1开始,不重复即可,作为处理的标志而已。
//处理拍摄照片回调
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode,data);
switch (requestCode){
//拍照得到图片
case TAKE_PHOTO:
if(resultCode == RESULT_OK){
try {
//将拍摄的图片展示并更新数据库
Bitmap bitmap = BitmapFactory.decodeStream((getContentResolver().openInputStream(imageUri)));
ri_portrati.setImageBitmap(bitmap);
loginUser.setPortrait(photoUtils.bitmap2byte(bitmap));
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
break;
//从相册中选择图片
case FROM_ALBUMS:
if(resultCode == RESULT_OK){
//判断手机版本号
if(Build.VERSION.SDK_INT >= 19){
imagePath = photoUtils.handleImageOnKitKat(this, data);
}else {
imagePath = photoUtils.handleImageBeforeKitKat(this, data);
}
}
if(imagePath != null){
//将拍摄的图片展示并更新数据库
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
ri_portrati.setImageBitmap(bitmap);
loginUser.setPortrait(photoUtils.bitmap2byte(bitmap));
}else{
Log.d("food","没有找到图片");
}
break;
default:
break;
}
}
PickerView
最全最新中国【省、市、区县、乡镇街道】json,csv,sql数据
Android PopupMenu and PopupWindow
Android 项目更换头像(拍照和选择相册)