Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 17

1. FragmentMain.

java
package com.example.final_project.hike;

import android.content.DialogInterface;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.final_project.Constants;
import com.example.final_project.R;
import com.example.final_project.databinding.FragmentMainBinding;

public class FragmentMain extends Fragment implements


HikeListAdapter.ListHikeListener {
private FragmentMainBinding binding;
private HikeListAdapter adapter;
HikeDAO dao;
SearchView searchView;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable
ViewGroup container,
@Nullable Bundle savedInstanceState) {
// Init the menu bar
AppCompatActivity app = (AppCompatActivity) getActivity();
ActionBar ab = app.getSupportActionBar();
ab.setHomeButtonEnabled(false);
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayHomeAsUpEnabled(false);
setHasOptionsMenu(true);

// Binding
binding = FragmentMainBinding.inflate(inflater, container, false);

// Init the DAO class to get the data


dao = new HikeDAO(getContext());
dao.hikeList.setValue(dao.getAllHike());
TextView empty1 = binding.empty1;
TextView empty2 = binding.empty2;

// Creating the recycler view


RecyclerView rv = binding.recyclerView;
rv.setHasFixedSize(true);//each row has equal size regardless of its
content
rv.addItemDecoration(new DividerItemDecoration(
getContext(),
(new LinearLayoutManager(getContext())).getOrientation())
);

// Observe the change of list item for the recycler view


dao.hikeList.observe(
getViewLifecycleOwner(),
hikeList -> {
adapter = new HikeListAdapter(hikeList, this);
binding.recyclerView.setAdapter(adapter);
binding.recyclerView.setLayoutManager(new
LinearLayoutManager(getActivity()));
if (hikeList.size() == 0) {
empty1.setVisibility(View.VISIBLE);
empty2.setVisibility(View.VISIBLE);
rv.setVisibility(View.GONE);
} else {
empty1.setVisibility(View.GONE);
empty2.setVisibility(View.GONE);
rv.setVisibility(View.VISIBLE);
}
}
);

// Set listener for the adding button


binding.fabAddHike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("id", Constants.NEW_HIKE_ID);
bundle.putString("name", Constants.EMPTY_STRING);
bundle.putString("location", Constants.EMPTY_STRING);
bundle.putString("date", Constants.EMPTY_STRING);
bundle.putString("parking_available", Constants.EMPTY_STRING);
bundle.putString("length", Constants.EMPTY_STRING);
bundle.putString("difficulty", Constants.EMPTY_STRING);
bundle.putString("description", Constants.EMPTY_STRING);

// Navigate to the edit form

Navigation.findNavController(getView()).navigate(R.id.fragmentEdit, bundle);
}
});
return binding.getRoot();
}

@Override
public void onResume() {
super.onResume();
Log.i(this.getClass().getName(), "On Resume");
dao.getAllHike();
}
@Override
public void onItemClick(HikeEntity hikeInput) {

// Get the specific ID of the hike by the click listener


HikeEntity hike = dao.getByID(hikeInput.getId());

Bundle bundle = new Bundle();


bundle.putString("id", hike.getId());
bundle.putString("name", hike.getName());
bundle.putString("location", hike.getLocation());
bundle.putString("date", hike.getDate());
bundle.putString("parking_available", hike.getParkingAvailable());
bundle.putString("length", hike.getLength());
bundle.putString("difficulty", hike.getDifficulty());
bundle.putString("description", hike.getDescription());

Navigation.findNavController(getView()).navigate(R.id.fragmentEdit, bundle);
}

// Initialize the listener for the search menu


