The Development Of Ordering System Based On Android Technology

Outline

This app, “Ordering system”, helps customers reserve a table, pre-order some dishes and indicate the exact time they may arrive at the restaurant. This is my undergraduate individual project from 15/10/2017 to 15/11/2017, and I have made some improvements afterward.

Demo

I have shown all functions of this app in this video.

Environment

Development tool: Android studio and SQLite database in it
Language: Java and Android technology

App Components

This app contains login page and four fragments which involve many activities, let me introduce them one by one.

Login page

Detect whether the user is a new customer or an old customer. If the user is a new customer( or the first customer of the app), *** creates a new user id*** for him automatically and stores his name and password in the database, else if the name exists in the database, check whether the password is correct. If the user ticks checkbox, the system will remember the password automatically and the user can log in directly without typing the password again.

Four Fragments

Main Fragment

Main fragment involves some pages, such as main page (include start button)

Main page: This page shows some special dishes of the restaurant, the blue imageview button means “start to order”.

Table ordering page: this page includes 7 tables, initially all tables being available, but after the table has been ordered, it will show grey color, which means the user cannot order it.

Food showing page: this page shows all types of food. For example, the left menu part contains “special, main, drink, meat dish, vegetable, soup”, the right home part contains relative food. Everytime the user presses add or sub button, the number of each food will change, and the bottom of this page will show the total money. The red button at the bottom of this page means “show bill”.

Everytime the user presses the shopping cart button, he can view all the food he has chosen. If he feels very expensive, he can adjust the food he has chosen.

Bill showing page: this page shows after the user presses “show bill” button of the last page, he can view all the food he has ordered. After the user edits the time he arrives at the restaurant, he can submit this bill (food name, number, price) by pressing the red submit button and wait for the restaurant to accept it.

When the user presses the red button, the system will store all the bill details in the SQLite database “customer.db”, and this page shows “waiting for the restaurant to accept it!”, (note if the user presses the blue button(back to the main page), the record will not be stored). After the user waits for a while, it will show “restaurant has accepted” at last.

Order Fragment

This fragment helps the user check the bills, since one customer pre-orders more than one time, when he clicks the bill, it will show the details of the bill.

Trends Fragment

This fragment allows all the customers to give their remarks to the restaurant, this fragment contains 4 elements: edit text, 3 buttons. The first button means “submit”, and each customer can write down their remarks and then submit it. Since one customer can submit more than one remark, so the second button means “manage”, with which customers can manage(delete) their remarks. The third button means “view the remarks of other customers”. Let me introduce them one by one.

Remarks submitting: After the user writes down his or her remark, and presses the first button, the screen will show “the remark has been submitted!”

Remarks managing: When the user presses the second button, it will show all remarks, when the user presses one remark item and swipe left, “delete” button will show in his right-hand side. If he or she clicks this delete button, that remark will be deleted from all remarks.

Remarks viewing: When the user presses the third button, all the remarks given by all customers will show.

My Fragment

The last fragment has four main functions (buttons): Personal information management, Contact with restaurant, Software version checking and Exit.

Personal information management: This page shows the basic information of the customer, such as name, image, age and gender, when the user presses the blue button(“edit”), the user can choose his image from his own photo album and edits his age and gender (name cannot be changed)

After the user confirms the change, all the information will be updated.

Contact with restaurant, software version checking and exit

SQLite Database

The most important part is to store the customer data, such as their name, password, recommendation, ordering details, and so on, in the database.
database

The data detail in database: (id,name,pwd,rec,orderdetail)
在这里插入图片描述
The data detail in database:(age,gender,photo)

Technical Focus

Food Showing

As you can see in the food showing page, the functions are achieved by the code of FoodShowActivity.java which below mainly set up three adapters:

  1. Left adapter (for menu)
  2. Right dish home (listview of food) order adapter
  3. Shop cart simple adapter

