首页 > 代码库 > 物品丢失与找回(结对项目)

物品丢失与找回(结对项目)

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 one rror(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 one rror(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

 

物品丢失与找回(结对项目)