@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater
inflater) {
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
searchView = (SearchView)
menu.findItem(R.id.action_search).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener()
{
@Override
public boolean onQueryTextSubmit(String query) {
dao.searchHike(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
dao.searchHike(newText);
return false;
}
});
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();

if (id == R.id.action_delete_all) {
// Handle the delete all action
deleteAllData();
return true;
}
return super.onOptionsItemSelected(item);
}
private void deleteAllData() {
AlertDialog.Builder builder = new
AlertDialog.Builder(requireContext());
builder.setTitle("Confirm Deletion");
builder.setMessage("Are you sure you want to delete all data?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
// User clicked Yes, delete all data
dao.deleteAllHikes();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
// User clicked No, do nothing
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
}
The main task of the FragmentMain.java file is to display a list of hikes, add new hikes to the list,
allow editing or viewing hike details, search and delete. All information about the hike.
// Init the menu bar
AppCompatActivity app = (AppCompatActivity) getActivity();
ActionBar ab = app.getSupportActionBar();
ab.setHomeButtonEnabled(false);
ab.setDisplayShowHomeEnabled(false);
ab.setDisplayHomeAsUpEnabled(false);
setHasOptionsMenu(true);
This block of code is used by the author to adjust and tweak the fragment's title bar, including
hiding or disabling certain elements of the ActionBar.

binding = FragmentMainBinding.inflate(inflater, container, false);

// Init the DAO class to get the data


dao = new HikeDAO(getContext());
dao.hikeList.setValue(dao.getAllHike());

TextView empty1 = binding.empty1;


TextView empty2 = binding.empty2;

// Creating the recycler view


RecyclerView rv = binding.recyclerView;
rv.setHasFixedSize(true);//each row has equal size regardless of its content
rv.addItemDecoration(new DividerItemDecoration(
getContext(),
(new LinearLayoutManager(getContext())).getOrientation())
);
This code block initializes important components in the user interface including: binding, object
dao to access hike data, TextView to display a blank message and RecyclerView to display the
hike list
// Observe the change of list item for the recycler view
dao.hikeList.observe(
getViewLifecycleOwner(),
hikeList -> {
adapter = new HikeListAdapter(hikeList, this);
binding.recyclerView.setAdapter(adapter);
binding.recyclerView.setLayoutManager(new
LinearLayoutManager(getActivity()));
if (hikeList.size() == 0) {
empty1.setVisibility(View.VISIBLE);
empty2.setVisibility(View.VISIBLE);
rv.setVisibility(View.GONE);
} else {
empty1.setVisibility(View.GONE);
empty2.setVisibility(View.GONE);
rv.setVisibility(View.VISIBLE);
}
}
);
In this code, the author uses the observe method of LiveData to monitor changes in the hike list
(dao.hikeList). When the list changes, the lambda function hikeList -> { ... } is called to handle
the changes and update the interface. This block of code ensures the RecyclerView is updated
every time the hike list changes and adjusts the display of the UI based on the list state (empty
or not empty).
binding.fabAddHike.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bundle bundle = new Bundle();
bundle.putString("id", Constants.NEW_HIKE_ID);
bundle.putString("name", Constants.EMPTY_STRING);
bundle.putString("location", Constants.EMPTY_STRING);
bundle.putString("date", Constants.EMPTY_STRING);
bundle.putString("parking_available", Constants.EMPTY_STRING);
bundle.putString("length", Constants.EMPTY_STRING);
bundle.putString("difficulty", Constants.EMPTY_STRING);
bundle.putString("description", Constants.EMPTY_STRING);

// Navigate to the edit form


Navigation.findNavController(getView()).navigate(R.id.fragmentEdit,
bundle);
}
});
In this code, the author will handle the event when the user clicks the button (fabAddHike).
When the button (fabAddHike) is clicked, public void Onclick(View v) is called. The author will
then create a Bundle object to contain the data transferred to the new fragment. Next, the
author sets the id value in the Package to a special value to identify that this is a new hike and
no ID has been assigned yet, and sets the other values in the Package to the empty string.
Finally, the author uses the Navigation Component to redirect to the FragmentEdit along with
the data in the Bundle.
@Override
public void onItemClick(HikeEntity hikeInput) {

// Get the specific ID of the hike by the click listener


HikeEntity hike = dao.getByID(hikeInput.getId());

Bundle bundle = new Bundle();


bundle.putString("id", hike.getId());
bundle.putString("name", hike.getName());
bundle.putString("location", hike.getLocation());
bundle.putString("date", hike.getDate());
bundle.putString("parking_available", hike.getParkingAvailable());
bundle.putString("length", hike.getLength());
bundle.putString("difficulty", hike.getDifficulty());
bundle.putString("description", hike.getDescription());

Navigation.findNavController(getView()).navigate(R.id.fragmentEdit, bundle);
}
The above code is used when a hike is clicked. onItemClick(HikeEntity hikeInput) this method
takes a HikeEntity object as an argument representing the pressed data, which will then use the
dao object to get information about the ride based on the pressed ID. The author uses Bundle
to package and transfer data between Fragments. Finally, it will redirect to fragmentEdit and
pass along the data in the bundle used to edit information about the hike.
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater
inflater) {
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
searchView = (SearchView)
menu.findItem(R.id.action_search).getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
dao.searchHike(query);
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
dao.searchHike(newText);
return false;
}
});
}