Orderadapter.java
Main idea: Set up listeners for add or sub button and use viewholder to cope with the scrolling of the listview, which can reduce the consumption of RAM (with no need to create many objects)

public class OrderAdapter extends BaseAdapter {

    private List<DishSelect> dss = new ArrayList<>();
    private Context context;
    //1.set up ClickListener for sub or add button
    private View.OnClickListener onAddNum;
    private View.OnClickListener onSubNum;
    public void setOnAddNum(View.OnClickListener onAddNum) {
        this.onAddNum = onAddNum;
    }
    
    public void setOnSubNum(View.OnClickListener onSubNum) {
        this.onSubNum = onSubNum;
    }
    
    public OrderAdapter(Context context) {
        this.context = context;
    }

    public void updateData(List<DishSelect> list) {//updata data source according to the clicked left menu item
        if(!dss.isEmpty()) dss.clear();
        dss.addAll(list);
        this.notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        int ret = 0;
        if (dss != null) {
            ret = dss.size();
        }
        return ret;
    }

    @Override
    public Object getItem(int i) {
        return dss.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        View v = null;
        if (view != null) {
            v = view;
        } else {
            v = LayoutInflater.from(this.context).inflate(R.layout.food_show_listview_content, viewGroup, false);
        }

        ViewHolder holder = (ViewHolder) v.getTag();
        if (holder == null) {
            holder = new ViewHolder();
            holder.item_title = (TextView) v.findViewById(R.id.title);
            holder.item_img = (ImageView) v.findViewById(R.id.img_food);
            holder.item_price = (TextView) v.findViewById(R.id.price);
            holder.item_num = (TextView) v.findViewById(R.id.number);

            //register the listeners in real layout components 
            holder.item_btn_add = (ImageView) v.findViewById(R.id.btn_add);
            holder.item_btn_add.setOnClickListener(onAddNum);

            holder.item_btn_sub = (ImageView) v.findViewById(R.id.btn_sub);
            holder.item_btn_sub.setOnClickListener(onSubNum);

        }

        holder.item_title.setText(dss.get(i).getName());
        holder.item_img.setImageResource((dss.get(i).getPic()));
        holder.item_price.setText(dss.get(i).getPrice());
        holder.item_num.setText(dss.get(i).getNum() + "");
       

        //set up Tag, help locate which item of right dish home has been clicked
        holder.item_btn_add.setTag(i);
        holder.item_btn_sub.setTag(i);

        v.setTag(holder);
        return v;
    }

    private static class ViewHolder {
        private TextView item_num;
        private TextView item_title;
        private ImageView item_img;
        private TextView item_price;
        private ImageView item_btn_add;
        private ImageView item_btn_sub;

    }
}

FoodShowActivity.java:
Main idea: create a List of dish groups as data sources. When the user chooses a different menu item, the data source will be changed according to the position of the menu item.

public class FoodShowActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {
    //Initialize all the layout components
    private ListView listView_foods = null;
    private ListView listview_shopcar = null;
    private ListView lv_menu;
    private ImageView img_order_submit = null;
    private ImageView view_shopcar = null;
    private TextView all_amount = null;

    private int pos;//table number
    private List<List<DishSelect>> alldatas;//contains different types of dish group
    private List<DishSelect> datas; //List of one dish group,e.g.special or drink
    private OrderAdapter adapter; //customized adapter used by right dish home
    LeftAdapter leftAdapter;//adpater used by left menu

    /*create observer: when Adapter.notifyDataSetChanged() is executed, 
    this  observer will be called to sum up current total money*/
    private DataSetObserver sumObserver = new DataSetObserver() {
        @Override
        public void onChanged() {
            super.onChanged();
            int sum = 0;
            for (int i = 0; i < alldatas.size(); i++) {
                for (int j = 0; j < alldatas.get(i).size(); j++)
                {
                    sum += alldatas.get(i).get(j).getNum() * Integer.parseInt(alldatas.get(i).get(j).getPrice());
                }

            }

            all_amount = (TextView) findViewById(R.id.all_amount);
			all_amount.setText(sum+"元");

        }
        @Override
        public void onInvalidated() {
            super.onInvalidated();//invalidate
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_food_show);
        listView_foods = (ListView) findViewById(R.id.listView_foods);
        all_amount = (TextView) findViewById(R.id.all_amount);
        img_order_submit = (ImageView) findViewById(R.id.img_order_submit);
        lv_menu = (ListView)findViewById(R.id.lv_menu);
        view_shopcar = (ImageView) findViewById(R.id.shopcar);

        //initialize left adapter
        leftAdapter = new LeftAdapter(getBaseContext());
        lv_menu.setAdapter(leftAdapter);

        // initialize data source and right adapter
        alldatas = DishSelect.getdishgroup();
        datas = alldatas.get(0);
        adapter = new OrderAdapter(this);
        adapter.updateData(datas);
        adapter.setOnAddNum(this);// sub button
        adapter.setOnSubNum(this);
        adapter.registerDataSetObserver(sumObserver);
        listView_foods.setAdapter(adapter);
        listView_foods.setOnItemClickListener(this);

        /*when the menu item in left handside has been clicked, 
        /the data source of right handside (dish home) should be updated*/
        lv_menu.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
                leftAdapter.updateData(arg2); 
                datas = alldatas.get(arg2);
                adapter.updateData(datas);

            }
        });

        img_order_submit.setOnClickListener(listener);// sum up(calculate) imageview
        view_shopcar.setOnClickListener(new View.OnClickListener() {//shopcar imageview
            @Override
            public void onClick(View v) {
                setDialog();

            }
        });

        Intent intent = getIntent();// get the data passed by last page
        Bundle b = intent.getExtras();
        pos = b.getInt("pos");

    }


    @Override
    public void onClick(View view) {
        Object tag = view.getTag();
        switch (view.getId()) {
            case R.id.btn_add: //add button
                // get Tag set up by adapter
                if (tag != null && tag instanceof Integer) {    
                //get position through value of Tag 
                    int position = (Integer) tag;
                    int num = datas.get(position).getNum();
                    num++;
                    datas.get(position).setNum(num); //change the number of dish                  
                    adapter.notifyDataSetChanged();//when the user presses button, update the item list
                }
                break;
            case R.id.btn_sub: //sub button,the same strategy as add               
                if (tag != null && tag instanceof Integer) {
                    int position = (Integer) tag;                   
                    int num = datas.get(position).getNum();
                    if (num > 0) {
                        num--;
                        datas.get(position).setNum(num); 
                        adapter.notifyDataSetChanged();
                    }
                }
                break;
        }
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        adapter.notifyDataSetChanged();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();       
        adapter.unregisterDataSetObserver(sumObserver);
    }

    //set up listener for "sum up" 
    private View.OnClickListener listener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            boolean exist = false;//check whether the user has chosen at least one dish
            for(int i = 0; i < alldatas.size(); i ++)
            {
                for(int j = 0;j < alldatas.get(i).size(); j ++) {
                    if (alldatas.get(i).get(j).getNum() != 0) {//user has ordered at least one dish
                        exist = true;
                    }
                }
            }

            if(exist) {// transfer data to next page
                Bundle b = new Bundle();
                int count = 0;
                for (int i = 0; i < alldatas.size(); i++) {
                    for(int j = 0;j < alldatas.get(i).size(); j ++) {
                        b.putString("food_amount" + count, String.valueOf(alldatas.get(i).get(j).getNum()));
                        count++;
                    }

                }
                b.putInt("pos", pos);
                Intent intent = new Intent();
                intent.setClass(getApplicationContext(), OrderDetailActivity.class);//transfer data to OrderDetailActivity
                intent.putExtras(b);
                startActivity(intent);
            }else{
                Toast.makeText(FoodShowActivity.this, "请点单,谢谢!", Toast.LENGTH_SHORT).show();
            }
        }
    };

    /*set up adapter for shopcar*/
    private void setDialog(){
        Dialog mCameraDialog = new Dialog(this, R.style.BottomDialog);
        LinearLayout root = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.shopcar_dialog, null);
        listview_shopcar = (ListView) root.findViewById(R.id.shoppingcar_listview);
        SimpleAdapter adapter1 = new SimpleAdapter(getApplicationContext(), getData(),R.layout.shopcar_dialog_listview_content,
                new String[]{"food_name","food_price","food_amount","food_totalprice"}, new int[]{R.id.foodname,R.id.foodprice,R.id.foodamount,R.id.foodtotalprice});
        listview_shopcar.setAdapter(adapter1);

        mCameraDialog.setContentView(root);//initialize view
        Window dialogWindow = mCameraDialog.getWindow();
        dialogWindow.setGravity(Gravity.BOTTOM);
        WindowManager.LayoutParams lp = dialogWindow.getAttributes(); // get the parameters of dialog Window
        lp.x = 0; // new x position
        lp.y = 0; // new y position
        lp.width = (int) getResources().getDisplayMetrics().widthPixels; // 宽度
        root.measure(0, 10);
        lp.height = root.getMeasuredHeight();
        lp.alpha = 9f; // transparent
        dialogWindow.setAttributes(lp);
        mCameraDialog.show();
    }

    private List<Map<String,Object>> getData(){// data source of shop car
        List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
        for(int i = 0; i < alldatas.size();i++) {
            for (int j = 0; j < alldatas.get(i).size(); j++) {
                if (alldatas.get(i).get(j).getNum() != 0) {//only shows the food item with number larger than 0
                    Map map = new HashMap<String, Object>();
                    map.put("food_name", alldatas.get(i).get(j).getName());
                    map.put("food_price", alldatas.get(i).get(j).getPrice());
                    map.put("food_amount", alldatas.get(i).get(j).getNum());
                    map.put("food_totalprice", String.valueOf(alldatas.get(i).get(j).getNum() * Integer.parseInt(alldatas.get(i).get(j).getPrice())));
                    data.add(map);

                }
            }
        }
        return data;
    }
}

