diff --git a/app/build.gradle b/app/build.gradle index f08c0e7..7b3d5f8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,4 +1,5 @@ apply plugin: 'com.android.application' +apply plugin: "androidx.navigation.safeargs" android { compileSdkVersion 30 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2c95a1b..21fd20f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -42,17 +42,10 @@ android:name=".view.activity.MainActivity" android:windowSoftInputMode="adjustPan" /> - - - - \ No newline at end of file diff --git a/app/src/main/java/com/tip/lunchbox/view/activity/CollectionDetails.java b/app/src/main/java/com/tip/lunchbox/view/activity/CollectionDetails.java deleted file mode 100644 index 77ae4b0..0000000 --- a/app/src/main/java/com/tip/lunchbox/view/activity/CollectionDetails.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.tip.lunchbox.view.activity; - -import android.content.Intent; -import android.os.Bundle; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; - -import com.tip.lunchbox.databinding.ActivityCollectionDetailsBinding; -import com.tip.lunchbox.utilities.Constants; -import com.tip.lunchbox.view.adapter.RestaurantAdapter; -import com.tip.lunchbox.view.listeners.RecyclerTouchListener; -import com.tip.lunchbox.viewmodel.CollectionDetailsViewModel; - -public class CollectionDetails extends AppCompatActivity { - private ActivityCollectionDetailsBinding binding; - private CollectionDetailsViewModel viewModel; - private RestaurantAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - binding = ActivityCollectionDetailsBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); - setupRecyclerView(); - - viewModel = new ViewModelProvider(this).get(CollectionDetailsViewModel.class); - int collectionId = getIntent().getIntExtra(Constants.INTENT_COLLECTION_ID, 0); - String collectionName = getIntent().getStringExtra(Constants.INTENT_COLLECTION_NAME); - binding.appBarTvLocation.setText(collectionName); - viewModel.getSearchResponseLiveData(collectionId).observe(this, searchResponse -> - adapter.setData(searchResponse.getRestaurantContainers())); - } - - private void setupRecyclerView() { - adapter = new RestaurantAdapter(this); - binding.rvCollectionsDetails.setAdapter(adapter); - binding.rvCollectionsDetails.setLayoutManager(new LinearLayoutManager(this)); - - new RecyclerTouchListener(this, binding.rvCollectionsDetails, (view, position) -> { - Intent intent = new Intent(this, RestaurantDetails.class); - intent.putExtra(Constants.INTENT_RES_ID, adapter.getData().get(position) - .getRestaurant().getId()); - startActivity(intent); - }); - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tip/lunchbox/view/activity/MainActivity.java b/app/src/main/java/com/tip/lunchbox/view/activity/MainActivity.java index 8a114b4..2ee0bf1 100644 --- a/app/src/main/java/com/tip/lunchbox/view/activity/MainActivity.java +++ b/app/src/main/java/com/tip/lunchbox/view/activity/MainActivity.java @@ -1,9 +1,13 @@ package com.tip.lunchbox.view.activity; import android.os.Bundle; +import android.view.View; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; +import androidx.navigation.NavDestination; import androidx.navigation.Navigation; import androidx.navigation.ui.NavigationUI; @@ -24,6 +28,16 @@ protected void onCreate(Bundle savedInstanceState) { //Setting navController NavController navController = Navigation.findNavController(this, R.id.navigation_host_fragment); + navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() { + @Override + public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) { + if (destination.getId() == R.id.restaurantDetails || destination.getId() == R.id.collectionDetails){ + mainBinding.mainActivityBn.setVisibility(View.GONE); + } else { + mainBinding.mainActivityBn.setVisibility(View.VISIBLE); + } + } + }); NavigationUI.setupWithNavController(mainBinding.mainActivityBn, navController); } diff --git a/app/src/main/java/com/tip/lunchbox/view/fragment/CollectionDetails.java b/app/src/main/java/com/tip/lunchbox/view/fragment/CollectionDetails.java new file mode 100644 index 0000000..9837695 --- /dev/null +++ b/app/src/main/java/com/tip/lunchbox/view/fragment/CollectionDetails.java @@ -0,0 +1,57 @@ +package com.tip.lunchbox.view.fragment; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.fragment.NavHostFragment; +import androidx.recyclerview.widget.LinearLayoutManager; + +import com.tip.lunchbox.databinding.FragmentCollectionDetailsBinding; +import com.tip.lunchbox.view.adapter.RestaurantAdapter; +import com.tip.lunchbox.view.listeners.RecyclerTouchListener; +import com.tip.lunchbox.viewmodel.CollectionDetailsViewModel; + +import org.jetbrains.annotations.NotNull; + +public class CollectionDetails extends Fragment { + private FragmentCollectionDetailsBinding binding; + private CollectionDetailsViewModel viewModel; + private RestaurantAdapter adapter; + + @Override + public View onCreateView(@NotNull LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + binding = FragmentCollectionDetailsBinding.inflate(inflater, container, false); + setupRecyclerView(); + + viewModel = new ViewModelProvider(this).get(CollectionDetailsViewModel.class); + assert getArguments() != null; + int collectionId = CollectionDetailsArgs.fromBundle(getArguments()).getCollectionID(); + String collectionName = CollectionDetailsArgs.fromBundle(getArguments()).getCollectionName(); + binding.appBarTvLocation.setText(collectionName); + viewModel.getSearchResponseLiveData(collectionId).observe(getViewLifecycleOwner(), searchResponse -> + adapter.setData(searchResponse.getRestaurantContainers())); + return binding.getRoot(); + } + + private void setupRecyclerView() { + adapter = new RestaurantAdapter(requireContext()); + binding.rvCollectionsDetails.setAdapter(adapter); + binding.rvCollectionsDetails.setLayoutManager(new LinearLayoutManager(requireContext())); + + new RecyclerTouchListener(requireContext(), binding.rvCollectionsDetails, (view, position) -> { + CollectionDetailsDirections.ActionCollectionDetailsToRestaurantDetails action = + CollectionDetailsDirections.actionCollectionDetailsToRestaurantDetails( + Integer.parseInt(adapter.getData().get(position) + .getRestaurant().getId())); + + NavHostFragment.findNavController(this).navigate(action); + }); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tip/lunchbox/view/fragment/HomeFragment.java b/app/src/main/java/com/tip/lunchbox/view/fragment/HomeFragment.java index 72e0043..74805f1 100644 --- a/app/src/main/java/com/tip/lunchbox/view/fragment/HomeFragment.java +++ b/app/src/main/java/com/tip/lunchbox/view/fragment/HomeFragment.java @@ -1,7 +1,6 @@ package com.tip.lunchbox.view.fragment; import android.animation.Animator; -import android.content.Intent; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -28,8 +27,6 @@ import com.tip.lunchbox.model.CategoryContainer; import com.tip.lunchbox.model.Restaurant; import com.tip.lunchbox.model.RestaurantContainer; -import com.tip.lunchbox.utilities.Constants; -import com.tip.lunchbox.view.activity.RestaurantDetails; import com.tip.lunchbox.view.listeners.CategoryChangeListener; import com.tip.lunchbox.view.adapter.RestaurantAdapter; import com.tip.lunchbox.view.listeners.RecyclerTouchListener; @@ -39,7 +36,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.concurrent.TimeUnit; import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; @@ -74,10 +70,12 @@ public View onCreateView(@NotNull LayoutInflater inflater, adapter = new RestaurantAdapter(getActivity()); new RecyclerTouchListener(getActivity(), homeBinding.rvRestaurant, (view, position) -> { - Intent intent = new Intent(getContext(), RestaurantDetails.class); - intent.putExtra(Constants.INTENT_RES_ID, adapter.getData().get(position) - .getRestaurant().getId()); - requireActivity().startActivity(intent); + HomeFragmentDirections.ActionHomeFragmentToRestaurantDetails action = + HomeFragmentDirections.actionHomeFragmentToRestaurantDetails( + Integer.parseInt(adapter.getData().get(position) + .getRestaurant().getId())); + + NavHostFragment.findNavController(this).navigate(action); }); onError(); BottomSheetBehavior.from(homeBinding.nsvRestaurantList); @@ -181,8 +179,8 @@ public void onAnimationRepeat(Animator animation) { showData(); homeBinding.appBarTvLocation.setText(geoCodeResponse.getLocality().getTitle() - + ", " - + geoCodeResponse.getLocality().getCityName()); + + ", " + + geoCodeResponse.getLocality().getCityName()); setMapMarkers(geoCodeResponse.getNearbyRestaurantContainers()); } else { showErrorView(); diff --git a/app/src/main/java/com/tip/lunchbox/view/activity/RestaurantDetails.java b/app/src/main/java/com/tip/lunchbox/view/fragment/RestaurantDetails.java similarity index 74% rename from app/src/main/java/com/tip/lunchbox/view/activity/RestaurantDetails.java rename to app/src/main/java/com/tip/lunchbox/view/fragment/RestaurantDetails.java index ff03101..fabc0a7 100644 --- a/app/src/main/java/com/tip/lunchbox/view/activity/RestaurantDetails.java +++ b/app/src/main/java/com/tip/lunchbox/view/fragment/RestaurantDetails.java @@ -1,4 +1,4 @@ -package com.tip.lunchbox.view.activity; +package com.tip.lunchbox.view.fragment; import android.Manifest; import android.content.Intent; @@ -7,63 +7,71 @@ import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; import androidx.recyclerview.widget.LinearLayoutManager; import com.bumptech.glide.Glide; import com.tip.lunchbox.R; -import com.tip.lunchbox.databinding.ActivityRestaurantDetailsBinding; +import com.tip.lunchbox.databinding.FragmentRestaurantDetailsBinding; import com.tip.lunchbox.model.Restaurant; import com.tip.lunchbox.utilities.Constants; +import com.tip.lunchbox.view.activity.MenuActivity; import com.tip.lunchbox.view.adapter.HighlightsAdapter; import com.tip.lunchbox.view.adapter.PhoneNumberAdapter; import com.tip.lunchbox.view.listeners.RecyclerTouchListener; import com.tip.lunchbox.viewmodel.RestaurantDetailsViewModel; +import org.jetbrains.annotations.NotNull; + import java.util.Arrays; import java.util.List; -public class RestaurantDetails extends AppCompatActivity { +public class RestaurantDetails extends Fragment { private final int callerPermissionCode = 29; private RestaurantDetailsViewModel viewModel; - private ActivityRestaurantDetailsBinding binding; + private FragmentRestaurantDetailsBinding binding; private PhoneNumberAdapter phoneNumberAdapter; private HighlightsAdapter highlightsAdapter; private static final String TAG = "Restaurant Details"; @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - binding = ActivityRestaurantDetailsBinding.inflate(getLayoutInflater()); - setContentView(binding.getRoot()); + public View onCreateView(@NotNull LayoutInflater inflater, + ViewGroup container, + Bundle savedInstanceState) { + + binding = FragmentRestaurantDetailsBinding.inflate(inflater, container, false); viewModel = new ViewModelProvider(this).get(RestaurantDetailsViewModel.class); - String resId = getIntent().getStringExtra(Constants.INTENT_RES_ID); - assert resId != null; + int resId = RestaurantDetailsArgs.fromBundle(getArguments()).getResId(); // creating adapter instances - phoneNumberAdapter = new PhoneNumberAdapter(this); - highlightsAdapter = new HighlightsAdapter(this); + phoneNumberAdapter = new PhoneNumberAdapter(requireContext()); + highlightsAdapter = new HighlightsAdapter(requireContext()); setupRecyclerViews(); binding.appBar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> { if (Math.abs(verticalOffset) - appBarLayout.getTotalScrollRange() == 0) { // Collapsed State binding.fabMenu.show(); - binding.toolbar.setBackgroundColor(getColor(R.color.white)); - binding.toolbar.setTitleTextColor(getColor(R.color.colorPrimary)); + binding.toolbar.setBackgroundColor(requireActivity().getColor(R.color.white)); + binding.toolbar.setTitleTextColor(requireActivity() + .getColor(R.color.colorPrimary)); } else { // Expanded State binding.fabMenu.hide(); - binding.toolbar.setBackgroundColor(getColor(R.color.colorTransparent)); + binding.toolbar.setBackgroundColor(requireActivity() + .getColor(R.color.colorTransparent)); } }); - viewModel.getRestaurantLiveData(Integer.parseInt(resId)).observe(this, this::setData); + viewModel.getRestaurantLiveData(resId).observe(getViewLifecycleOwner(), this::setData); + return binding.getRoot(); } /** @@ -71,25 +79,25 @@ protected void onCreate(Bundle savedInstanceState) { * used in this activity. */ private void setupRecyclerViews() { - binding.rvPhoneNumber.setLayoutManager(new LinearLayoutManager(this)); + binding.rvPhoneNumber.setLayoutManager(new LinearLayoutManager(requireContext())); binding.rvPhoneNumber.setAdapter(phoneNumberAdapter); binding.rvHighlights.setLayoutManager(new LinearLayoutManager( - this, + requireContext(), LinearLayoutManager.HORIZONTAL, true)); binding.rvHighlights.setAdapter(highlightsAdapter); // Item click listener for phone number's recyclerview - new RecyclerTouchListener(this, binding.rvPhoneNumber, (view, position) -> { + new RecyclerTouchListener(requireContext(), binding.rvPhoneNumber, (view, position) -> { if (checkPermission()) { Intent callIntent = new Intent(Intent.ACTION_DIAL); callIntent.setData(Uri.parse("tel:" + phoneNumberAdapter.getData().get(position))); - if (callIntent.resolveActivity(getPackageManager()) != null) { + if (callIntent.resolveActivity(getActivity().getPackageManager()) != null) { startActivity(callIntent); } else { Toast.makeText( - this, + requireContext(), getString(R.string.dialer_app_not_found), Toast.LENGTH_LONG).show(); } @@ -101,13 +109,13 @@ private boolean checkPermission() { String callPermission = Manifest.permission.CALL_PHONE; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission( - this, callPermission) == PackageManager.PERMISSION_DENIED) { + requireContext(), callPermission) == PackageManager.PERMISSION_DENIED) { boolean showRationale = shouldShowRequestPermissionRationale(callPermission); if (showRationale) { requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, callerPermissionCode); } else { - Toast.makeText(this, R.string.permission_rationale_call, + Toast.makeText(requireContext(), R.string.permission_rationale_call, Toast.LENGTH_SHORT).show(); } } else { @@ -137,7 +145,7 @@ private void setData(Restaurant restaurant) { // onClickListener for opening up the MenuActivity binding.fabMenu.setOnClickListener( view -> { - Intent menuIntent = new Intent(this, MenuActivity.class); + Intent menuIntent = new Intent(requireContext(), MenuActivity.class); menuIntent.putExtra(Constants.INTENT_RESTAURANT_NAME, restaurant.getName()); menuIntent.putExtra(Constants.INTENT_MENU_URL, restaurant.getMenuUrl()); startActivity(menuIntent); @@ -163,15 +171,16 @@ private void getDirections(Restaurant restaurant) { restaurant.getName())); Intent mapIntent = new Intent(Intent.ACTION_VIEW); mapIntent.setData(url); - if (mapIntent.resolveActivity(getPackageManager()) != null) { + if (mapIntent.resolveActivity(getActivity().getPackageManager()) != null) { startActivity(mapIntent); } else { - Toast.makeText(this, getString(R.string.maps_not_found), Toast.LENGTH_LONG).show(); + Toast.makeText(requireContext(), getString(R.string.maps_not_found), Toast.LENGTH_LONG).show(); } } /** * This method is used to set a hardcoded review text based on the ratings fetched from APIs. + * * @param aggregateRating restaurant's rating fetched from the APIs. */ private void setOurReviewText(float aggregateRating) { diff --git a/app/src/main/java/com/tip/lunchbox/view/fragment/SearchFragment.java b/app/src/main/java/com/tip/lunchbox/view/fragment/SearchFragment.java index 6fceaf0..2cc2071 100644 --- a/app/src/main/java/com/tip/lunchbox/view/fragment/SearchFragment.java +++ b/app/src/main/java/com/tip/lunchbox/view/fragment/SearchFragment.java @@ -1,6 +1,5 @@ package com.tip.lunchbox.view.fragment; -import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.LayoutInflater; @@ -10,13 +9,11 @@ import androidx.appcompat.widget.SearchView; import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; +import androidx.navigation.fragment.NavHostFragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.PagerSnapHelper; import com.tip.lunchbox.databinding.FragmentSearchBinding; -import com.tip.lunchbox.utilities.Constants; -import com.tip.lunchbox.view.activity.CollectionDetails; -import com.tip.lunchbox.view.activity.RestaurantDetails; import com.tip.lunchbox.view.adapter.CollectionsAdapter; import com.tip.lunchbox.view.adapter.RestaurantAdapter; import com.tip.lunchbox.view.listeners.RecyclerTouchListener; @@ -87,21 +84,22 @@ public void setUpRecyclerViews() { // Setting up on item click action new RecyclerTouchListener(getActivity(), binding.rvSearch, (view, position) -> { - Intent intent = new Intent(getContext(), RestaurantDetails.class); - intent.putExtra(Constants.INTENT_RES_ID, searchAdapter.getData().get(position) + int resId = Integer.parseInt(searchAdapter.getData().get(position) .getRestaurant().getId()); - requireActivity().startActivity(intent); + SearchFragmentDirections.ActionSerachFragmentToRestaurantDetails action = + SearchFragmentDirections.actionSerachFragmentToRestaurantDetails(resId); + NavHostFragment.findNavController(this).navigate(action); }); new RecyclerTouchListener(getActivity(), binding.rvCollections, (view, position) -> { - Intent intent = new Intent(getActivity(), CollectionDetails.class); - intent.putExtra(Constants.INTENT_COLLECTION_ID, - collectionsAdapter.getData() - .get(position).getCollection().getCollectionId()); - - intent.putExtra(Constants.INTENT_COLLECTION_NAME, collectionsAdapter.getData() - .get(position).getCollection().getTitle()); - requireActivity().startActivity(intent); + int collectionId = collectionsAdapter.getData() + .get(position).getCollection().getCollectionId(); + String collectionName = collectionsAdapter.getData() + .get(position).getCollection().getTitle(); + SearchFragmentDirections.ActionSerachFragmentToCollectionDetails action = + SearchFragmentDirections + .actionSerachFragmentToCollectionDetails(collectionId, collectionName); + NavHostFragment.findNavController(this).navigate(action); }); } diff --git a/app/src/main/res/layout/activity_collection_details.xml b/app/src/main/res/layout/fragment_collection_details.xml similarity index 97% rename from app/src/main/res/layout/activity_collection_details.xml rename to app/src/main/res/layout/fragment_collection_details.xml index 45f3bb0..adc8551 100644 --- a/app/src/main/res/layout/activity_collection_details.xml +++ b/app/src/main/res/layout/fragment_collection_details.xml @@ -5,7 +5,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context=".view.activity.CollectionDetails"> + tools:context=".view.fragment.CollectionDetails"> + tools:context=".view.fragment.RestaurantDetails"> + tools:layout="@layout/fragment_home" > + + + tools:layout="@layout/fragment_search"> + + + + + + + + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2858e4d..36a32a2 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,8 @@ buildscript { jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.0.1" + classpath 'com.android.tools.build:gradle:4.1.0' + classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -46,7 +47,7 @@ ext { rx_android_version = '3.0.0' rx_java_version = '3.0.6' glide_version = '4.11.0' - navigation_version = '2.3.0' + navigation_version = '2.3.1' google_maps_version = '12.0.1' shimmer_loading_version = 'v1.3' lottie_version = '3.4.4' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2b210ec..bc82e4f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Aug 30 01:35:50 IST 2020 +#Fri Oct 30 12:50:49 IST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip