使用Bmob实现失物招领app

失物招领app,这个app是非常适合初学者在学习数据库或bmob云数据库开发时练习的项目。在我完成这个app的开发后,确实收获很多,那么。这篇文章我来整理一下思路和开发时遇到的坎坷和解决方法。 首先常规的按流程来,先编写页面,这次的失物招领app,我所实现的功能很简单,所涉及的数据库的操作也是增、删、改、查。

一、页面设计

页面分类

登录页面(login.xml)
注册页面(register.xml)
发布页面(add_lost_information.xml)
浏览列表页面(lost_and_found.xml)
欢迎(启动)页面(welcome.xml)
浏览列表的内容页面(item.xml)
长按显示的编辑和删除的控件(pop_window_view.xml) (布局页面代码,看文章后面的代码链接)
二、设计与数据库中对应的实体数据类

这个根据在bmob里面的表来设计 举个例子 Person表,里面有String name 和 String password,那User.java就这样写。

package com.example.tone.bean;

import android.widget.Toast;

import java.lang.ref.SoftReference;

import cn.bmob.v3.BmobObject;
import cn.bmob.v3.exception.BmobException;
import cn.bmob.v3.listener.SaveListener;

import static cn.bmob.v3.Bmob.getApplicationContext;

public class Person extends BmobObject {
public String getName() {
return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

String name;
String password;

}

编写属性的Get和Set方法,AndroidStdio的快捷操作是,选中String name;String password;右键单击选择Greater,选择创建get和set方法。

三、与页面对应的功能类设计

这里主要编写这些页面的逻辑。

Welcome.java

主要的逻辑操作就是,显示开屏图片然后停留2秒,跳转到登录页面

//Bmob默认初始化
Bmob.initialize(this,“你自己的ID”);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//进入登录页面
Intent intent = new Intent(WelcomeActivity.this,LoginActivity.class);
startActivity(intent);
finish();
}
},2000);
login.java

获取用户输入的用户名和密码 使用bmob的login方法实现登录 单击“还没注册”跳转注册页面 登录代码代码如下

private void bmobUserAccotuntLogin(){
final String accountName = accountLoginName.getText().toString().trim(); //从控件中获取账号
final String accountPassword = accountLoginPassword.getText().toString().trim();//从控件中获取密码

    if(TextUtils.isEmpty(accountName)){
        showToast("账号不能为空");
        return;
    }

    if (TextUtils.isEmpty(accountPassword)){
        showToast("密码不能为空");
        return;
    }

    //登录过程

// 展示加载中的圈圈
showProgressBar();

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            //BmobUSer类为Bmob后端云提供的类
            BmobUser bmobUser = new BmobUser();
            bmobUser.setUsername(accountName);
            bmobUser.setPassword(accountPassword);
            bmobUser.login(new SaveListener() {
                @Override
                public void done(BmobUser bmobUser, BmobException e){
                    if (e==null){
                        //登录成功后进入主页面
                        Intent intent =new Intent(LoginActivity.this,LostAndFoundActivity.class);
                        startActivity(intent);
                        finish();
                    }else {
                        showToast(""+e.getMessage());
                        hiddenProgressBar(); //隐藏进度条
                    }
                }
            });

        }
    },3000);
}

Register.java

主要逻辑 填写数据 点击注册 关键代码

private void bmobRegisterAccount(){
final String registerName = accountRegisterName.getText().toString().trim(); //从控件中获取账号
final String registerPasswor = accountRegisterPassword.getText().toString().trim(); //从控件中获取密码

    if (TextUtils.isEmpty(registerName)||TextUtils.isEmpty(registerPasswor)){
        showToast("注册账号或密码为空");
        return;
    }

    BmobUser bmobUser = new BmobUser();  //实例化对象
    bmobUser.setUsername(registerName);   //添加账号到数据库
    bmobUser.setPassword(registerPasswor);  //添加密码到数据库
    bmobUser.signUp(new SaveListener() {
        @Override
        public void done(BmobUser bmobUser, BmobException e){
            if (e==null){
                showToast("注册账号成功");
                finish();
            }else {
                showToast("register fail:" + e.getMessage());
            }
        }
    });
}

当然有查重代码

private void registerAccount(){
final String registerName = accountRegisterName.getText().toString().trim(); //获取账号
final String registerPassword = accountRegisterPassword.getText().toString().trim(); //获取密码

    //为空判断
    if (TextUtils.isEmpty(registerName) || TextUtils.isEmpty(registerPassword)) {
        showToast("注册账号或密码为空");
        return;
    }

    //账号查询  防止重复注册
    BmobQuery registerUserBmobQuery = new BmobQuery<>();
    registerUserBmobQuery.order("-createdAt");  //数据库操作  按时间排序
    registerUserBmobQuery.findObjects(new FindListener() {
        @Override
        public void done(List lists, BmobException e) {
            for (RegisterUser list : lists){
                if (registerName.equals(list.getRegisterName())){
                    showToast("账号已被注册,请重新注册");

                }else{
                    registerAccount(registerName, registerPassword);
                }
            }
        }
    });
}

浏览页面LostAndFound.java

这个页面是展示别的用户或自己发布的失物招领帖子 主要操作:

加载页面将内(条目)放在Recycleview的适配器里

private void initData(){
BmobQuerylostInfomationReqBmobQuery = new BmobQuery<>();
lostInfomationReqBmobQuery.order("-updateAt"); //排序
lostInfomationReqBmobQuery.findObjects(new FindListener() {
@Override
public void done(List list, BmobException e) {
if (e== null){
lostInfomationReqList = list;
lostAndFoundAdapter.setData(list);
recyclerView.setAdapter(lostAndFoundAdapter);
}else {
showToast(“查询数据失败”);
}
}
});
}
刷新页面

//监测页面刷新
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
switch (requestCode){
case REQUEST_CODE:
if (resultCode == RESULT_OK){
refreshData(); //数据刷新
}
break;
default:
break;
}
}

/*
* 查询数据库中的最新数据
*
* */
private void refreshData(){
    BmobQuery lostInfomationReqBmobQuery = new BmobQuery<>();
    lostInfomationReqBmobQuery.order("-updatedAt");//按更新时间排序
    lostInfomationReqBmobQuery.findObjects(new FindListener() {
        @Override
        public void done(List list, BmobException e) {
            if (e == null) {
                lostInfomationReqList = list;
                lostAndFoundAdapter.setData(list);
                lostAndFoundAdapter.notifyDataSetChanged();
            }
        }
    });
}

长按内容(条目)可以选择和删除或编辑

@Override
public void onEditOrDeleteClick(int position, int code){
if (code == LostAndFoundAdapter.EDIT_CODE){
/带参页面跳转/
Intent intent = new Intent(LostAndFoundActivity.this, AddLostInformationActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable(“editData”, lostInfomationReqList.get(position));
intent.putExtras(bundle);
startActivityForResult(intent, REQUEST_CODE);
} else if (code == LostAndFoundAdapter.DELETE_CODE) {
deleteItemData(position);
}
}

private void deleteItemData(final int position){
    if (lostInfomationReqList.size()!=0){
        LostInfomationReq lostInfomationReq =new LostInfomationReq();
        lostInfomationReq.setObjectId(lostInfomationReqList.get(position).getObjectId());
        lostInfomationReq.delete(new UpdateListener() {
            @Override
            public void done(BmobException e) {
                if (e==null){
                    lostInfomationReqList.remove(position);
                    lostAndFoundAdapter.setData(lostInfomationReqList);
                    lostAndFoundAdapter.notifyDataSetChanged();
                }else {
                    showToast("数据删除失败");
                }
            }
        });
    }
}

点击右上角的加号图片跳转到发布(AddLostAndFound)页面

public void onClick(View v){
switch (v.getId()){
case R.id.iv_add:
Intent intent =new Intent(LostAndFoundActivity.this,AddLostInformationActivity.class);
startActivityForResult(intent,REQUEST_CODE);
break;
default:
break;
}
}
点击返回弹出“再按一次退出应用”

@Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK){
if (System.currentTimeMillis() - exitTime>2000){
showToast(“再按一次退出程序”);
exitTime = System.currentTimeMillis();
}else {
android.os.Process.killProcess(android.os.Process.myPid());
}
}
return false;
}
AddLostAndFound.java

由于长按也会跳转到此,所以需要判断是编辑(更新)还是新发布(添加) 更新

private void updataInfo(String titleName,String num,String descidle){
LostInfomationReq lostInfomationReq = new LostInfomationReq();
lostInfomationReq.setTitle(titleName); //titleName 为用户输入的标题
lostInfomationReq.setPhoneNum(num);
lostInfomationReq.setDesc(descidle);
lostInfomationReq.update(infomationReq.getObjectId(), new UpdateListener() {
@Override
public void done(BmobException e) {
if (e== null){
showToast(“更新信息成功”);
//更新数据后提示主界面进行数据刷新
Intent intent = new Intent();
setResult(RESULT_OK,intent);
finish();
}
}
});
}
添加数据