Database storaging

SQLiteUtil.java
Main idea: define the DB name, table name and all types of attributes(name, age, photo, ordering detail, password, recommendation, gender)

public class SQLiteUtil extends SQLiteOpenHelper {
    //define db name , table name and attributes
    private static final String DBNAME = "customer.db";
    private static final String TABLE_NAME = "customer_info";
    private static final String TABLE_INFO_COLUM_ID  = "_id";//primary key(cannot be null)
    private static final String TABLE_INFO_COLUM_NAME = "name";
    private static final String TABLE_INFO_COLUM_PWD = "pwd";
    private static final String TABLE_INFO_COLUM_REC = "rec";
    private static final String TABLE_INFO_COLUM_ORDDETAIl = "orddetail";
    private static final String TABLE_INFO_COLUM_age = "age";
    private static final String TABLE_INFO_COLUM_gender = "gender";
    private static final String TABLE_INFO_COLUM_photo = "photo";

    //constructor
    public SQLiteUtil(Context context, int version) {
        super(context, DBNAME, null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        //create table by using StringBuffer to reduce the consumption of RAM
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("CREATE TABLE IF NOT EXISTS ");
        stringBuffer.append(TABLE_NAME + "(");
        stringBuffer.append(TABLE_INFO_COLUM_ID+" integer primary key autoincrement ,");
        stringBuffer.append(TABLE_INFO_COLUM_NAME+" varchar(10),");
        stringBuffer.append(TABLE_INFO_COLUM_PWD+" varchar(10),");
        stringBuffer.append(TABLE_INFO_COLUM_REC+" varchar(100),");
        stringBuffer.append(TABLE_INFO_COLUM_ORDDETAIl+" varchar(255),");
        stringBuffer.append(TABLE_INFO_COLUM_age+" integer,");
        stringBuffer.append(TABLE_INFO_COLUM_gender+" varchar(10),");
        stringBuffer.append(TABLE_INFO_COLUM_photo+" varchar(255))");


        db.execSQL(stringBuffer.toString());
    }
    
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        String sql = "drop table if exists "+TABLE_NAME;
        db.execSQL(sql);
        onCreate(db);
    }

UserDao.java
Main idea: define how to search, update, delete, and insert Userinfo object to the database.

public class UserDao {