This code is an overridden method from the interface class that is responsible for initializing the
menu bar for searching. This line of code inflater.inflate(R.menu.menu_main, menu) uses
inflater to add menu items from the memu_main.xml file
searchView = (SearchView)menu.findItem(R.id.action_search).getActionView() this line searches
for the menu item with ID action_search and gets its ActionView object then converts it to a
SearchView object to enter and search data Whether.
onQueryTextSubmit(String query) This method is called when the user presses the search
button
onQueryTextChange(String newText) this method is called when the text in the SearchView
changes
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
int id = item.getItemId();

if (id == R.id.action_delete_all) {
// Handle the delete all action
deleteAllData();
return true;
}
return super.onOptionsItemSelected(item);
}
private void deleteAllData() {
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
builder.setTitle("Confirm Deletion");
builder.setMessage("Are you sure you want to delete all data?");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// User clicked Yes, delete all data
dao.deleteAllHikes();
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// User clicked No, do nothing
dialog.dismiss();
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
The above code handles the event when the user selects the delete icon on the application bar.
After selecting the deletion icon, there will be a confirmation dialog box to delete all data and
hikes. The code line int id = item.getItemID() will get the ID of the hikes to be deleted., then that
will check if the selected item is action_delete_all or not. If correct, all data will be deleted.
2. FragmentEdit.java
package com.example.final_project.hike;

import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.navigation.Navigation;

import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Switch;

import com.example.final_project.Constants;
import com.example.final_project.DateHandling;
import com.example.final_project.R;
import com.example.final_project.databinding.FragmentEditBinding;

import java.util.Calendar;

public class FragmentEdit extends Fragment {


private Switch aSwitch;
private FragmentEditBinding binding;
private DatePickerDialog datePickerDialog;
EditText editTextDate;
HikeDAO dao;
boolean riskCheck;
SharedPreferences sharedPreferences;

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable
ViewGroup container,
@Nullable Bundle savedInstanceState){
AppCompatActivity app = (AppCompatActivity)getActivity();
ActionBar ab = app.getSupportActionBar();
ab.setHomeButtonEnabled(true);
ab.setDisplayShowHomeEnabled(true);
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeAsUpIndicator(R.drawable.baseline_save_24);
setHasOptionsMenu(true);

binding = FragmentEditBinding.inflate(inflater, container, false);

//Calling the DAO


dao = new HikeDAO(getContext());
//Calling the DAO and get the observation by ID sent from
MainFragment and it returns the observation
String idReceived = getArguments().getString("id");
Bundle bundleReceived = getArguments();

//Set condition for the update


if(idReceived != Constants.NEW_HIKE_ID){
dao.hike.setValue(dao.getByID(idReceived));
}

//Observing the changes and set text for the editor view from the
bundle sent from main
dao.hike.observe(
getViewLifecycleOwner(),
hike ->{

binding.editNameHike.setText(bundleReceived.getString("name"));

binding.editLocation.setText(bundleReceived.getString("location"));

binding.editDateHike.setText(bundleReceived.getString("date"));

binding.selectParking.setText(bundleReceived.getString("parking_available"));

binding.editLengthOfHike.setText(bundleReceived.getString("length"));

binding.editDifficulty.setText(bundleReceived.getString("difficulty"));

binding.editDescription.setText(bundleReceived.getString("description"));
requireActivity().invalidateOptionsMenu();
}
);

binding.selectParking.setInputType(InputType.TYPE_NULL);
aSwitch = binding.switchParking;
sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(getContext());
aSwitch.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean
isChecked) {
if (isChecked) {
binding.selectParking.setText("Parking available");
} else {
binding.selectParking.setText("No parking available");
}
saveSwitchState(isChecked);
}
});
riskCheck = sharedPreferences.getBoolean("Notification", true);
aSwitch.setChecked(riskCheck);

