物品丟失與找回(結對項目)
Lost and Found(失物招領APP)
Lost and Found(失物招領APP)是以Bmob為基礎的,參考了網上的案例。主要實現物品的發布、修改、呈現和刪除。使用場景如下:用戶撿到物品,打開手機軟件,填寫物品的招領信息(標題、描述和聯系方式);用戶丟失物品,打開手機軟件,填寫物品的丟失信息(標題、描述和聯系方式);任何人都可以查看到失物和招領的信息列表,可以對發布的信息進行刪除。該項目將使用到Bmob的以下幾個功能:
1、 添加數據
添加失物/招領信息到服務器中。
2、 查找數據
在列表中顯示所有用戶發布的失物/招領信息。
3、 刪除數據
刪除已發布的失物/招領信息。
部分界面效果如下:
進入動畫 主界面
失物信息界面添加失物信息界面
失物列表 編輯刪除
數據結構設計
失物表(Lost) | ||
字段名 | 類型 | 描述 |
describe | String | 失物的描述信息 |
phone | String | 聯系的手機號碼 |
title | String | 失物的標題信息 |
招領表(Found) | ||
字段名 | 類型 | 描述 |
describe | String | 招領的描述信息 |
phone | String | 聯系的手機號碼 |
title | String | 招領的標題信息 |
初始化SDK
Bmob為每個應用都提供了一個唯一標識,使用Bmob開發的應用都要首先使用這個Application ID”進行初始化(在前面博客中已經提到)。對應代碼如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //初始化 Bmob SDK,第一個參數為上下文,第二個參數為Application ID Bmob.initialize(this, Constants.Bmob_APPID); //其他代碼 }
Lost類和Found類
為操作Bmob的雲端數據庫,SDK首先需要創建數據表對應的模型類(模型類的名稱必須和雲端數據表的名稱一致),該類需要繼承自BmobObject,實現剛剛創建的數據表字段的set和get方法(系統默認字段objectId、createAt、updateAt不需要聲明)。因為項目需要操作Lost表和Found表,因此需要創建Lost類和Found類。
創建失物對象
public class Lost extends BmobObject{ private String title;//標題 private String describe;//描述 private String phone;//聯系手機 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
創建招領對象
public class Found extends BmobObject { private String title;//標題 private String describe;//描述 private String phone;//聯系手機 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
添加失物/招領信息
用戶填寫了失物信息之後,只需要構造一個Lost實例,然後簡單調用模型類的insertObject方法就可以將信息添加到雲數據庫中,實現代碼如下:
public class AddActivity extends BaseActivity implements OnClickListener { EditText edit_title, edit_photo, edit_describe; Button btn_back, btn_true; TextView tv_add; String from = ""; String old_title = ""; String old_describe = ""; String old_phone = ""; @Override public void setContentView() { // TODO Auto-generated method stub setContentView(R.layout.activity_add); } @Override public void initViews() { // TODO Auto-generated method stub tv_add = (TextView) findViewById(R.id.tv_add); btn_back = (Button) findViewById(R.id.btn_back); btn_true = (Button) findViewById(R.id.btn_true); edit_photo = (EditText) findViewById(R.id.edit_photo); edit_describe = (EditText) findViewById(R.id.edit_describe); edit_title = (EditText) findViewById(R.id.edit_title); } @Override public void initListeners() { // TODO Auto-generated method stub btn_back.setOnClickListener(this); btn_true.setOnClickListener(this); } @Override public void initData() { // TODO Auto-generated method stub from = getIntent().getStringExtra("from"); old_title = getIntent().getStringExtra("title"); old_phone = getIntent().getStringExtra("phone"); old_describe = getIntent().getStringExtra("describe"); edit_title.setText(old_title); edit_describe.setText(old_describe); edit_photo.setText(old_phone); if (from.equals("Lost")) { tv_add.setText("添加失物信息"); } else { tv_add.setText("添加招領信息"); } } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v == btn_true) { addByType(); } else if (v == btn_back) { finish(); } } String title = ""; String describe = ""; String photo=""; /**根據類型添加失物/招領 * */ private void addByType(){ title = edit_title.getText().toString(); describe = edit_describe.getText().toString(); photo = edit_photo.getText().toString(); if(TextUtils.isEmpty(title)){ ShowToast("請填寫標題"); return; } if(TextUtils.isEmpty(describe)){ ShowToast("請填寫描述"); return; } if(TextUtils.isEmpty(photo)){ ShowToast("請填寫手機"); return; } if(from.equals("Lost")){ addLost(); }else{ addFound(); } } private void addLost(){ Lost lost = new Lost(); lost.setDescribe(describe); lost.setPhone(photo); lost.setTitle(title); lost.save(this, new SaveListener() { @Override public void onSuccess() { // TODO Auto-generated method stub ShowToast("失物信息添加成功!"); setResult(RESULT_OK); finish(); } @Override public void onFailure(int code, String arg0) { // TODO Auto-generated method stub ShowToast("添加失敗:"+arg0); } }); } private void addFound(){ Found found = new Found(); found.setDescribe(describe); found.setPhone(photo); found.setTitle(title); found.save(this, new SaveListener() { @Override public void onSuccess() { // TODO Auto-generated method stub ShowToast("招領信息添加成功!"); setResult(RESULT_OK); finish(); } @Override public void onFailure(int code, String arg0) { // TODO Auto-generated method stub ShowToast("添加失敗:"+arg0); } }); } }
獲取失物/招領列表、刪除失物招領信息
項目使用到Bmob提供的最簡單的查詢和排序功能,直接調用BmobQuery類的findObjects方法和order方法來獲取失物列表。從雲數據庫中刪除某條記錄需要設置這個要刪除的ObjectId的信息,再調用模型類的deleteObject方法就可以了,實現代碼如下
public class MainActivity extends BaseActivity implements OnClickListener, IPopupItemClick, OnItemLongClickListener { RelativeLayout layout_action;// LinearLayout layout_all; TextView tv_lost; ListView listview; Button btn_add; protected QuickAdapter<Lost> LostAdapter;// 失物 protected QuickAdapter<Found> FoundAdapter;// 招領 private Button layout_found; private Button layout_lost; PopupWindow morePop; RelativeLayout progress; LinearLayout layout_no; TextView tv_no; @Override public void setContentView() { // TODO Auto-generated method stub setContentView(R.layout.activity_main); } @Override public void initViews() { // TODO Auto-generated method stub progress = (RelativeLayout) findViewById(R.id.progress); layout_no = (LinearLayout) findViewById(R.id.layout_no); tv_no = (TextView) findViewById(R.id.tv_no); layout_action = (RelativeLayout) findViewById(R.id.layout_action); layout_all = (LinearLayout) findViewById(R.id.layout_all); // 默認是失物界面 tv_lost = (TextView) findViewById(R.id.tv_lost); tv_lost.setTag("lost"); listview = (ListView) findViewById(R.id.list_lost); btn_add = (Button) findViewById(R.id.btn_add); // 初始化長按彈窗 initEditPop(); } @Override public void initListeners() { // TODO Auto-generated method stub listview.setOnItemLongClickListener(this); btn_add.setOnClickListener(this); layout_all.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub if (v == layout_all) { showListPop(); } else if (v == btn_add) { Intent intent = new Intent(this, AddActivity.class); intent.putExtra("from", tv_lost.getTag().toString()); startActivityForResult(intent, Constants.REQUESTCODE_ADD); } else if (v == layout_found) { changeTextView(v); morePop.dismiss(); queryFounds(); } else if (v == layout_lost) { changeTextView(v); morePop.dismiss(); queryLosts(); } } @Override public void initData() { // TODO Auto-generated method stub if (LostAdapter == null) { LostAdapter = new QuickAdapter<Lost>(this, R.layout.item_list) { @Override protected void convert(BaseAdapterHelper helper, Lost lost) { helper.setText(tv_title, lost.getTitle()) .setText(tv_describe, lost.getDescribe()) .setText(tv_time, lost.getCreatedAt()) .setText(tv_photo, lost.getPhone()); } }; } if (FoundAdapter == null) { FoundAdapter = new QuickAdapter<Found>(this, R.layout.item_list) { @Override protected void convert(BaseAdapterHelper helper, Found found) { helper.setText(tv_title, found.getTitle()) .setText(tv_describe, found.getDescribe()) .setText(tv_time, found.getCreatedAt()) .setText(tv_photo, found.getPhone()); } }; } listview.setAdapter(LostAdapter); // 默認加載失物界面 queryLosts(); } private void changeTextView(View v) { if (v == layout_found) { tv_lost.setTag("Found"); tv_lost.setText("Found"); } else { tv_lost.setTag("Lost"); tv_lost.setText("Lost"); } } @SuppressWarnings("deprecation") private void showListPop() { View view = LayoutInflater.from(this).inflate(R.layout.pop_lost, null); // 註入 layout_found = (Button) view.findViewById(R.id.layout_found); layout_lost = (Button) view.findViewById(R.id.layout_lost); layout_found.setOnClickListener(this); layout_lost.setOnClickListener(this); morePop = new PopupWindow(view, mScreenWidth, 600); morePop.setTouchInterceptor(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_OUTSIDE) { morePop.dismiss(); return true; } return false; } }); morePop.setWidth(WindowManager.LayoutParams.MATCH_PARENT); morePop.setHeight(WindowManager.LayoutParams.WRAP_CONTENT); morePop.setTouchable(true); morePop.setFocusable(true); morePop.setOutsideTouchable(true); morePop.setBackgroundDrawable(new BitmapDrawable()); // 動畫效果 從頂部彈下 morePop.setAnimationStyle(R.style.MenuPop); morePop.showAsDropDown(layout_action, 0, -dip2px(this, 2.0F)); } private void initEditPop() { mPopupWindow = new EditPopupWindow(this, 200,48); mPopupWindow.setOnPopupItemClickListner(this); } EditPopupWindow mPopupWindow; int position; @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub position = arg2; int[] location = new int[2]; arg1.getLocationOnScreen(location); mPopupWindow.showAtLocation(arg1, Gravity.RIGHT | Gravity.TOP, location[0], getStateBar() + location[1]); return false; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { return; } switch (requestCode) { case Constants.REQUESTCODE_ADD:// 添加成功之後的回調 String tag = tv_lost.getTag().toString(); if (tag.equals("Lost")) { queryLosts(); } else { queryFounds(); } break; } } /** * 查詢全部失物信息 queryLosts * * */ private void queryLosts() { showView(); BmobQuery<Lost> query = new BmobQuery<Lost>(); query.order("-createdAt");// 按照時間降序 query.findObjects(this, new FindListener<Lost>() { @Override public void onSuccess(List<Lost> losts) { // TODO Auto-generated method stub LostAdapter.clear(); FoundAdapter.clear(); if (losts == null || losts.size() == 0) { showErrorView(0); LostAdapter.notifyDataSetChanged(); return; } progress.setVisibility(View.GONE); LostAdapter.addAll(losts); listview.setAdapter(LostAdapter); } @Override public void onError(int code, String arg0) { // TODO Auto-generated method stub showErrorView(0); } }); } public void queryFounds() { showView(); BmobQuery<Found> query = new BmobQuery<Found>(); query.order("createdAt");// 按照時間降序 query.findObjects(this, new FindListener<Found>() { @Override public void onSuccess(List<Found> arg0) { // TODO Auto-generated method stub LostAdapter.clear(); FoundAdapter.clear(); if (arg0 == null || arg0.size() == 0) { showErrorView(1); FoundAdapter.notifyDataSetChanged(); return; } FoundAdapter.addAll(arg0); listview.setAdapter(FoundAdapter); progress.setVisibility(View.GONE); } @Override public void onError(int code, String arg0) { // TODO Auto-generated method stub showErrorView(1); } }); } /** * 請求出錯或者無數據時候顯示的界面 showErrorView * */ private void showErrorView(int tag) { progress.setVisibility(View.GONE); listview.setVisibility(View.GONE); layout_no.setVisibility(View.VISIBLE); if (tag == 0) { tv_no.setText(getResources().getText(R.string.list_no_data_lost)); } else { tv_no.setText(getResources().getText(R.string.list_no_data_found)); } } private void showView() { listview.setVisibility(View.VISIBLE); layout_no.setVisibility(View.GONE); } @Override public void onEdit(View v) { // TODO Auto-generated method stub String tag = tv_lost.getTag().toString(); Intent intent = new Intent(this, AddActivity.class); String title = ""; String describe = ""; String phone = ""; if (tag.equals("Lost")) { title = LostAdapter.getItem(position).getTitle(); describe = LostAdapter.getItem(position).getDescribe(); phone = LostAdapter.getItem(position).getPhone(); } else { title = FoundAdapter.getItem(position).getTitle(); describe = FoundAdapter.getItem(position).getDescribe(); phone = FoundAdapter.getItem(position).getPhone(); } intent.putExtra("decribe", describe); intent.putExtra("phone", phone); intent.putExtra("title", title); intent.putExtra("from", tag); startActivityForResult(intent, Constants.REQUESTCODE_ADD); } @Override public void onDelete(View v) { // TODO Auto-generated method stub String tag = tv_lost.getTag().toString(); if (tag.equals(”Lost")) { deleteLost(); } else { deleteFound(); } } private void deleteLost() { Lost lost = new Lost(); lost.setObjectId(LostAdapter.getItem(position).getObjectId()); lost.delete(this, new DeleteListener() { @Override public void onSuccess() { // TODO Auto-generated method stub LostAdapter.remove(position); } @Override public void onFailure(int code, String arg0) { // TODO Auto-generated method stub } }); } private void deleteFound() { Found found = new Found(); found.setObjectId(FoundAdapter.getItem(position).getObjectId()); found.delete(this, new DeleteListener() { @Override public void onSuccess() { // TODO Auto-generated method stub FoundAdapter.remove(position); } @Override public void onFailure(int code, String arg0) { // TODO Auto-generated method stub } }); } }
結對成員已將登錄與註冊界面設計發布 可參考http://www.cnblogs.com/buyaping/p/6942822.html
物品丟失與找回(結對項目)