    private SQLiteUtil sqLiteUtil;
    public UserDao(Context context){
        sqLiteUtil = new SQLiteUtil(context,1);
    }

    //search the database
    public List search(){
        List list = new ArrayList();       
        SQLiteDatabase db = sqLiteUtil.getReadableDatabase();       
        Cursor cursor = db.rawQuery("select * from customer_info", null);
        UserInfo userInfo = null;//Database object
        while (cursor.moveToNext()){
            int id = cursor.getInt(cursor.getColumnIndex("_id"));
            String username = cursor.getString(cursor.getColumnIndex("name"));
            String pwd = cursor.getString(cursor.getColumnIndex("pwd"));
            String rec = cursor.getString(cursor.getColumnIndex("rec"));
            String orddetail = cursor.getString(cursor.getColumnIndex("orddetail"));
            int age = cursor.getInt(cursor.getColumnIndex("age"));
            String gender = cursor.getString(cursor.getColumnIndex("gender"));
            String photo = cursor.getString(cursor.getColumnIndex("photo"));
            userInfo = new UserInfo();
            userInfo.setId(id);
            userInfo.setUsername(username);
            userInfo.setPwd(pwd);
            userInfo.setRec(rec);
            userInfo.setOrddetail(orddetail);
            userInfo.setAge(age);
            userInfo.setGender(gender);
            userInfo.setPhoto(photo);
            list.add(userInfo);
        }
        cursor.close();
        db.close();
        return list;
    }

    //Insert
    public void insert(UserInfo userInfo){ 
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        //ContentValues can store the data,like Map
        ContentValues contentValues = new ContentValues();
        //generate id automatically!
        contentValues.put("name",userInfo.getUsername());
        contentValues.put("pwd",userInfo.getPwd());
        contentValues.put("rec",userInfo.getRec());
        contentValues.put("orddetail",userInfo.getOrddetail());
        contentValues.put("age",userInfo.getAge());
        contentValues.put("gender",userInfo.getGender());
        contentValues.put("photo",userInfo.getPhoto());

        //execute insertion
        db.insert("customer_info", null, contentValues);
        db.close();
    }

    //Delete
    public void del(int id){
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        db.delete("customer_info", "_id = ?", new String[]{String.valueOf(id)});

        db.close();
    }

    //Update
    public void updateRec(UserInfo userInfo){
        SQLiteDatabase db = sqLiteUtil.getWritableDatabase();
        String sql = "update customer_info set rec = ? where _id = ?";
        db.execSQL(sql,new Object[]{userInfo.getRec(),userInfo.getId()});
        db.close();
    }

Recommendation Management

MyListView.java
Main idea:Initialize the pop window, when the system detects MotionEvent.ACTION_DOWN, if the pop window is showing, dismiss it, else locate which item is clicked. When sys detects MotionEvent.ACTION_MOVE, check whether the user is swiping left to a certain distance, if true, set the “isSliding” tag to True, and show the delete button on the left-hand side.

class MyListView extends ListView {

    private static final String TAG = MyListView.class.getSimpleName();

    private int touchSlop;  //the shortest distance the user swipes the screen
    private boolean isSliding;  //check whether user slides
    private int xDown;  //pressing position
    private int yDown;  
    private int xMove;  //position when the finger moves
    private int yMove;  
    private LayoutInflater mInflater; 
    private PopupWindow mPopupWindow;   //pop up a Window for showing
    private int mPopupWindowHeight;     //the height of the popwindow
    private int mPopupWindowWidth;      //the width of the popwindow