//DatePicker
editTextDate = binding.editDateHike;
editTextDate.setInputType(InputType.TYPE_NULL);
editTextDate.setText(DateHandling.getTodayDate());
editTextDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initDatePicker();
showDateDialog();
}
});
return binding.getRoot();
}

@Override
public void onPrepareOptionsMenu(@NonNull Menu menu) {
super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (this.validate()) return saveAndReturn();
else return false;
} else if (item.getItemId() == R.id.action_delete) {
return deleteAndReturn();
} else if (item.getItemId() == R.id.observationsDetail) {
return toObservation();
} else {
return super.onOptionsItemSelected(item);
}
}
private boolean toObservation() {
Bundle bundleReceived = getArguments();

Navigation.findNavController(getView()).navigate(R.id.fragmentObservationMain,
bundleReceived);
return true;
}

private boolean validate() {


EditText name = binding.editNameHike;
EditText location = binding.editLocation;
EditText date = binding.editDateHike;
EditText parking= binding.selectParking;
EditText length = binding.editLengthOfHike;
EditText difficutly = binding.editDifficulty;
boolean isValidated = true;

if (name.getText().toString().equals(Constants.EMPTY_STRING)){
name.setError("Name of the hike is required");
isValidated = false;
}
if (location.getText().toString().equals(Constants.EMPTY_STRING)){
location.setError("Location of the hike is required");
isValidated = false;
}
if (date.getText().toString().equals(Constants.EMPTY_STRING)){
date.setError("Date of the hike is required");
isValidated = false;
}
if (difficutly.getText().toString().equals(Constants.EMPTY_STRING)){
difficutly.setError("Difficutly of the hike is required");
isValidated = false;
}
if (length.getText().toString().equals(Constants.EMPTY_STRING)){
length.setError("Length of the hike is required");
isValidated = false;
}
if (parking.getText().toString().equals(Constants.EMPTY_STRING)){
parking.setError("Please fill in the parking available or we will
assume that you do not need any parking");
binding.selectParking.setText("No parking available");
isValidated = false;
}
return isValidated;
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater
inflater) {
if(getArguments().getString("id") != Constants.NEW_HIKE_ID){
inflater.inflate(R.menu.menu_hike, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
private boolean saveAndReturn() {
Log.i(this.getClass().getName(), "Saved and return");

HikeEntity hike = new HikeEntity();

hike.setName(binding.editNameHike.getText().toString());
hike.setLocation(binding.editLocation.getText().toString());
hike.setDate(binding.editDateHike.getText().toString());
hike.setParkingAvailable(binding.selectParking.getText().toString());
hike.setLength(binding.editLengthOfHike.getText().toString());
hike.setDifficulty(binding.editDifficulty.getText().toString());
hike.setDescription(binding.editDescription.getText().toString());

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());


builder.setTitle("Information of this hike:");
builder.setMessage("Name of the hike: " +
binding.editNameHike.getText().toString() + "\n" +
"Location: " + binding.editLocation.getText().toString() + "\
n" +
"Date Hike: " + binding.editDateHike.getText().toString() + "\
n" +
"Parking available: " +
binding.selectParking.getText().toString() + "\n" +
"Length: " + binding.editLengthOfHike.getText().toString() +
"\n" +
"Difficulty: " + binding.editDifficulty.getText().toString() +
"\n" +
"Description: " + binding.editDescription.getText().toString()
+ "\n" );
builder.setPositiveButton("Save", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (getArguments().getString("id") != "0"){
hike.setId(getArguments().getString("id"));
dao.updateHike(hike);
}
else{
dao.insertHike(hike);
}
dialog.dismiss();
Navigation.findNavController(getView()).navigateUp();
}
});
builder.setNegativeButton("Back", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
return true;
}
private boolean deleteAndReturn() {
Log.i(this.getClass().getName(), "Delete and return");

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());


builder.setTitle("Delete this hike");
builder.setMessage("This hike will be permanently deleted ");
builder.setPositiveButton("Yes", new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
dao.deleteHike(dao.hike.getValue().getId());
Navigation.findNavController(getView()).navigateUp();
}
});
builder.setNegativeButton("Back", new
DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
return true;
}