private void publishLostInfo(String titleName,String num,String descridle){
LostInfomationReq lostInfomationReq = new LostInfomationReq();
lostInfomationReq.setTitle(titleName);//titleName为用户输入的标题
lostInfomationReq.setPhoneNum(num);//num为用户输入的号码
lostInfomationReq.setDesc(descridle);//descridle为信息描述
lostInfomationReq.save(new SaveListener() {
@Override
public void done(String s, BmobException e) {
if (e==null){
showToast(“招领信息发布成功”);
//成功后提示主界面刷新数据
Intent intent =new Intent();
setResult(RESULT_OK,intent);
//成功后将页面销毁
finish();
}else {
showToast(“信息发布失败”);
}
}
});
}
四、编写适配器(Adapter)

适配器就好像是这个布局里的容器,它需要适配多种可能的item(条目),而这个条目是可以图文混合的,排列方式也是多种多样,所以需要Adapter去适配(封装)。 代码如下 有时间可以去好好研究,很有趣

public class LostAndFoundAdapter extends RecyclerView.Adapter {
private Context mContext;
private ListlostInfosData;
private ItemClickListener mItemClickListener;
public final static int EDIT_CODE = 998;
public final static int DELETE_CODE = 997;

public LostAndFoundAdapter(Context context){
    this.mContext=context;
}

public void setData(List data){
    this.lostInfosData=data;
}



/*创建recycleview*/
@Override
public LostAndFoundHolder onCreateViewHolder( ViewGroup parent, int viewType) {
    /*传入内容页面 itme.xml*/
    View view = LayoutInflater.from(mContext).inflate(R.layout.lost_itme,parent,false);
    LostAndFoundHolder lostAndFoundHolder = new LostAndFoundHolder(view);
    return lostAndFoundHolder;
}


/*传入数据*/
@Override
public void onBindViewHolder(@NonNull final LostAndFoundAdapter.LostAndFoundHolder holder, final int position) {

// 绑定数据
if (lostInfosData!=null){
LostInfomationReq lostInfomationReq = lostInfosData.get(position);
holder.title.setText(lostInfomationReq.getTitle());
holder.desc.setText(lostInfomationReq.getDesc());
holder.phoneNum.setText(lostInfomationReq.getPhoneNum());
holder.time.setText(lostInfomationReq.getCreatedAt());

        holder.IIitem.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {

// mLongClickListener.onLongClick(position);
showWindow(holder,position);
return false;
}
});
}
}

//长按后方法  显示
private void showWindow(LostAndFoundHolder holder,final int pos){
    //加载布局文件
    View contenview = LayoutInflater.from(mContext).inflate(R.layout.pop_window_view,null);
    final PopupWindow popupWindow = new PopupWindow(contenview,LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
    //设置焦点
    popupWindow.setFocusable(true);
    //触摸框外
    popupWindow.setOutsideTouchable(true);
    //点击空白处的时候让PopupWindow消失
    popupWindow.setBackgroundDrawable(new ColorDrawable(0x00000000));
    //设置出现时候的偏移量
    popupWindow.showAsDropDown(holder.time,300,-100);

    //showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
    // showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
    //showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移

    //点击编辑按钮
    contenview.findViewById(R.id.edit_btn).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //回调给主界面,进行数据操作
            mItemClickListener.onEditOrDeleteClick(pos,EDIT_CODE);
            //销毁弹出框
            popupWindow.dismiss();
        }
    });
    //点击删除按钮
    contenview.findViewById(R.id.delete_btn).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //回调给主界面,进行数据操作
            mItemClickListener.onEditOrDeleteClick(pos,DELETE_CODE);
            //销毁弹出框
            popupWindow.dismiss();
        }
    });
}


/*计数  看看创建了几个 item*/
@Override
public int getItemCount() {

    return lostInfosData.size()==0?0:lostInfosData.size();
}


/*绑定条目页面的控件 (子控件)*/
public class LostAndFoundHolder extends RecyclerView.ViewHolder{
    private TextView title;
    private TextView desc;
    private TextView time;
    private TextView phoneNum;
    private LinearLayout IIitem;

    public LostAndFoundHolder(View itemView){
        super(itemView);
        title =(TextView)itemView.findViewById(R.id.tv_title);
        desc = (TextView) itemView.findViewById(R.id.tv_desc);
        time = (TextView) itemView.findViewById(R.id.tv_time);
        phoneNum = (TextView) itemView.findViewById(R.id.tv_num);
        IIitem = (LinearLayout) itemView.findViewById(R.id.II_item);
    }
}
/*
* 设置长按事件
* */
public void setLongClickListener(ItemClickListener clickListener){
    this.mItemClickListener = clickListener;
}

public interface ItemClickListener{
    void onEditOrDeleteClick(int position,int code);
}

}

你可能感兴趣的:(java学习,Android,studio)