    private TextView delete;    //when user swipes left, the delete button will show
    private DeleteClickListener mListener;  // set up listener for delete button
    private View mCurrentView;  //view of delete button
    private int mCurrentViewPos;    //the position of delete button view

    /**
     * customized listview constructor
     */
    public MyListView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mInflater = LayoutInflater.from(context);   
        touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  
        View view = mInflater.inflate(R.layout.delete_button, null);   //find the layout of delete button
        delete = (TextView) view.findViewById(R.id.delete)

        mPopupWindow = new PopupWindow(view, LinearLayout.LayoutParams. WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);    //create a popupWindow

        mPopupWindow.getContentView().measure(0, 0);    //initialize
        mPopupWindowHeight = mPopupWindow.getContentView().getMeasuredHeight(); //get the height of the popupwindow
        mPopupWindowWidth = mPopupWindow.getContentView().getMeasuredWidth();  
    }

    /**
     * dispatchTouchEvent
     */
    @Override public boolean dispatchTouchEvent(MotionEvent ev) {

        int action = ev.getAction();
        int x = (int) ev.getX();// the position the user touches
        int y = (int) ev.getY();

        switch (action) {
            case MotionEvent.ACTION_DOWN:   //0 action_down dismiss
                xDown = x;
                yDown = y;
                if (mPopupWindow.isShowing()) {// if the popup window shows, dismiss it
                    dismissPopWindow();
                    return false;
                }
                //else get the current touching position
                mCurrentViewPos = pointToPosition(xDown, yDown);   
                View view = getChildAt(mCurrentViewPos - getFirstVisiblePosition());//get the item the user presses
                mCurrentView = view;

                break;

            case MotionEvent.ACTION_MOVE:   //2 move
                xMove = x;
                yMove = y;
                int dx = xMove - xDown;
                int dy = yMove - yDown;

                if (xMove < xDown && Math.abs(dx) > touchSlop && Math.abs(dy) < touchSlop) { //check whether the finger swipes left to a certain distance(>touchslop), it so ,pop up window
                    isSliding = true;   
                }
                break;
        }

        return super.dispatchTouchEvent(ev);

    }


    @Override public boolean onTouchEvent(MotionEvent ev) {

        if (mCurrentView == null) { // if the view doesn't exist ,return false
            return false;
        }

        int action = ev.getAction();

        if (isSliding) {
            switch (action) {
                case MotionEvent.ACTION_MOVE:
                    int[] location = new int[2];
                    mCurrentView.getLocationOnScreen(location);
                    mPopupWindow.update();

                    delete.setHeight(getMeasuredHeight()/getChildCount());//calculate the height of each delete button
                    
                    int x = location[0] + mCurrentView.getWidth();
                    int y = location[1] + mCurrentView.getHeight() / 2 - mPopupWindowHeight;

                    mPopupWindow.showAtLocation(mCurrentView, Gravity.LEFT | Gravity.TOP, x, y);     


                    delete.setOnClickListener(new OnClickListener() {
                        @Override public void onClick(View view) {
                            if (mListener != null) {
                                mListener.onClickDelete(mCurrentViewPos);
                                mPopupWindow.dismiss();
                            }
                        }
                    });

                    break;

                case MotionEvent.ACTION_UP:
                    isSliding = false;
                    break;
            }


            return true;
        }
        return super.onTouchEvent(ev);
    }

    private void dismissPopWindow() {
        if (mPopupWindow != null && mPopupWindow.isShowing()) {
            mPopupWindow.dismiss();
        }
    }
    public void setDelButtonClickListener(DeleteClickListener listener) {
        mListener = listener;
    }

Reference: http://www.zhanghongyang.com

PersonalTrendsManageActivity.java
Main idea: Set up an adapter for listview, when the user deletes the item, update the remark attribute in the database, at the same time, the remark listview contents will also be updated.

public class PersonalTrendsManageActivity extends Activity {
    SimpleAdapter simpleAdapter = null;
    private MyListView mListView;
    List<Map<String, Object>> lists = new ArrayList<Map<String, Object>>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.personal_trend_manage_listview);