private void initDatePicker() {


DatePickerDialog.OnDateSetListener dateSetListener = new
DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int month, int
dayOfMonth) {
month = month+1;
String date = DateHandling.makeDateString(dayOfMonth, month,
year);
binding.editDateHike.setText(date);
}
};

Calendar cal = Calendar.getInstance();


int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int style = AlertDialog.THEME_HOLO_LIGHT;

datePickerDialog = new DatePickerDialog(requireActivity(),


style,dateSetListener, year, month, day);
}

private void showDateDialog() {


datePickerDialog.show();
}
private void saveSwitchState(boolean isChecked) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putBoolean("Notification", isChecked);
editor.apply();
}
}
The main function of this code file is to edit and update information about the hiking trip, using
components such as Switch, DatePickerDialong and SharedPreferences to save and display data
private Switch aSwitch;
private FragmentEditBinding binding;
private DatePickerDialog datePickerDialog;
EditText editTextDate;
HikeDAO dao;
boolean riskCheck;
SharedPreferences sharedPreferences;
The author uses the variables aSwitch, binding, datePickerDialog, editTextDate, dao, riskCheck
and sharedPreferences. The variable aSwitch is used to select between "Parking available" and
"No parking available". The FragmentEditBinding object is created to connect and use interface
components in Fragments. The datePickerDiaLog variable is used to select the date for the hike,
the editTextDate variable to display and input the date field, dao are used to database access.
The riskCheck variable is used to store the on/off status for the Parking available feature of the
trip. sharedPreference stops to save the Switch's state between application starts to help
maintain user state information.
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup
container,
@Nullable Bundle savedInstanceState){
AppCompatActivity app = (AppCompatActivity)getActivity();
ActionBar ab = app.getSupportActionBar();
ab.setHomeButtonEnabled(true);
ab.setDisplayShowHomeEnabled(true);
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeAsUpIndicator(R.drawable.baseline_save_24);
setHasOptionsMenu(true);

binding = FragmentEditBinding.inflate(inflater, container, false);


//Calling the DAO
dao = new HikeDAO(getContext());

//Calling the DAO and get the observation by ID sent from MainFragment
and it returns the observation
String idReceived = getArguments().getString("id");
Bundle bundleReceived = getArguments();

//Set condition for the update


if(idReceived != Constants.NEW_HIKE_ID){
dao.hike.setValue(dao.getByID(idReceived));
}

//Observing the changes and set text for the editor view from the bundle
sent from main
dao.hike.observe(
getViewLifecycleOwner(),
hike ->{

binding.editNameHike.setText(bundleReceived.getString("name"));

binding.editLocation.setText(bundleReceived.getString("location"));

binding.editDateHike.setText(bundleReceived.getString("date"));

binding.selectParking.setText(bundleReceived.getString("parking_available"));

binding.editLengthOfHike.setText(bundleReceived.getString("length"));

binding.editDifficulty.setText(bundleReceived.getString("difficulty"));

binding.editDescription.setText(bundleReceived.getString("description"));
requireActivity().invalidateOptionsMenu();
}
);

binding.selectParking.setInputType(InputType.TYPE_NULL);
aSwitch = binding.switchParking;
sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(getContext());
aSwitch.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean
isChecked) {
if (isChecked) {
binding.selectParking.setText("Parking available");
} else {
binding.selectParking.setText("No parking available");
}
saveSwitchState(isChecked);
}
});
riskCheck = sharedPreferences.getBoolean("Notification", true);
aSwitch.setChecked(riskCheck);
//DatePicker
editTextDate = binding.editDateHike;
editTextDate.setInputType(InputType.TYPE_NULL);
editTextDate.setText(DateHandling.getTodayDate());
editTextDate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initDatePicker();
showDateDialog();
}
});
return binding.getRoot();
}

