Tracking realtime shipper

This commit is contained in:
Nezumi
2023-04-08 15:22:42 +07:00
parent 93a0b970d9
commit 933174a8c1
21 changed files with 564 additions and 25 deletions
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<runningDeviceTargetSelectedWithDropDown>
<Target>
<type value="RUNNING_DEVICE_TARGET" />
<deviceKey>
<Key>
<type value="SERIAL_NUMBER" />
<value value="60646e70" />
</Key>
</deviceKey>
</Target>
</runningDeviceTargetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-04-08T07:13:47.827233500Z" />
</component>
</project>
+8 -1
View File
@@ -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")
+27 -5
View File
@@ -28,17 +28,39 @@
android:usesCleartextTraffic="true"
tools:replace="android:theme"
tools:targetApi="31">
<!--
TODO: Before you run your application, you need a Google Maps API key.
To get one, follow the directions here:
https://developers.google.com/maps/documentation/android-sdk/get-api-key
Once you have your API key (it starts with "AIza"), define a new property in your
project's local.properties file (e.g. MAPS_API_KEY=Aiza...), and replace the
"YOUR_API_KEY" string in this file with "${MAPS_API_KEY}".
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyAY14Ic32UP26Hg6GILznOfbBihiY5BUxw" />
<activity
android:name=".Activity.TrackingOrderActivity"
android:exported="false"
android:label="@string/title_activity_tracking_order" />
<activity
android:name=".Activity.OrderCheckOutActivity"
android:launchMode="singleTask"
android:exported="true">
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="demozpdk"
android:host="app" />
<data
android:host="app"
android:scheme="demozpdk" />
</intent-filter>
</activity>
<activity
@@ -0,0 +1,19 @@
package com.capstone.foodify.API;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface GoogleMapDirectionApi {
GoogleMapDirectionApi apiService = new Retrofit.Builder()
.baseUrl("https://maps.googleapis.com/").addConverterFactory(ScalarsConverterFactory.create())
.build()
.create(GoogleMapDirectionApi.class);
@GET("maps/api/directions/json")
Call<String> getDirections(@Query("origin") String origin, @Query("destination") String destination,
@Query("key") String key);
}
@@ -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();
}
@@ -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) {
@@ -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<Basket> 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){
@@ -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<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
assert response.body() != null;
new ParserTask().execute(response.body());
}
@Override
public void onFailure(Call<String> 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<String, Integer, List<List<HashMap<String, String>>>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... strings) {
JSONObject jsonObject;
List<List<HashMap<String, String>>> 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<List<HashMap<String, String>>> lists) {
ArrayList points = new ArrayList();
PolylineOptions lineOptions = new PolylineOptions();
for(int i = 0; i < lists.size(); i++){
List<HashMap<String, String>> path = lists.get(i);
for(int j = 0; j < path.size(); j++) {
HashMap<String, String> 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();
}
}
@@ -112,6 +112,8 @@ public class BasketAdapter extends RecyclerView.Adapter<BasketAdapter.BasketView
//Update total price
calculateTotalPrice();
Common.FINAL_SHOP = null;
} else {
foodBasket.setQuantity(String.valueOf(quantity));
holder.value.setText(String.valueOf(quantity));
@@ -129,6 +131,7 @@ public class BasketAdapter extends RecyclerView.Adapter<BasketAdapter.BasketView
for(Basket foodTemp: listBasketFood){
total += (foodTemp.getCost()) * (Float.parseFloat(foodTemp.getQuantity())) * (100 - foodTemp.getDiscountPercent())/100;
}
basketFragment.total.setText(Common.changeCurrencyUnit(total));
basketFragment.totalFloat = total;
}
@@ -0,0 +1,100 @@
package com.capstone.foodify;
import com.google.android.gms.maps.model.LatLng;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DirectionJSONParser {
/**
* Receives a JSONObject and returns a list of lists containing latitude and longitude
*/
public List<List<HashMap<String, String>>> parse(JSONObject jObject) {
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String, String>>>();
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<HashMap<String, String>>();
/** 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<String, String> hm = new HashMap<String, String>();
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;
}
}
@@ -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();
@@ -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!");
}
@@ -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();
}
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C6.47,2 2,6.47 2,12s4.47,10 10,10 10,-4.47 10,-10S17.53,2 12,2zM17,15.59L15.59,17 12,13.41 8.41,17 7,15.59 10.59,12 7,8.41 8.41,7 12,10.59 15.59,7 17,8.41 13.41,12 17,15.59z"/>
</vector>
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>
@@ -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"
/>
<Button
android:id="@+id/tracking_shipper_location_button"
android:text="Vị trí shipper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
app:layout_constraintTop_toBottomOf="@id/order_view"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:backgroundTint="#2ADFD1"
android:drawableLeft="@drawable/baseline_location_on_24"
android:drawableTint="@color/white"
android:drawablePadding="10dip"
android:paddingLeft="50dp"
android:paddingRight="50dp"
android:gravity="center"
android:visibility="gone"
/>
<View
android:id="@+id/line_view"
android:id="@+id/line_view_cancel_order"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="2dp"
@@ -150,8 +176,28 @@
app:layout_constraintTop_toBottomOf="@id/cancel_order_button"
/>
<View
android:id="@+id/line_view_tracking_order"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/gray"
app:layout_constraintTop_toBottomOf="@id/tracking_shipper_location_button"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<TextView
android:textSize="25sp"
android:fontFamily="@font/bebas"
android:textColor="@color/black"
android:layout_marginStart="12dp"
android:text="Chi tiết các món ăn:"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view_order_detail"
android:layout_marginTop="10dp"
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Activity.TrackingOrderActivity"
>
<ImageView
android:id="@+id/back_image"
android:layout_width="30dp"
android:layout_height="30dp"
android:padding="8dp"
android:layout_marginStart="15dp"
android:layout_marginTop="60dp"
android:src="@drawable/back_button"
android:background="@drawable/circle_button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:elevation="10dp"
/>
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.TrackingOrderActivity"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
+1 -1
View File
@@ -117,7 +117,7 @@
<TextView
android:id="@+id/total_text_view"
android:text="$10,000"
android:text="0 đ"
android:fontFamily="@font/opensans"
android:textSize="24sp"
android:textColor="@android:color/white"
+2
View File
@@ -41,6 +41,8 @@
android:layout_marginTop="3dp"
app:layout_constraintTop_toBottomOf="@+id/image_view"
app:layout_constraintStart_toStartOf="parent"
android:maxLines="2"
android:ellipsize="end"
/>
<LinearLayout
+1
View File
@@ -48,4 +48,5 @@
<string name="full_name">Họ và tên</string>
<string name="basket">basket</string>
<string name="food_name">Food Name</string>
<string name="title_activity_tracking_order">TrackingOrderActivity</string>
</resources>
+1
View File
@@ -6,4 +6,5 @@ buildscript {
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'com.google.android.libraries.mapsplatform.secrets-gradle-plugin' version '2.0.1' apply false
}