        mListView = (MyListView) findViewById(R.id.table);

        simpleAdapter = new SimpleAdapter(getApplicationContext(), getData(), R.layout.personal_trend_manage_listview_content, new String[]{"Rec"}, new int[]{R.id.user_recommend});

        mListView.setAdapter(simpleAdapter);
        mListView.setSelector(new ColorDrawable(Color.LTGRAY));

        mListView.setDelButtonClickListener(new DeleteClickListener() {

            @Override
            public void onClickDelete(int position) {
                lists.remove(position);//remove the item
                simpleAdapter.notifyDataSetChanged();
                UserDao userDao = new UserDao(getApplicationContext());
                FileIO io = new FileIO(getApplicationContext());
                String username = io.load("CurrentUser");//get the current user name
                List<UserInfo> list = userDao.search();//search all the users
                UserInfo user;
                for (int i = 0; i < list.size(); i++) {
                    user = (UserInfo) list.get(i);
                    //update the recommendation
                    if (user.getUsername().equals(username)) {
                        String[] allrecs = user.getRec().split(";");   
                        ArrayList<String> all = new ArrayList<>();
                        for (int j = 0; j < allrecs.length; j++) {
                            all.add(allrecs[j]);
                        }
                        all.remove(position);
                        String newstr = "";

                        for (int j = 0; j < all.size(); j++) {
                            newstr += all.get(j) + ";";
                        }
                        user.setRec(newstr);
                        userDao.updateRec(user);//update the recommendation
                    }
                }

            }
        });

        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            }
        });
    }

    private List<Map<String, Object>> getData() {//adapter data source (show the remarks in detail )

        FileIO io = new FileIO(getApplicationContext());
        Map<String, Object> map = null;

        UserDao userDao = new UserDao(getApplicationContext());
        List<UserInfo> userInfolist = userDao.search();
        String username = io.load("CurrentUser");


            for (int i = 0; i < userInfolist.size(); i++) {
               if(userInfolist.get(i).getRec()!=null){
                if (userInfolist.get(i).getUsername().equals(username)&&!userInfolist.get(i).getRec().equals("")) {
                    String[] checkRec = userInfolist.get(i).getRec().split(";");
                    if (checkRec.length > 0) {
                        for (int j = 0; j < checkRec.length; j++) {
                            String[] str = checkRec[j].split("#");
                            if(str.length!= 0) {
                                map = new HashMap<String, Object>();
                                map.put("Rec", "于 " + str[1] + " 评价:" + j + ":" + str[0]);
                                lists.add(map);
                            }
                        }
                    }
                }
               }
            }

            if(lists.size() == 0) {
                map = new HashMap<String, Object>();
                map.put("Rec", "暂未作出任何评价");
                lists.add(map);
            }


        return lists;
    }
}

Image choosing and showing

PersonalInfEditActivity.java
Main idea: open the album, parse the uri (or reconstruct URI) and get the real storage path of the photo, and show the photo in imageview

public class PersonalInfEditActivity extends Activity {

