代码经过简单的整理,已经放到Github上了。https://github.com/zhengweichao/Hevttc
回首来看,代码质量一般,里面也有各种逻辑问题,还望各位看官海涵。接下来有时间的话,会逐步进行优化。如果对你有帮助,还望可以给个star,不胜感激。
在校园生活中,存在着各种各样的信息差。也正因为这些信息差的存在,经常让校园同学们面临各种各样的问题。比如丢东西的找不到东西,捡到东西的找不到失主等等。其中最为突出的莫过于 【失物招领】及【二手交易】了。
校园作为一个比较特殊的地点,大家的素质以及诚信度普遍高于其它地方。“科师有约” 校园APP致力于减少校园信息差的存在,让校园生活更简单。
科师有约 只是一个美好的想法,并将部分功能从技术上进行简单实现。在实际生活中并未推广开来使用,在此权当抛砖引玉之用。还是希望学弟学妹们可以做出真正的产品,并在校园生活中得以应用。
本项目基于Bmob进行开发,很多地方需要Bmob相关知识。大家如果没了解过的话,可先自行查看 Bmob开发文档 。
系列文章:
Github地址: 科师有约校园APP
【失物招领】:
分为 寻物启事(找东西的)+ 失物招领(找失主的)
【二手交易】:
分为 淘点宝贝(想买东西的)+ 换点银子(想卖东西的)。效果图与失物招领类似
失物招领与二手交易,两个模块从整体逻辑上来说基本一致。因为我们只做简易实现,所以就两个模块就不再区分讲解(下简称 “需求” )。
(当然,这里还可以做很多很多优化,本文后面【未来可做的优化】部分会进一步讲解)
需要实现功能如下:
其中需求列表的展示页面,与 新闻中心模块 使用的技术代码基本相同。想了解的可以再退回去看 上篇文章。
(因两模块基本逻辑相似,仅就失物招领模块开讲)
为了使数据区分的更清楚,设计数据库时,将 “失物招领” 与 “寻物启事” 分别设置为两个表。其中的字段名称设计等均相同。字段如下:
字段名 | 描述 | 类型 | 是否主键 |
---|---|---|---|
objectId | 事件id号 | String | 是 |
title | 事件标题 | String | - |
tel | 联系方式 | Number | - |
author | 发布人 | String | - |
content | 事件详细描述 | String | - |
isOver | 事件处理状态 | Boolean | - |
createdAt | 事件发布时间 | Date | - |
(大家也可以设置为一个表,其中另外加一个字段进行区分)
此处应用的技术都比较简单。发布需求 其实就是简单的数据库的增加操作。带图片的需求需要再做一下进一步的处理(图片压缩以及上传)
LoseItem bean = new LoseItem();
MyUser user = BmobUser.getCurrentUser(MyUser.class);
bean.setAuthor(user.getUsername());
bean.setContent(loseDesc);
bean.setTel(loseTel);
bean.setTitle(loseTitle);
bean.save(new SaveListener<String>() {
@Override
public void done(String objectId, BmobException e) {
if (e == null) {
ToastUtil.show(LoseAddActivity.this, "发布成功", Toast.LENGTH_SHORT);
LoadDialog.dismiss(LoseAddActivity.this);
startActivity(new Intent(LoseAddActivity.this, LoseActivity.class));
finish();
} else {
ToastUtil.show(LoseAddActivity.this, "发布失败,请稍后再试", Toast.LENGTH_SHORT);
LoadDialog.dismiss(LoseAddActivity.this);
}
}
});
现在手机像素一般都很高,所以一个图片好几MB 的情况也很常见。直接上传的话,会极大浪费用户流量以及文件存储空间。所以需要对图片进行压缩处理后再上传。
所以发布有图片的需求需要拆分为以下 4 步来进行。
1. 选择图片
选择图片部分使用了 廖子尧 大神的 imagepicker 库。完全仿微信UI,实现了拍照、图片选择(单选/多选)、 裁剪 、旋转 等功能。
Github : imagepicker
作者:廖子尧 jeasonlzy
大神的文档写的十分详尽,集成方法我就不再赘述了。核心代码如下:
// 设置 图片选择器 相应参数
ImagePicker imagePicker = ImagePicker.getInstance();
imagePicker.setImageLoader(new GlideImageLoader()); //设置图片加载器
imagePicker.setShowCamera(true); //显示拍照按钮
imagePicker.setCrop(true); //允许裁剪(单选才有效)
imagePicker.setSaveRectangle(true); //是否按矩形区域保存
imagePicker.setSelectLimit(maxImgCount); //选中数量限制
imagePicker.setStyle(CropImageView.Style.RECTANGLE); //裁剪框的形状
imagePicker.setFocusWidth(800); //裁剪框的宽度。单位像素(圆形自动取宽高最小值)
imagePicker.setFocusHeight(800); //裁剪框的高度。单位像素(圆形自动取宽高最小值)
imagePicker.setOutPutX(1000); //保存文件的宽度。单位像素
imagePicker.setOutPutY(1000); //保存文件的高度。单位像素
// ...省略其它代码
// 开始选择图片
List<String> names = new ArrayList<>();
names.add("拍照");
names.add("相册");
showDialog(new SelectDialog.SelectDialogListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
switch (position) {
case 0:
// 直接调起相机
ImagePicker.getInstance().setSelectLimit(maxImgCount - selImageList.size());
Intent intent = new Intent(LoseAddActivity.this, ImageGridActivity.class);
intent.putExtra(ImageGridActivity.EXTRAS_TAKE_PICKERS, true); // 是否是直接打开相机
startActivityForResult(intent, REQUEST_CODE_SELECT);
break;
case 1:
//打开选择,本次允许选择的数量
ImagePicker.getInstance().setSelectLimit(maxImgCount - selImageList.size());
Intent intent1 = new Intent(LoseAddActivity.this, ImageGridActivity.class);
intent1.putExtra(ImageGridActivity.EXTRAS_IMAGES, images);
startActivityForResult(intent1, REQUEST_CODE_SELECT);
break;
}
}
}, names);
2. 图片压缩
图片压缩部分采用了 Luban(鲁班) —— Android图片压缩工具,仿微信朋友圈压缩策略。
作者采用逆向推算,效果已经很接近微信朋友圈压缩后的效果。
(再次踩在了巨人的肩膀上……)
Github : Luban(鲁班)
作者: Curzibn
核心代码如下:
Luban.with(LoseAddActivity.this)
.load(paths) // 传入要压缩的图片列表
.ignoreBy(100) // 忽略不压缩图片的大小
.setTargetDir(getPath()) // 设置压缩后文件存储位置
.setCompressListener(new OnCompressListener() { //设置回调
@Override
public void onStart() {
// 开始压缩 ...
}
@Override
public void onSuccess(File file) {
// 压缩成功 ...
}
@Override
public void onError(Throwable e) {
// 当压缩过程出现问题时调用
}
}).launch(); //启动压缩
3. 图片上传
这里是按照Bmob官方代码来写的。详情可见 Bmob文件管理 。
BmobFile.uploadBatch(filePaths, new UploadBatchListener() {
@Override
public void onSuccess(List<BmobFile> files, List<String> urls) {
// 上传图片成功
//1、files-上传完成后的BmobFile集合,是为了方便大家对其上传后的数据进行操作,例如你可以将该文件保存到表中
//2、urls-上传文件的完整url地址
}
@Override
public void onError(int statuscode, String errormsg) {
// 上传图片失败
LoadDialog.dismiss(LoseAddActivity.this);
}
@Override
public void onProgress(int curIndex, int curPercent, int total, int totalPercent) {
}
});
需要注意的是 上传多张图片,onSuccess 会多次调用 。别忘了做相应处理。
4. 发布需求
和发布无图片需求代码基本一致,只不过多了一句设置图片的代码。
LoseItem bean = new LoseItem();
// ... 省略其它代码
bean.setPic(files.get(0));
bean.save(new SaveListener<String>() {
@Override
public void done(String objectId, BmobException e) {
// ... 省略其它代码
}
});
至此,失物招领 & 二手交易模块基本完成。
然而整个流程中还有很多可以优化的地方,作者大概率没有时间和精力去做这部分了。
特将这部分内容整理如下,若他人有类似需求,以望能有所启迪或帮助。
简而言之,就是 提升平台能力。
因两个模块逻辑相似性较高,故此处以【失物招领】为例:
在一个完整的过程中,总共存在3方:丢东西的,捡东西的,平台。
本文上面已经讲解了最基础简易的沟通流程:
这种方式固然简单粗暴,但是显得不太灵活。
身为平台,应该发挥出平台更大的能力。那么应该从哪里开始入手呢?
校园是一个很特殊的地方,这里的失物招领有许多特殊之处,总结一下不难发现:
综上所述,未来如果有学弟学妹想做这部分,按个人看法,可做的优化如下:
至此,本文内容全部完毕,项目中大量依赖或采用了第三方项目的代码。在此向各位有分享精神的大佬们致敬!
如果本文对你有所帮助,还望可以随手赏一个点赞哈 ~ ~