From 933174a8c1a2bbe804176959bb7f87b77112c108 Mon Sep 17 00:00:00 2001 From: Nezumi <123229563+Nez27@users.noreply.github.com> Date: Sat, 8 Apr 2023 15:22:42 +0700 Subject: [PATCH] Tracking realtime shipper --- .idea/deploymentTargetDropDown.xml | 17 ++ app/build.gradle | 9 +- app/src/main/AndroidManifest.xml | 32 ++- .../foodify/API/GoogleMapDirectionApi.java | 19 ++ .../foodify/Activity/MainActivity.java | 4 +- .../Activity/OrderCheckOutActivity.java | 4 +- .../foodify/Activity/OrderDetailActivity.java | 33 ++- .../Activity/TrackingOrderActivity.java | 255 ++++++++++++++++++ .../foodify/Adapter/BasketAdapter.java | 3 + .../capstone/foodify/DirectionJSONParser.java | 100 +++++++ .../foodify/Fragment/BasketFragment.java | 3 - .../foodify/Fragment/HomeFragment.java | 12 +- .../foodify/Fragment/ProfileFragment.java | 1 + .../main/res/drawable/baseline_cancel_24.xml | 5 + .../res/drawable/baseline_location_on_24.xml | 5 + .../main/res/layout/activity_order_detail.xml | 48 +++- .../res/layout/activity_tracking_order.xml | 33 +++ app/src/main/res/layout/fragment_basket.xml | 2 +- app/src/main/res/layout/item_food.xml | 2 + app/src/main/res/values/strings.xml | 1 + build.gradle | 1 + 21 files changed, 564 insertions(+), 25 deletions(-) create mode 100644 .idea/deploymentTargetDropDown.xml create mode 100644 app/src/main/java/com/capstone/foodify/API/GoogleMapDirectionApi.java create mode 100644 app/src/main/java/com/capstone/foodify/Activity/TrackingOrderActivity.java create mode 100644 app/src/main/java/com/capstone/foodify/DirectionJSONParser.java create mode 100644 app/src/main/res/drawable/baseline_cancel_24.xml create mode 100644 app/src/main/res/drawable/baseline_location_on_24.xml create mode 100644 app/src/main/res/layout/activity_tracking_order.xml diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..9e69b5d --- /dev/null +++ b/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index d8c3475..b7b2f59 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'com.google.gms.google-services' + id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' } android { @@ -38,6 +39,9 @@ android { classpath 'com.google.gms:google-services:4.3.15' } } + buildFeatures { + viewBinding true + } } @@ -53,6 +57,7 @@ dependencies { implementation 'com.google.android.gms:play-services-maps:18.1.0' implementation 'com.google.android.gms:play-services-location:21.0.1' implementation files('libs/zpdk-release-v3.1.aar') + implementation 'com.google.firebase:firebase-database-ktx:20.1.0' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' @@ -69,7 +74,7 @@ dependencies { implementation 'com.github.denzcoskun:ImageSlideshow:0.1.0' implementation 'com.makeramen:roundedimageview:2.3.0' implementation 'com.github.smarteist:autoimageslider:1.4.0' - implementation 'com.github.bumptech.glide:glide:4.14.2' + implementation 'com.github.bumptech.glide:glide:4.15.1' annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' implementation 'com.github.kojofosu:Quantitizer:1.6.7' implementation 'com.squareup.picasso:picasso:2.71828' @@ -82,6 +87,8 @@ dependencies { implementation 'androidx.browser:browser:1.5.0' + implementation 'com.github.d-max:spots-dialog:1.1@aar' + //Firebase implementation platform('com.google.firebase:firebase-bom:31.2.3') implementation("com.squareup.okhttp3:okhttp:4.10.0") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 27e7499..b256a4c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -28,17 +28,39 @@ android:usesCleartextTraffic="true" tools:replace="android:theme" tools:targetApi="31"> + + + + + - + android:exported="true" + android:launchMode="singleTask"> + - + + getDirections(@Query("origin") String origin, @Query("destination") String destination, + @Query("key") String key); +} diff --git a/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java b/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java index 5f9dca3..d4bc0cf 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/MainActivity.java @@ -77,7 +77,6 @@ public class MainActivity extends AppCompatActivity { //Location private static final int REQUEST_CHECK_SETTINGS = 100; private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000; - private static final long FASTEST_UPDATE_IN_MILLISECONDS = 3000; private static final long MAX_WAIT_TIME_IN_MILLISECONDS = 1000; private static final int LOCATION_REQUEST_CODE = 100; private static final String TAG = MainActivity.class.getSimpleName(); @@ -167,7 +166,7 @@ public class MainActivity extends AppCompatActivity { mLocationRequest = new LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, UPDATE_INTERVAL_IN_MILLISECONDS) .setWaitForAccurateLocation(false) - .setMinUpdateDistanceMeters(FASTEST_UPDATE_IN_MILLISECONDS) + .setMinUpdateIntervalMillis(1000) .setMaxUpdateDelayMillis(MAX_WAIT_TIME_IN_MILLISECONDS) .build(); @@ -367,7 +366,6 @@ public class MainActivity extends AppCompatActivity { @Override protected void onResume() { super.onResume(); - HomeFragment.setNameUser(); if (mRequestingLocationUpdates && checkPermission() && Common.CURRENT_LOCATION == null) { startLocationUpdates(); } diff --git a/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java b/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java index 81141bf..1a1dd47 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/OrderCheckOutActivity.java @@ -358,7 +358,6 @@ public class OrderCheckOutActivity extends AppCompatActivity { // handle CreateOrder btn_ZaloPay.setOnClickListener(new View.OnClickListener() { - @RequiresApi(api = Build.VERSION_CODES.O) @SuppressLint("SetTextI18n") @Override public void onClick(View v) { @@ -438,10 +437,9 @@ public class OrderCheckOutActivity extends AppCompatActivity { Common.showErrorServerNotification(OrderCheckOutActivity.this, "Tài khoản của bạn đã bị khoá!"); } + progress_layout.setVisibility(View.GONE); } }); - - progress_layout.setVisibility(View.GONE); } private void createOrderFood(String transactionId, String paymentMethod) { diff --git a/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java b/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java index d1611f3..6d205e2 100644 --- a/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java +++ b/app/src/main/java/com/capstone/foodify/Activity/OrderDetailActivity.java @@ -40,13 +40,15 @@ import retrofit2.Response; public class OrderDetailActivity extends AppCompatActivity { private static final String AWAITING = "AWAITING"; + private static final String SHIPPING = "SHIPPING"; private TextView order_tracking_number, user_name, phone, address, orderTime, total, status; private ImageView back_image; private List listOrderDetails = new ArrayList<>(); OrderDetailAdapter adapter; RecyclerView recyclerView; private Order order; - private Button btn_cancel_order; + private Button btn_cancel_order, btn_tracking_location_shipper; + private View line_cancel_order, line_tracking_order; @Override protected void onCreate(Bundle savedInstanceState) { @@ -60,8 +62,18 @@ public class OrderDetailActivity extends AppCompatActivity { if(getIntent() != null) order = (Order) getIntent().getSerializableExtra("order"); - if(order.getStatus().equals(AWAITING)) + if(order.getStatus().equals(AWAITING)){ btn_cancel_order.setVisibility(View.VISIBLE); + line_tracking_order.setVisibility(View.GONE); + } + + + if(order.getStatus().equals(SHIPPING)){ + btn_tracking_location_shipper.setVisibility(View.VISIBLE); + line_cancel_order.setVisibility(View.GONE); + } + + //Init data order_tracking_number.setText("Order Id: #" + order.getOrderTrackingNumber()); @@ -101,6 +113,17 @@ public class OrderDetailActivity extends AppCompatActivity { showDeleteDialogConfirm(); } }); + + btn_tracking_location_shipper.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(OrderDetailActivity.this, TrackingOrderActivity.class); + intent.putExtra("trackingOrderNumber", order.getOrderTrackingNumber()); + intent.putExtra("latOrder", order.getLat()); + intent.putExtra("lngOrder", order.getLng()); + startActivity(intent); + } + }); } private void showDeleteDialogConfirm(){ @@ -141,8 +164,6 @@ public class OrderDetailActivity extends AppCompatActivity { @Override public void onClick(@NonNull AestheticDialog.Builder builder) { - OrderActivity.orderActivity.finish(); - startActivity(new Intent(OrderDetailActivity.this, OrderActivity.class)); builder.dismiss(); finish(); @@ -173,6 +194,10 @@ public class OrderDetailActivity extends AppCompatActivity { back_image = findViewById(R.id.back_image); btn_cancel_order = findViewById(R.id.cancel_order_button); status = findViewById(R.id.status); + btn_tracking_location_shipper = findViewById(R.id.tracking_shipper_location_button); + + line_cancel_order = findViewById(R.id.line_view_cancel_order); + line_tracking_order = findViewById(R.id.line_view_tracking_order); } private String translateStatus(String status){ diff --git a/app/src/main/java/com/capstone/foodify/Activity/TrackingOrderActivity.java b/app/src/main/java/com/capstone/foodify/Activity/TrackingOrderActivity.java new file mode 100644 index 0000000..8d0a4f3 --- /dev/null +++ b/app/src/main/java/com/capstone/foodify/Activity/TrackingOrderActivity.java @@ -0,0 +1,255 @@ +package com.capstone.foodify.Activity; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.FragmentActivity; + +import com.capstone.foodify.API.GoogleMapDirectionApi; +import com.capstone.foodify.Common; +import com.capstone.foodify.DirectionJSONParser; +import com.capstone.foodify.Model.GoogleMap.Location; +import com.capstone.foodify.R; +import com.capstone.foodify.databinding.ActivityTrackingOrderBinding; +import com.google.android.gms.maps.CameraUpdateFactory; +import com.google.android.gms.maps.GoogleMap; +import com.google.android.gms.maps.OnMapReadyCallback; +import com.google.android.gms.maps.SupportMapFragment; +import com.google.android.gms.maps.model.BitmapDescriptor; +import com.google.android.gms.maps.model.BitmapDescriptorFactory; +import com.google.android.gms.maps.model.CameraPosition; +import com.google.android.gms.maps.model.LatLng; +import com.google.android.gms.maps.model.Marker; +import com.google.android.gms.maps.model.MarkerOptions; +import com.google.android.gms.maps.model.Polyline; +import com.google.android.gms.maps.model.PolylineOptions; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class TrackingOrderActivity extends FragmentActivity implements OnMapReadyCallback, ValueEventListener { + + private GoogleMap mMap; + private ActivityTrackingOrderBinding binding; + private String trackingOrderNumber, latOrder, lngOrder = null; + private ImageView back_image; + private FirebaseDatabase database; + private DatabaseReference orderDatabase; + private Marker shippingMarker; + private Polyline polyline; + private static final String TAG = "TrackingOrderActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //Get tracking number order + if(getIntent() != null){ + trackingOrderNumber = getIntent().getStringExtra("trackingOrderNumber"); + latOrder = getIntent().getStringExtra("latOrder"); + lngOrder = getIntent().getStringExtra("lngOrder"); + } + + if(trackingOrderNumber == null){ + Toast.makeText(this, "Chưa lấy được mã đơn hàng! Xin vui lòng thử lại sau!", Toast.LENGTH_SHORT).show(); + finish(); + } + binding = ActivityTrackingOrderBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + + database = FirebaseDatabase.getInstance(); + orderDatabase = database.getReference("Order"); + orderDatabase.addValueEventListener(this); + + //Init component + back_image = findViewById(R.id.back_image); + + back_image.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onBackPressed(); + finish(); + } + }); + + + + + // Obtain the SupportMapFragment and get notified when the map is ready to be used. + SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() + .findFragmentById(R.id.map); + mapFragment.getMapAsync(this); + } + + /** + * Manipulates the map once available. + * This callback is triggered when the map is ready to be used. + * This is where we can add markers or lines, add listeners or move the camera. In this case, + * we just add a marker near Sydney, Australia. + * If Google Play services is not installed on the device, the user will be prompted to install + * it inside the SupportMapFragment. This method will only be triggered once the user has + * installed Google Play services and returned to the app. + */ + @SuppressLint("MissingPermission") + @Override + public void onMapReady(GoogleMap googleMap) { + mMap = googleMap; + mMap.getUiSettings().setZoomControlsEnabled(true); + mMap.getUiSettings().setMapToolbarEnabled(true); + mMap.getUiSettings().setCompassEnabled(true); + + + trackingLocation(); + } + + private void trackingLocation() { + //Get order location + LatLng location = new LatLng(Double.parseDouble(latOrder), Double.parseDouble(lngOrder)); + + mMap.addMarker(new MarkerOptions().position(location) + .title("Đơn hàng #" + trackingOrderNumber) + .icon(BitmapDescriptorFactory.defaultMarker())); + + //Set shipper location + orderDatabase.child(trackingOrderNumber).addListenerForSingleValueEvent(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + Location shipperLocation = snapshot.getValue(Location.class); + + LatLng latLng = new LatLng(shipperLocation.getLat(), shipperLocation.getLng()); + if(shippingMarker == null){ + shippingMarker = mMap.addMarker(new MarkerOptions() + .position(latLng) + .title("Người giao") + .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN))); + } else { + shippingMarker.setPosition(latLng); + } + + //Update camera + CameraPosition cameraPosition = new CameraPosition.Builder() + .target(latLng) + .zoom(16) + .bearing(0) + .tilt(45) + .build(); + mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); + + //Draw routes + if(polyline != null) + polyline.remove(); + GoogleMapDirectionApi.apiService.getDirections(shipperLocation.getLat() + "," + shipperLocation.getLng(), + latOrder + "," + lngOrder, Common.MAP_API + ).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + assert response.body() != null; + new ParserTask().execute(response.body()); + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(TrackingOrderActivity.this, "Có lỗi kết nối!", Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void onCancelled(@NonNull DatabaseError error) { + + } + }); + } + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + trackingLocation(); + } + + @Override + public void onCancelled(@NonNull DatabaseError error) { + + } + + + private class ParserTask extends AsyncTask>>> { + + @Override + protected void onPreExecute() { + super.onPreExecute(); + } + + @Override + protected List>> doInBackground(String... strings) { + JSONObject jsonObject; + List>> routes = null; + try { + jsonObject = new JSONObject(strings[0]); + DirectionJSONParser parser = new DirectionJSONParser(); + + routes = parser.parse(jsonObject); + } catch (JSONException e) { + e.printStackTrace(); + } + return routes; + } + + @Override + protected void onPostExecute(List>> lists) { + + ArrayList points = new ArrayList(); + PolylineOptions lineOptions = new PolylineOptions(); + + for(int i = 0; i < lists.size(); i++){ + + List> path = lists.get(i); + + for(int j = 0; j < path.size(); j++) { + HashMap point = path.get(j); + + double lat = Double.parseDouble(point.get("lat")); + double lng = Double.parseDouble(point.get("lng")); + LatLng position = new LatLng(lat, lng); + + points.add(position); + } + + lineOptions.addAll(points); + lineOptions.width(12); + lineOptions.color(Color.RED); + lineOptions.geodesic(true); + } + polyline = mMap.addPolyline(lineOptions); + } + } + + @Override + protected void onStop() { + orderDatabase.removeEventListener(this); + super.onStop(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java b/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java index 559d4ed..98b12ad 100644 --- a/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java +++ b/app/src/main/java/com/capstone/foodify/Adapter/BasketAdapter.java @@ -112,6 +112,8 @@ public class BasketAdapter extends RecyclerView.Adapter>> parse(JSONObject jObject) { + + List>> routes = new ArrayList>>(); + JSONArray jRoutes = null; + JSONArray jLegs = null; + JSONArray jSteps = null; + + try { + + jRoutes = jObject.getJSONArray("routes"); + + /** Traversing all routes */ + for (int i = 0; i < jRoutes.length(); i++) { + jLegs = ((JSONObject) jRoutes.get(i)).getJSONArray("legs"); + List path = new ArrayList>(); + + /** Traversing all legs */ + for (int j = 0; j < jLegs.length(); j++) { + jSteps = ((JSONObject) jLegs.get(j)).getJSONArray("steps"); + + /** Traversing all steps */ + for (int k = 0; k < jSteps.length(); k++) { + String polyline = ""; + polyline = (String) ((JSONObject) ((JSONObject) jSteps.get(k)).get("polyline")).get("points"); + List list = decodePoly(polyline); + + /** Traversing all points */ + for (int l = 0; l < list.size(); l++) { + HashMap hm = new HashMap(); + hm.put("lat", Double.toString(((LatLng) list.get(l)).latitude)); + hm.put("lng", Double.toString(((LatLng) list.get(l)).longitude)); + path.add(hm); + } + } + routes.add(path); + } + } + + } catch (JSONException e) { + e.printStackTrace(); + } catch (Exception e) { + } + + return routes; + } + + /** + * Method to decode polyline points + * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java + */ + private List decodePoly(String encoded) { + List poly = new ArrayList(); + int index = 0, len = encoded.length(); + int lat = 0, lng = 0; + + while (index < len) { + int b, shift = 0, result = 0; + do { + b = encoded.charAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lat += dlat; + + shift = 0; + result = 0; + do { + b = encoded.charAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); + lng += dlng; + + LatLng p = new LatLng((((double) lat / 1E5)), + (((double) lng / 1E5))); + poly.add(p); + } + + return poly; + } +} diff --git a/app/src/main/java/com/capstone/foodify/Fragment/BasketFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/BasketFragment.java index 2b92416..6e3f2d9 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/BasketFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/BasketFragment.java @@ -61,9 +61,6 @@ public class BasketFragment extends Fragment implements ItemTouchHelperListener btnCheckOut = view.findViewById(R.id.btnCheckOut); listBasketFoodLayout = view.findViewById(R.id.list_basket_food_layout); - //Init data - total.setText(Common.changeCurrencyUnit(0)); - //Check list basket is null or not! checkListBasket(); diff --git a/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java index 6ce0df5..78a499b 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/HomeFragment.java @@ -71,6 +71,8 @@ public class HomeFragment extends Fragment { rcvMenu.setAdapter(menuAdapter); } + setNameUser(); + LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), RecyclerView.VERTICAL, false); rcvMenu.setLayoutManager(linearLayoutManager); @@ -91,10 +93,12 @@ public class HomeFragment extends Fragment { } public static void setNameUser(){ - //Set name user while user already login - if(Common.CURRENT_USER != null) - welcomeText.setText("Xin chào, " + Common.CURRENT_USER.getFullName() + "!"); - else + if(Common.CURRENT_USER != null){ + //Set name user while user already login + String[] arrayOfName = Common.CURRENT_USER.getFullName().split(" "); + String name = arrayOfName[arrayOfName.length - 1]; + welcomeText.setText("Xin chào, " + name + "!"); + } else welcomeText.setText("Xin chào, khách!"); } diff --git a/app/src/main/java/com/capstone/foodify/Fragment/ProfileFragment.java b/app/src/main/java/com/capstone/foodify/Fragment/ProfileFragment.java index d2f00d5..012e397 100644 --- a/app/src/main/java/com/capstone/foodify/Fragment/ProfileFragment.java +++ b/app/src/main/java/com/capstone/foodify/Fragment/ProfileFragment.java @@ -108,6 +108,7 @@ public class ProfileFragment extends Fragment { Common.TOKEN = null; Common.CURRENT_USER = null; + dialog.dismiss(); getActivity().startActivity(new Intent(getContext(), MainActivity.class)); getActivity().finish(); } diff --git a/app/src/main/res/drawable/baseline_cancel_24.xml b/app/src/main/res/drawable/baseline_cancel_24.xml new file mode 100644 index 0000000..a0a94e3 --- /dev/null +++ b/app/src/main/res/drawable/baseline_cancel_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/baseline_location_on_24.xml b/app/src/main/res/drawable/baseline_location_on_24.xml new file mode 100644 index 0000000..dd12113 --- /dev/null +++ b/app/src/main/res/drawable/baseline_location_on_24.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/layout/activity_order_detail.xml b/app/src/main/res/layout/activity_order_detail.xml index 9d9c1e6..81101c3 100644 --- a/app/src/main/res/layout/activity_order_detail.xml +++ b/app/src/main/res/layout/activity_order_detail.xml @@ -138,11 +138,37 @@ app:layout_constraintTop_toBottomOf="@id/order_view" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" + android:drawableLeft="@drawable/baseline_cancel_24" + android:drawableTint="@color/white" + android:drawablePadding="10dip" + android:paddingLeft="50dp" + android:paddingRight="50dp" + android:gravity="center" + android:visibility="gone" + /> + +