Aqua Reminder

A brief introduction to

This is a big assignment for our human-computer interaction course. The task is to design a simple APP that meets the goal of human-computer interaction. We have designed a water Reminder app – Aqua Reminder, which is modeled after the Lemon water app. The function of daily drinking water display, drinking water added, drinking water reminder, planting trees, user ranking, etc. It took me a long time to learn some knowledge about Android, and I will introduce some knowledge used in the app below.

Function is introduced

  • Daily water consumption shows:

    • The cup will display the amount of water consumed today
    • The water in the glass should not exceed 1500ml
  • Drink water to add:

    • After drinking water, you can add the amount of water you drink
    • The amount of water you drink will be renewed throughout the day
  • Drink water reminder:

    • Timer alert: The alarm clock will alert at the specified time
    • Interval alert: The alarm will be set to alert every hour
  • Planting trees:

    • Users can exchange tree seeds in the planting interface
    • The tree can be viewed in the planted tree after exchange
  • User ranking:

    • The app will rank all users according to how much energy they have


Main Page Display

Login interface:

Water interface:

Interface for adding drinking water:

Reminder setting interface:

Planting tree interface:

Select the tree interface:

Planted interface:

User Interface:

User ranking interface:



Technology introduction

  • The dividing line at the top and bottom of the ListView

    ListView lv; lv.addHeaderView(new View(this)); // Add top splitter lv. AddFooterView (new View(this)); // Add a bottom dividerCopy the code
  • Return to the previous level:

    Activity.this.finish();
    Copy the code
  • Dialog:

    AlertDialog alert = null; AlertDialog.Builder builder = null; alert = null; builder = new AlertDialog.Builder(Activity.this); // Title + message + button alert = builder.setTitle("...") ).setMessage("..." ).setNegativeButton("..." , new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }).create(); alert.show();Copy the code
  • Alarm clock reminder:

    Android Official Documentation

  • Bottom navigation bar:

    Novice tutorial

  • Dynamic change of water volume in cup:

    The Histogram classes:

    public class Histogram extends View { int MAX = 1800; Int corner = 0; // Rectangle Angle, set to 0, no Angle. double data = 0; Double tempData = 0; Int textPadding = 0; Paint mPaint; int mColor; Context mContext; Public Histogram(Context Context) {super(Context); mContext = context; } public Histogram(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mContext = context; initPaint(); } public Histogram(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; initPaint(); } // Paint method private void initPaint() {mPaint = new Paint(); mPaint.setAntiAlias(true); mColor = mContext.getResources().getColor(R.color.water); mPaint.setColor(mColor); } @Override public void draw(Canvas canvas) { super.draw(canvas); If (data == 0.0) {mPaint. SetTextSize (getWidth() / 2); RectF oval3 = new RectF(0, getHeight() - DensityUtils.pxTodip(mContext, 20), getWidth(), getHeight()); DrawRoundRect (oval3, densityutils.pxtodip (mContext, corner), densityutils.pxtodip (mContext, corner), mPaint); Canvas. DrawText ("", getWidth() * 0.1f - mPaint. MeasureText ("0") * 0.1f, getHeight() - denSityutils.pxtodip (mContext, 20) - 2 * DensityUtils.pxTodip(mContext, textPadding), mPaint); return; Int step = (int) (data / 100 + 1.0); if (tempData < data - step) { tempData = tempData + step; } else { tempData = data; } // Draw a rounded rectangle String S = tempData + ""; // If you need to add % after the number, add % in "" // set the font displayed // Typeface Typeface = Typeface.createFromAsset(getContext().getAssets(),"digital-7.ttf"); // mPaint.setTypeface(typeface); If (s.length () < 4) {mPaint. SetTextSize (getWidth() / 2); } else { mPaint.setTextSize(50); Ascent () + mPaint. Descent (); // Float textH = mPaint. Ascent () + mPaint. float MaxH = getHeight() - textH - 2 * DensityUtils.pxTodip(mContext, textPadding); RealH = (float) (MaxH/MAX * tempData); float realH = (float) (MaxH/MAX * tempData); RectF oval3 = new RectF(0, getHeight() - realH, getWidth(), getHeight()); DrawRoundRect (oval3, densityutils.pxtodip (mContext, corner), densityutils.pxtodip (mContext, corner), mPaint); DrawText (S, getWidth() * 0.5f - mPaint. MeasureText (S) * 0.5f, getHeight() - realH - 2 * DensityUtils.pxTodip(mContext, textPadding), mPaint); if (tempData ! = data) { postInvalidate(); } } public void setData(double tempData, double data, int MAX) { this.tempData = tempData; this.data = data; this.MAX = MAX; postInvalidate(); }}Copy the code

    An Activity or Fragment:

    private Histogram histogram;
    ​
    histogram.setData(tempWater, water, MAX_WATER);
    Copy the code

    Don’t forget to define a Histogram control on your page

  • SwitchCompat switch:

    The name of the class: androidx appcompat. Widget. SwitchCompat


Existing problems

App uses BroadcastReceiver to listen for date changes, but there has been an error in updating data in the database caused by repeated calls of onReceive method. This problem has not been solved yet. If there is a solution, welcome comments or private messages.

The code is as follows:

dateChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_DATE_CHANGED) && broadcastFlag) { broadcastFlag = false; updateUserInfo(); flag = true; } else { broadcastFlag = true; }}}; IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_DATE_CHANGED); registerReceiver(dateChangeReceiver, intentFilter);Copy the code


The project address

Gitee address

Making the address