First, the author will set up AppCompatActvity's ActionBar to display the Save function button,
then trigger the event to show the options menu in the ActionBar with
setHasOptionMenu(true). Next, the author uses FragmentEditBinding to connect the interface
components and create a HikeDAO object to perform database access operations. The author
will get the ID of the hike from the Bundle argument and check if it is not a new hike then use
DAO to get the details and update the value of dao.hike.
The author will set up listener events for the Switch to update the status and display the
corresponding text. Use SharedPreferences to save the Switch's state.
Finally the author sets the default editTextDate field to display the current date and when
entered will open the date picker dialog box and then return the binding.getRoot() of the
initialized UI.
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
if (this.validate()) return saveAndReturn();
else return false;
} else if (item.getItemId() == R.id.action_delete) {
return deleteAndReturn();
} else if (item.getItemId() == R.id.observationsDetail) {
return toObservation();
} else {
return super.onOptionsItemSelected(item);
}
}
The above code will handle the event when an item in the options menu is selected. If the user
clicks on the Save icon, it will save and exit. Pressing the action_delete item will delete the
hiking and exit the Fragment. If the user presses the observationsDetail item, it will redirect to
another Fragment to view the observations of the hike and if not in the above cases, the
system's default handling will be performed.
private boolean toObservation() {
Bundle bundleReceived = getArguments();
Navigation.findNavController(getView()).navigate(R.id.fragmentObservationMain,
bundleReceived);
return true;
}
The toObservation method is used to redirect to fragmentObservationMain and pass along the
data (Bundle) received from the current Fragment's argument. After redirection, the method
returns true.
private boolean validate() {
EditText name = binding.editNameHike;
EditText location = binding.editLocation;
EditText date = binding.editDateHike;
EditText parking= binding.selectParking;
EditText length = binding.editLengthOfHike;
EditText difficutly = binding.editDifficulty;
boolean isValidated = true;

if (name.getText().toString().equals(Constants.EMPTY_STRING)){
name.setError("Name of the hike is required");
isValidated = false;
}
if (location.getText().toString().equals(Constants.EMPTY_STRING)){
location.setError("Location of the hike is required");
isValidated = false;
}
if (date.getText().toString().equals(Constants.EMPTY_STRING)){
date.setError("Date of the hike is required");
isValidated = false;
}
if (difficutly.getText().toString().equals(Constants.EMPTY_STRING)){
difficutly.setError("Difficutly of the hike is required");
isValidated = false;
}
if (length.getText().toString().equals(Constants.EMPTY_STRING)){
length.setError("Length of the hike is required");
isValidated = false;
}
if (parking.getText().toString().equals(Constants.EMPTY_STRING)){
parking.setError("Please fill in the parking available or we will
assume that you do not need any parking");
binding.selectParking.setText("No parking available");
isValidated = false;
}
return isValidated;
}
This is the code that validates the required fields in fragmentEdit. If any case is empty it will
display a message and return false otherwise it will return true
private boolean saveAndReturn() {
Log.i(this.getClass().getName(), "Saved and return");

HikeEntity hike = new HikeEntity();

hike.setName(binding.editNameHike.getText().toString());
hike.setLocation(binding.editLocation.getText().toString());
hike.setDate(binding.editDateHike.getText().toString());
hike.setParkingAvailable(binding.selectParking.getText().toString());
hike.setLength(binding.editLengthOfHike.getText().toString());
hike.setDifficulty(binding.editDifficulty.getText().toString());
hike.setDescription(binding.editDescription.getText().toString());

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());


builder.setTitle("Information of this hike:");
builder.setMessage("Name of the hike: " +
binding.editNameHike.getText().toString() + "\n" +
"Location: " + binding.editLocation.getText().toString() + "\n" +
"Date Hike: " + binding.editDateHike.getText().toString() + "\n" +
"Parking available: " + binding.selectParking.getText().toString()
+ "\n" +
"Length: " + binding.editLengthOfHike.getText().toString() + "\n"
+
"Difficulty: " + binding.editDifficulty.getText().toString() + "\
n" +
"Description: " + binding.editDescription.getText().toString() +
"\n" );
builder.setPositiveButton("Save", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (getArguments().getString("id") != "0"){
hike.setId(getArguments().getString("id"));
dao.updateHike(hike);
}
else{
dao.insertHike(hike);
}
dialog.dismiss();
Navigation.findNavController(getView()).navigateUp();
}
});
builder.setNegativeButton("Back", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.show();
return true;
}
In the saveAndReturn method, the author creates a HikeEntity object with input from the
interface fields. After clicking the save icon, a confirmation dialog box with details and hike
information will be displayed. If the hiking trip already exists, an update will be made, if it is a
new trip, an addition will be made to the database. Finally, close the dialog box and redirect to
the previous screen of the application.

You might also like