Updated UI regarding place visualization in map
This commit is contained in:
parent
3e167da742
commit
598978ee15
|
|
@ -86,16 +86,12 @@ public class MyReportsAdapter extends RecyclerView.Adapter<MyReportsAdapter.View
|
|||
AlertDialog dialog = DialogUtils.confirmationDialog(
|
||||
context,
|
||||
confirmationText,
|
||||
(dialogInterface, i) -> {
|
||||
removeReport(report.getUuid());
|
||||
}
|
||||
(dialogInterface, i) -> removeReport(report.getUuid())
|
||||
);
|
||||
dialog.show();
|
||||
});
|
||||
|
||||
holder.ivEdit.setOnClickListener(v -> {
|
||||
Helper.goTo(context, AddReportActivity.class, Constants.REPORT, report);
|
||||
});
|
||||
holder.ivEdit.setOnClickListener(v -> Helper.goTo(context, AddReportActivity.class, Constants.REPORT, report));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error in MyReports Adapter", e);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ public class PlaceReportsAdapter extends RecyclerView.Adapter<PlaceReportsAdapte
|
|||
this.context = context;
|
||||
this.reportList = reportList;
|
||||
}
|
||||
|
||||
public void clearReports() {
|
||||
reportList.clear();
|
||||
notifyDataSetChanged();
|
||||
|
|
@ -60,14 +61,14 @@ public class PlaceReportsAdapter extends RecyclerView.Adapter<PlaceReportsAdapte
|
|||
holder.tvDescription.setText(report.getDescription());
|
||||
if (report.getReportRating() == 1) {
|
||||
holder.tvRating.setText(context.getString(R.string.Rating_BAD));
|
||||
holder.ivRating.setImageResource(R.drawable.ic_thumbs_down);} else if (report.getReportRating() == 2) {
|
||||
holder.ivRating.setImageResource(R.drawable.ic_thumbs_down);
|
||||
} else if (report.getReportRating() == 2) {
|
||||
holder.tvRating.setText(context.getString(R.string.Rating_AVERAGE));
|
||||
holder.ivRating.setImageResource(R.drawable.ic_thumb_up_average);
|
||||
} else if (report.getReportRating() == 3) {
|
||||
holder.tvRating.setText(context.getString(R.string.Rating_GOOD));
|
||||
holder.ivRating.setImageResource(R.drawable.ic_thumbs_up);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Error in PlaceReportsAdapter", e);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,374 @@
|
|||
package com.example.acloc.dialog;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatButton;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.acloc.activity.AddNewPlaceActivity;
|
||||
import com.example.acloc.activity.AddReportActivity;
|
||||
import com.example.acloc.activity.PlaceDetailActivity;
|
||||
import com.example.acloc.adapter.PlaceReportsAdapter;
|
||||
import com.example.acloc.api.LocationApiClient;
|
||||
import com.example.acloc.model.Place;
|
||||
import com.example.acloc.model.Report;
|
||||
import com.example.acloc.service.FavoriteService;
|
||||
import com.example.acloc.service.ReportService;
|
||||
import com.example.acloc.utility.Constants;
|
||||
import com.example.acloc.utility.DialogUtils;
|
||||
import com.example.acloc.utility.Helper;
|
||||
import com.example.acloc.utility.SharedPref;
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.ieslamar.acloc.R;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class PlaceBottomSheetDialog extends BottomSheetDialogFragment {
|
||||
private static final String TAG = "PlaceBottomSheetDialog";
|
||||
|
||||
private final Place place;
|
||||
private Context context;
|
||||
private boolean isFavorite = false;
|
||||
|
||||
private TextView tvPlaceName, tvAddress, tvDescription, tvNoReports;
|
||||
private ImageView ivFavorite, ivEdit, ivExpand;
|
||||
private AppCompatButton btnAddReport;
|
||||
private RecyclerView rvReports;
|
||||
private PlaceReportsAdapter adapter;
|
||||
private final List<Report> reportList = new ArrayList<>();
|
||||
private BottomSheetBehavior<View> behavior;
|
||||
|
||||
public PlaceBottomSheetDialog(Place place) {
|
||||
this.place = place;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||
BottomSheetDialog dialog = (BottomSheetDialog) super.onCreateDialog(savedInstanceState);
|
||||
|
||||
dialog.setOnShowListener(dialogInterface -> {
|
||||
BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
|
||||
View bottomSheet = bottomSheetDialog.findViewById(com.google.android.material.R.id.design_bottom_sheet);
|
||||
if (bottomSheet != null) {
|
||||
behavior = BottomSheetBehavior.from(bottomSheet);
|
||||
behavior.setPeekHeight(getResources().getDisplayMetrics().heightPixels / 2);
|
||||
behavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
|
||||
}
|
||||
});
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.bottom_sheet_place_detail, container, false);
|
||||
context = getContext();
|
||||
|
||||
initUI(view);
|
||||
setPlaceData();
|
||||
initListeners();
|
||||
checkIfPlaceIsFavorite(SharedPref.getUserUid(context), place.getUuid());
|
||||
loadReports();
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
private void initUI(View view) {
|
||||
tvPlaceName = view.findViewById(R.id.tvPlaceName);
|
||||
tvAddress = view.findViewById(R.id.tvAddress);
|
||||
tvDescription = view.findViewById(R.id.tvDescription);
|
||||
tvNoReports = view.findViewById(R.id.tvNoData);
|
||||
ivFavorite = view.findViewById(R.id.ivFavorite);
|
||||
ivEdit = view.findViewById(R.id.ivEdit);
|
||||
ivExpand = view.findViewById(R.id.ivExpand);
|
||||
btnAddReport = view.findViewById(R.id.btnAddReport);
|
||||
rvReports = view.findViewById(R.id.rvReports);
|
||||
|
||||
// Set up RecyclerView
|
||||
rvReports.setLayoutManager(new LinearLayoutManager(context));
|
||||
}
|
||||
|
||||
private void setPlaceData() {
|
||||
tvPlaceName.setText(place.getName());
|
||||
tvAddress.setText(place.getAddress());
|
||||
tvDescription.setText(place.getDescription());
|
||||
}
|
||||
|
||||
private void initListeners() {
|
||||
ivFavorite.setOnClickListener(v -> {
|
||||
if (isFavorite) {
|
||||
removePlaceFromFavorites(SharedPref.getUserUid(context), place.getUuid());
|
||||
} else {
|
||||
addPlaceToFavorites(SharedPref.getUserUid(context), place.getUuid());
|
||||
}
|
||||
});
|
||||
|
||||
ivEdit.setOnClickListener(v -> {
|
||||
Helper.goTo(context, AddNewPlaceActivity.class, Constants.PLACE, place);
|
||||
dismiss();
|
||||
});
|
||||
|
||||
ivExpand.setOnClickListener(v -> {
|
||||
if (behavior.getState() == BottomSheetBehavior.STATE_EXPANDED) {
|
||||
behavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);
|
||||
ivExpand.setImageResource(R.drawable.ic_expand_less);
|
||||
} else {
|
||||
behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
ivExpand.setImageResource(R.drawable.ic_expand_more);
|
||||
}
|
||||
});
|
||||
|
||||
btnAddReport.setOnClickListener(v -> {
|
||||
Helper.goTo(context, AddReportActivity.class, Constants.PLACE, place);
|
||||
dismiss();
|
||||
});
|
||||
|
||||
// Open full screen details on click
|
||||
View.OnClickListener fullScreenListener = v -> {
|
||||
Helper.goTo(context, PlaceDetailActivity.class, Constants.PLACE, place);
|
||||
dismiss();
|
||||
};
|
||||
|
||||
tvPlaceName.setOnClickListener(fullScreenListener);
|
||||
tvAddress.setOnClickListener(fullScreenListener);
|
||||
tvDescription.setOnClickListener(fullScreenListener);
|
||||
}
|
||||
|
||||
private void loadReports() {
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context);
|
||||
ReportService reportService = LocationApiClient.getInstance().getReportService();
|
||||
|
||||
Call<JsonObject> call = reportService.getPlaceReports(token, place.getUuid());
|
||||
call.enqueue(new Callback<JsonObject>() {
|
||||
@Override
|
||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
JsonObject responseBody = response.body();
|
||||
JsonObject data = responseBody.getAsJsonObject("_data");
|
||||
|
||||
if (data != null && data.has("reports")) {
|
||||
reportList.clear();
|
||||
|
||||
for (JsonElement element : data.getAsJsonArray("reports")) {
|
||||
JsonObject reportObject = element.getAsJsonObject();
|
||||
Report report = new Report();
|
||||
|
||||
report.setUuid(reportObject.get("uuid").getAsString());
|
||||
report.setReportRating(reportObject.get("rating").getAsInt());
|
||||
report.setDescription(reportObject.get("description").getAsString());
|
||||
report.setPlaceName(reportObject.get("place_name").getAsString());
|
||||
report.setPlaceUuid(reportObject.get("place_uuid").getAsString());
|
||||
|
||||
reportList.add(report);
|
||||
}
|
||||
|
||||
// Show latest reports first
|
||||
Collections.reverse(reportList);
|
||||
List<Report> latestReports = reportList.size() > 3 ?
|
||||
reportList.subList(0, 3) : reportList;
|
||||
|
||||
updateReportsUI(latestReports);
|
||||
} else {
|
||||
showNoReports();
|
||||
}
|
||||
} else {
|
||||
showNoReports();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||
showNoReports();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateReportsUI(List<Report> reports) {
|
||||
if (reports != null && !reports.isEmpty()) {
|
||||
adapter = new PlaceReportsAdapter(context, reports);
|
||||
rvReports.setAdapter(adapter);
|
||||
rvReports.setVisibility(View.VISIBLE);
|
||||
tvNoReports.setVisibility(View.GONE);
|
||||
} else {
|
||||
showNoReports();
|
||||
}
|
||||
}
|
||||
|
||||
private void showNoReports() {
|
||||
rvReports.setVisibility(View.GONE);
|
||||
tvNoReports.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private void checkIfPlaceIsFavorite(String userUuid, String placeUuid) {
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context);
|
||||
FavoriteService favoriteService = LocationApiClient.getInstance().getFavoriteService();
|
||||
|
||||
Call<JsonObject> call = favoriteService.getFavoritePlaces(token, userUuid);
|
||||
call.enqueue(new Callback<JsonObject>() {
|
||||
@Override
|
||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
JsonObject body = response.body();
|
||||
JsonArray favoritesArray = body.getAsJsonObject("_data").getAsJsonArray("favorites");
|
||||
|
||||
isFavorite = false;
|
||||
for (JsonElement item : favoritesArray) {
|
||||
JsonObject favoriteObj = item.getAsJsonObject();
|
||||
String favPlaceUuid = favoriteObj.get("place_uuid").getAsString();
|
||||
if (favPlaceUuid.equals(placeUuid)) {
|
||||
isFavorite = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateFavoriteIcon();
|
||||
} else {
|
||||
isFavorite = false;
|
||||
updateFavoriteIcon();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||
isFavorite = false;
|
||||
updateFavoriteIcon();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateFavoriteIcon() {
|
||||
if (isFavorite) {
|
||||
ivFavorite.setImageResource(R.drawable.ic_favorite);
|
||||
} else {
|
||||
ivFavorite.setImageResource(R.drawable.ic_favorite_border);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPlaceToFavorites(String userUuid, String placeUuid) {
|
||||
DialogUtils.showLoadingDialog(context, getString(R.string.Adding_to_favorites));
|
||||
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("place_uuid", placeUuid);
|
||||
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context);
|
||||
FavoriteService favoriteService = LocationApiClient.getInstance().getFavoriteService();
|
||||
|
||||
Call<JsonObject> call = favoriteService.restorePlaceToFavorites(token, userUuid, body);
|
||||
call.enqueue(new Callback<JsonObject>() {
|
||||
@Override
|
||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||
DialogUtils.dismissDialog();
|
||||
if (response.isSuccessful()) {
|
||||
isFavorite = true;
|
||||
updateFavoriteIcon();
|
||||
Helper.showToast(context, getString(R.string.Place_added_to_favorites));
|
||||
} else {
|
||||
try {
|
||||
if (response.errorBody() != null) {
|
||||
String errorBody = response.errorBody().string();
|
||||
|
||||
// Try restoring if it's a duplicate (409 Conflict)
|
||||
if (response.code() == 409 && errorBody.contains("ER_DUP_ENTRY")) {
|
||||
restorePlaceToFavorites(userUuid, placeUuid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "ERROR: ", e);
|
||||
}
|
||||
|
||||
Helper.showToast(context, getString(R.string.Failed_to_add_favorite_Server_error));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||
DialogUtils.dismissDialog();
|
||||
Helper.showToast(context, getString(R.string.Network_error_Try_again));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void restorePlaceToFavorites(String userUuid, String placeUuid) {
|
||||
DialogUtils.showLoadingDialog(context, getString(R.string.Restoring_favorite));
|
||||
|
||||
JsonObject body = new JsonObject();
|
||||
body.addProperty("place_uuid", placeUuid);
|
||||
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context);
|
||||
FavoriteService favoriteService = LocationApiClient.getInstance().getFavoriteService();
|
||||
|
||||
Call<JsonObject> call = favoriteService.restorePlaceToFavorites(token, userUuid, body);
|
||||
call.enqueue(new Callback<JsonObject>() {
|
||||
@Override
|
||||
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
|
||||
DialogUtils.dismissDialog();
|
||||
if (response.isSuccessful()) {
|
||||
isFavorite = true;
|
||||
updateFavoriteIcon();
|
||||
Helper.showToast(context, getString(R.string.Place_restored_to_favorites));
|
||||
} else {
|
||||
Helper.showToast(context, getString(R.string.Failed_to_restore_favorite));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<JsonObject> call, Throwable t) {
|
||||
DialogUtils.dismissDialog();
|
||||
Helper.showToast(context, getString(R.string.Network_error_Try_again));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removePlaceFromFavorites(String userUuid, String placeUuid) {
|
||||
DialogUtils.showLoadingDialog(context, getString(R.string.Removing_from_favorites));
|
||||
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context);
|
||||
FavoriteService favoriteService = LocationApiClient.getInstance().getFavoriteService();
|
||||
|
||||
Call<Void> call = favoriteService.removePlaceFromFavorites(token, userUuid, placeUuid);
|
||||
call.enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(Call<Void> call, Response<Void> response) {
|
||||
DialogUtils.dismissDialog();
|
||||
if (response.isSuccessful()) {
|
||||
isFavorite = false;
|
||||
updateFavoriteIcon();
|
||||
Helper.showToast(context, getString(R.string.Removed_from_favorites));
|
||||
} else {
|
||||
Helper.showToast(context, getString(R.string.Failed_to_remove_from_favorites));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Void> call, Throwable t) {
|
||||
DialogUtils.dismissDialog();
|
||||
Helper.showToast(context, getString(R.string.Network_error_Try_again));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -12,23 +12,29 @@ import android.location.Geocoder;
|
|||
import android.location.Location;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.ieslamar.acloc.R;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.example.acloc.activity.AddNewPlaceActivity;
|
||||
import com.example.acloc.activity.PlaceDetailActivity;
|
||||
import com.example.acloc.api.LocationApiClient;
|
||||
import com.example.acloc.dialog.PlaceBottomSheetDialog;
|
||||
import com.example.acloc.model.Place;
|
||||
import com.example.acloc.service.PlaceService;
|
||||
import com.example.acloc.utility.Constants;
|
||||
|
|
@ -40,8 +46,10 @@ import com.google.android.gms.maps.CameraUpdateFactory;
|
|||
import com.google.android.gms.maps.GoogleMap;
|
||||
import com.google.android.gms.maps.SupportMapFragment;
|
||||
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.material.textfield.TextInputEditText;
|
||||
import com.ieslamar.acloc.R;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
|
@ -59,19 +67,26 @@ import retrofit2.Response;
|
|||
public class MapFragment extends Fragment {
|
||||
public static final String TAG = MapFragment.class.getSimpleName();
|
||||
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
|
||||
private static final float DEFAULT_ZOOM = 14f;
|
||||
private static final float SEARCH_ZOOM = 16f;
|
||||
|
||||
private RelativeLayout rlMap;
|
||||
private View view;
|
||||
private TextInputEditText etSearchLocation;
|
||||
private ListView lvSuggestions;
|
||||
private GoogleMap googleMap;
|
||||
private FusedLocationProviderClient fusedLocationClient;
|
||||
private Geocoder geocoder;
|
||||
private Dialog dialog;
|
||||
private Context context;
|
||||
private Handler searchHandler = new Handler(Looper.getMainLooper());
|
||||
private Runnable searchRunnable;
|
||||
private List<String> suggestionsList = new ArrayList<>();
|
||||
private ArrayAdapter<String> suggestionsAdapter;
|
||||
private List<Address> addressResults = new ArrayList<>();
|
||||
|
||||
private List<Place> placeList = new ArrayList<>();
|
||||
|
||||
|
||||
public MapFragment() {
|
||||
}
|
||||
|
||||
|
|
@ -94,10 +109,32 @@ public class MapFragment extends Fragment {
|
|||
private void initUI() {
|
||||
rlMap = view.findViewById(R.id.rlMap);
|
||||
etSearchLocation = view.findViewById(R.id.etSearchLocation);
|
||||
|
||||
// Initialize suggestions ListView
|
||||
lvSuggestions = view.findViewById(R.id.lvSuggestions);
|
||||
if (lvSuggestions == null) {
|
||||
// If the ListView doesn't exist in the layout, create it programmatically
|
||||
lvSuggestions = new ListView(getContext());
|
||||
lvSuggestions.setId(View.generateViewId());
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.addRule(RelativeLayout.BELOW, etSearchLocation.getId());
|
||||
lvSuggestions.setLayoutParams(params);
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
lvSuggestions.setBackgroundColor(getResources().getColor(android.R.color.white));
|
||||
rlMap.addView(lvSuggestions);
|
||||
}
|
||||
}
|
||||
|
||||
private void initObj() {
|
||||
context = getContext();
|
||||
|
||||
// Initialize suggestions adapter
|
||||
suggestionsAdapter = new ArrayAdapter<>(context,
|
||||
android.R.layout.simple_list_item_1, suggestionsList);
|
||||
lvSuggestions.setAdapter(suggestionsAdapter);
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
|
|
@ -126,6 +163,7 @@ public class MapFragment extends Fragment {
|
|||
String address = Helper.getStringFromInput(etSearchLocation);
|
||||
if (!address.isEmpty()) {
|
||||
searchLocationByAddress(address);
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -134,16 +172,106 @@ public class MapFragment extends Fragment {
|
|||
return false;
|
||||
});
|
||||
|
||||
// Add TextWatcher for search suggestions
|
||||
etSearchLocation.addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
// Cancel any pending searches
|
||||
if (searchRunnable != null) {
|
||||
searchHandler.removeCallbacks(searchRunnable);
|
||||
}
|
||||
|
||||
// If text is empty, hide suggestions
|
||||
if (s.length() == 0) {
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Delay search to avoid too many API calls while typing
|
||||
searchRunnable = () -> getSuggestions(s.toString());
|
||||
searchHandler.postDelayed(searchRunnable, 300);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
});
|
||||
|
||||
// Handle suggestion click
|
||||
lvSuggestions.setOnItemClickListener((parent, view, position, id) -> {
|
||||
String selectedAddress = suggestionsList.get(position);
|
||||
etSearchLocation.setText(selectedAddress);
|
||||
|
||||
// Get the corresponding Address object
|
||||
if (position < addressResults.size()) {
|
||||
Address address = addressResults.get(position);
|
||||
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
|
||||
|
||||
// Zoom to the selected location
|
||||
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, SEARCH_ZOOM));
|
||||
|
||||
// Find the closest place
|
||||
Place closestPlace = findClosestPlace(latLng);
|
||||
if (closestPlace != null) {
|
||||
// Show the place details in a bottom sheet
|
||||
showPlaceBottomSheet(closestPlace);
|
||||
}
|
||||
}
|
||||
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
});
|
||||
|
||||
// trigger on Enter/Done key
|
||||
etSearchLocation.setOnEditorActionListener((v, actionId, event) -> {
|
||||
String address = Helper.getStringFromInput(etSearchLocation);
|
||||
if (!address.isEmpty()) {
|
||||
searchLocationByAddress(address);
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void getSuggestions(String query) {
|
||||
if (query.length() < 3) {
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Clear previous results
|
||||
suggestionsList.clear();
|
||||
addressResults.clear();
|
||||
|
||||
// Get suggestions from Geocoder
|
||||
List<Address> addresses = geocoder.getFromLocationName(query, 5);
|
||||
if (addresses != null && !addresses.isEmpty()) {
|
||||
for (Address address : addresses) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i <= address.getMaxAddressLineIndex(); i++) {
|
||||
if (i > 0) sb.append(", ");
|
||||
sb.append(address.getAddressLine(i));
|
||||
}
|
||||
String addressText = sb.toString();
|
||||
suggestionsList.add(addressText);
|
||||
addressResults.add(address);
|
||||
}
|
||||
|
||||
suggestionsAdapter.notifyDataSetChanged();
|
||||
lvSuggestions.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error getting suggestions", e);
|
||||
lvSuggestions.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void initMap() {
|
||||
fetchAndShowAllPlaces();
|
||||
|
||||
|
|
@ -158,7 +286,7 @@ public class MapFragment extends Fragment {
|
|||
fusedLocationClient.getLastLocation().addOnSuccessListener(location -> {
|
||||
if (location != null) {
|
||||
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14f));
|
||||
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, DEFAULT_ZOOM));
|
||||
showNearbyPlaces(currentLatLng);
|
||||
}
|
||||
});
|
||||
|
|
@ -166,7 +294,7 @@ public class MapFragment extends Fragment {
|
|||
googleMap.setOnMapClickListener(latLng -> {
|
||||
Place existingPlace = getPlaceIfExists(latLng);
|
||||
if (existingPlace != null) {
|
||||
Helper.goTo(getContext(), PlaceDetailActivity.class, Constants.PLACE, existingPlace); //Navigate to PlaceDetailActivity if the place already exists
|
||||
showPlaceBottomSheet(existingPlace);
|
||||
return;
|
||||
} else {
|
||||
try {
|
||||
|
|
@ -193,7 +321,6 @@ public class MapFragment extends Fragment {
|
|||
placeEntity.setDescription(""); // Empty description
|
||||
placeEntity.setUuid(null); // No UUID for a new place
|
||||
Helper.goTo(getContext(), AddNewPlaceActivity.class, Constants.PLACE, placeEntity);
|
||||
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
|
|
@ -208,14 +335,12 @@ public class MapFragment extends Fragment {
|
|||
Place existingPlace = getPlaceIfExists(latLng);
|
||||
|
||||
if (existingPlace != null) {
|
||||
Helper.goTo(getContext(), PlaceDetailActivity.class, Constants.PLACE, existingPlace);
|
||||
showPlaceBottomSheet(existingPlace);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
requestPermissions(new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
|
||||
}
|
||||
|
|
@ -239,6 +364,39 @@ public class MapFragment extends Fragment {
|
|||
return null;
|
||||
}
|
||||
|
||||
private Place findClosestPlace(LatLng searchLatLng) {
|
||||
if (placeList.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Place closestPlace = null;
|
||||
float minDistance = Float.MAX_VALUE;
|
||||
float[] result = new float[1];
|
||||
|
||||
for (Place place : placeList) {
|
||||
double lat = Double.parseDouble(place.getLatitude());
|
||||
double lng = Double.parseDouble(place.getLongitude());
|
||||
|
||||
Location.distanceBetween(
|
||||
searchLatLng.latitude, searchLatLng.longitude,
|
||||
lat, lng,
|
||||
result);
|
||||
|
||||
if (result[0] < minDistance) {
|
||||
minDistance = result[0];
|
||||
closestPlace = place;
|
||||
}
|
||||
}
|
||||
|
||||
// Only return if within reasonable distance (1000 meters)
|
||||
return minDistance < 1000 ? closestPlace : null;
|
||||
}
|
||||
|
||||
private void showPlaceBottomSheet(Place place) {
|
||||
PlaceBottomSheetDialog bottomSheet = new PlaceBottomSheetDialog(place);
|
||||
bottomSheet.show(getChildFragmentManager(), "PlaceBottomSheet");
|
||||
}
|
||||
|
||||
private void showNearbyPlaces(LatLng latLng) {
|
||||
googleMap.clear();
|
||||
}
|
||||
|
|
@ -249,8 +407,17 @@ public class MapFragment extends Fragment {
|
|||
if (addresses != null && !addresses.isEmpty()) {
|
||||
Address location = addresses.get(0);
|
||||
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
|
||||
showNearbyPlaces(latLng);
|
||||
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, SEARCH_ZOOM));
|
||||
|
||||
// Find the closest place to the search result
|
||||
Place closestPlace = findClosestPlace(latLng);
|
||||
if (closestPlace != null) {
|
||||
// Show the place details in a bottom sheet
|
||||
showPlaceBottomSheet(closestPlace);
|
||||
} else {
|
||||
// No close places found
|
||||
Helper.makeSnackBar(rlMap, "No places found near this location");
|
||||
}
|
||||
} else {
|
||||
Helper.makeSnackBar(rlMap, "Location not found");
|
||||
}
|
||||
|
|
@ -294,6 +461,7 @@ public class MapFragment extends Fragment {
|
|||
private void fetchAndShowAllPlaces() {
|
||||
String token = "Bearer " + SharedPref.getAccessToken(context); // get saved token
|
||||
|
||||
// Using the new PlaceService through LocationApiClient
|
||||
PlaceService placeService = LocationApiClient.getInstance().getPlaceService();
|
||||
Call<ResponseBody> call = placeService.getAllPlaces(token);
|
||||
|
||||
|
|
@ -305,6 +473,9 @@ public class MapFragment extends Fragment {
|
|||
JSONObject jsonObject = new JSONObject(response.body().string());
|
||||
JSONArray placesArray = jsonObject.getJSONObject("_data").getJSONArray("places");
|
||||
|
||||
// Clear existing places
|
||||
placeList.clear();
|
||||
|
||||
for (int i = 0; i < placesArray.length(); i++) {
|
||||
JSONObject placeObj = placesArray.getJSONObject(i);
|
||||
String name = placeObj.getString("name");
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ package com.example.acloc.model;
|
|||
import java.io.Serializable;
|
||||
|
||||
public class Report implements Serializable {
|
||||
String uuid, fkUser, fkPlace, fkReportType, description, createdBy;
|
||||
String placeName, placeUuid;
|
||||
int reportRating;
|
||||
private String uuid, fkUser, fkPlace, fkReportType, description, created, createdBy;
|
||||
private String placeName, placeUuid;
|
||||
private int reportRating;
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
|
|
@ -46,7 +46,9 @@ public class Report implements Serializable {
|
|||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getCreationDate(){
|
||||
return created;
|
||||
}
|
||||
public String getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
|
@ -78,4 +80,7 @@ public class Report implements Serializable {
|
|||
public void setPlaceUuid(String placeUuid) {
|
||||
this.placeUuid = placeUuid;
|
||||
}
|
||||
public String getCreatedDate(){
|
||||
return created;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M12,8l-6,6 1.41,1.41L12,10.83l4.59,4.58L18,14z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<!-- Header section -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvPlaceName"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toStartOf="@+id/ivExpand"
|
||||
android:textColor="@android:color/black"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="Place Name" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivExpand"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_expand_less"
|
||||
android:contentDescription="@string/expand" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Address and description -->
|
||||
<TextView
|
||||
android:id="@+id/tvAddress"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textSize="16sp"
|
||||
tools:text="123 Main St, City, Country" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:textSize="14sp"
|
||||
tools:text="Description of the place" />
|
||||
|
||||
<!-- Action buttons -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivFavorite"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/ic_favorite_border"
|
||||
android:contentDescription="@string/Favorite" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivEdit"
|
||||
android:layout_width="36dp"
|
||||
android:layout_height="36dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_toEndOf="@id/ivFavorite"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/ic_edit"
|
||||
android:contentDescription="@string/edit" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatButton
|
||||
android:id="@+id/btnAddReport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="36dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@color/primaryColor_dark"
|
||||
android:textColor="@android:color/white"
|
||||
android:text="@string/Add_Report" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- Reports section -->
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="#DDDDDD" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/recent_reports" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvNoData"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/no_reports_yet"
|
||||
android:visibility="gone" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvReports"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
|
|
@ -4,8 +4,7 @@
|
|||
android:id="@+id/rlFavorite"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
tools:context=".fragment.FavoriteFragment">
|
||||
android:layout_marginTop="?attr/actionBarSize">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvFavorite"
|
||||
|
|
|
|||
|
|
@ -2,37 +2,53 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/rlMap"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/rlMap"
|
||||
android:layout_marginTop="?attr/actionBarSize"
|
||||
tools:context=".fragment.MapFragment">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tilSearch"
|
||||
android:padding="@dimen/content_padding"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:startIconDrawable="@drawable/ic_location">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/etSearchLocation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableEnd="@drawable/ic_search"
|
||||
android:hint="@string/Search_Place"
|
||||
android:importantForAutofill="no"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="textPersonName"
|
||||
android:drawableTint="?attr/colorOnBackground"/>
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
tools:context="com.example.acloc.fragments.MapFragment">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/mapFrame"
|
||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@+id/tilSearch" />
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tilSearchLocation"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:elevation="4dp"
|
||||
app:endIconMode="custom"
|
||||
app:endIconDrawable="@android:drawable/ic_menu_search"
|
||||
app:boxCornerRadiusBottomEnd="8dp"
|
||||
app:boxCornerRadiusBottomStart="8dp"
|
||||
app:boxCornerRadiusTopEnd="8dp"
|
||||
app:boxCornerRadiusTopStart="8dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/etSearchLocation"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/Search_Place"
|
||||
android:imeOptions="actionSearch"
|
||||
android:background="@color/primaryVariant_dark"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<!-- ListView for search suggestions -->
|
||||
<ListView
|
||||
android:id="@+id/lvSuggestions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/tilSearchLocation"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@color/primaryVariant_dark"
|
||||
android:elevation="4dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -1,91 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardCornerRadius="12dp"
|
||||
app:cardElevation="4dp"
|
||||
app:cardUseCompatPadding="true"
|
||||
app:strokeColor="?attr/colorPrimary"
|
||||
app:strokeWidth="2dp"
|
||||
tools:ignore="MissingConstraints">
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
app:cardElevation="2dp">
|
||||
|
||||
<!--Report rating-->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="3"
|
||||
android:textSize="14sp"
|
||||
tools:text="This is a report description that might be multiple lines long. It describes the accessibility features or issues at this location." />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="@dimen/content_padding"
|
||||
android:weightSum="2">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.6"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ivRating"
|
||||
android:layout_width="@dimen/small_image_icon_height"
|
||||
android:layout_height="@dimen/small_image_icon_height"
|
||||
android:contentDescription="rating"
|
||||
android:src="@drawable/ic_thumbs_up" />
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:src="@drawable/ic_thumbs_up"
|
||||
app:tint="@color/primaryColor_dark" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvRating"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/Rating_GOOD"
|
||||
android:textSize="12sp"
|
||||
android:textStyle="bold"
|
||||
android:gravity="center_horizontal"
|
||||
android:textColor="?attr/colorOnBackground"
|
||||
/>
|
||||
|
||||
tools:text="GOOD" />
|
||||
</LinearLayout>
|
||||
|
||||
<!--Report description-->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/small_padding"
|
||||
android:layout_weight="1.5"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="@dimen/small_padding"
|
||||
android:text="@string/Report_Description"
|
||||
android:textColor="?attr/colorPrimary"
|
||||
android:textSize="@dimen/textSizeInEditText"
|
||||
android:textStyle="bold"
|
||||
app:startIconDrawable="@drawable/ic_location" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/tvDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:hint="@string/Report_Description"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="textMultiLine"
|
||||
android:text="@string/Report_Description"
|
||||
android:textColor="@color/neutralGrey"
|
||||
android:textSize="@dimen/textSizeSmall"
|
||||
tools:ignore="HardcodedText" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
|
|
|||
Loading…
Reference in New Issue