    private ImageView photo;
    private ImageView submit;
    private EditText age;
    private TextView name;
    private EditText sex;
    String imagePath = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_frag_personal_inf_edit);
        photo=(ImageView)findViewById(R.id.image) ;
        submit=(ImageView)findViewById(R.id.submit) ;
        age = (EditText)findViewById(R.id.age);
        name = (TextView)findViewById(R.id.name);
        sex = (EditText)findViewById(R.id.gender);

        initView();

        submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                FileIO io = new FileIO(getApplicationContext());
                String username = io.load("CurrentUser");//current user name
                UserDao userDao = new UserDao(getBaseContext());
                List<UserInfo> userlist = userDao.search();
                name.setText(username);
                UserInfo user;
                if(userlist.size() > 0) {
                    for (int i = 0; i < userlist.size(); i++) {
                        user = (UserInfo) userlist.get(i);
                        if (user.getUsername().equals(username)) {

                            if(!age.getText().equals("")&& !sex.getText().equals("") && imagePath!=null) {
                                user.setAge(Integer.parseInt(age.getText().toString()));
                                userDao.updateAge(user);

                                user.setGender(sex.getText().toString());
                                userDao.updateGender(user);

                                user.setPhoto(imagePath);
                                userDao.updatephoto(user);

                                Intent intent = new Intent();
                                intent.setClass(getApplicationContext(), MainActivity.class);
                                startActivity(intent);

                            }
                            else
                            {
                                Toast.makeText(PersonalInfEditActivity.this, "请输入完整信息后提交!", Toast.LENGTH_SHORT).show();
                            }

                        }
                    }
                }

            }
        });


    }


    private void initView() {
        ImageView pick = (ImageView) findViewById(R.id.button2);
        pick.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openAlbum();
            }
        });
    }

    /**
     * open the album
     */
    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent, 2);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case 2:
                    //the different methods to cope with different API version
                    if (Build.VERSION.SDK_INT >= 19) {
                        handleImageOnKitKat(data);
                    } else {
                        handleImageBeforeOnKitKat(data);
                    }
                    break;
            }
        }
    }
    
    //parse the uri and get the real storage path of photo, and show the photo in imageview when API >= 19
    private void handleImageOnKitKat(Intent data) {
     /*If the uri is of the document type, the documentID of the uri is taken out. If it is not, the normal method is used to handle it. If the Authority of the uri is of the media type, you need to split the id to take out the real id value and reconstruct the uri*/
        Uri uri = data.getData();
        if (DocumentsContract.isDocumentUri(this, uri)) {

            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {

                String id = docId.split(":")[1];
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {

                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),
                        Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equals(uri.getScheme())) {
            imagePath = getImagePath(uri, null);
        } else if ("file".equals(uri.getScheme())) {
            imagePath = uri.getPath();
        }

        displayImage(imagePath);
    }

    //method to display image
    private void displayImage(String imagePath) {
        if (!TextUtils.isEmpty(imagePath)) {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            int w,h;
            w = bitmap.getWidth();
            h = bitmap.getHeight();
            Bitmap scale = Bitmap.createScaledBitmap(bitmap,500,500*h/w,false);
            photo.setImageBitmap(scale);
        } else {
            Toast.makeText(this, "cannot find the path of the photo", Toast.LENGTH_SHORT).show();
        }
    }

    /*
     * invest the real storage path of the photo from provider according to uri and selection
     */
    private String getImagePath(Uri uri, String selection) {
        String path = null;
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }

        return path;
    }

    // Method to get image path and display when API<19
    private void handleImageBeforeOnKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
    }
}

Reference: https://blog.csdn.net/wuhun_166/article/details/80000521

About Tests

I mainly do some manual tests in this project. Sometimes the screen shows “unfortunately the app closed” and exits from the app directly. According to the running record, I notice that NULL object error occurs frequently, so I have monitored the operation related to insertion, deletion, and update of data. In this condition, I could fix the problem after I check the format of data in the database in detail.

Future Improvements

Store the data to the cloud database rather than the local database.
Create a restaurant website to manage the preorder bill.
More types of food can be stored, JSON can be introduced.

Conclusion

This app helps customers reserve the table, pre-order dishes and tell the restaurant the exact time they may arrive, which means the restaurant can prepare the dishes and table in advance and customers don’t need to wait for a long time after they arrive at the restaurant. In this project, initially, the UI interface is a bit simple, so I re-design all the pages and try to store the customer data in the local database, which helps me obtain the needed data conveniently. The app features can be viewed in this blog. I think more improvements could be made in the future,. For example, a cloud database can be used to store a large amount of customer information. I will keep learning the knowledge of android and make this project more perfect. Thanks for reading!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值