Convert ExploreFragment to kotlin

This commit is contained in:
Paul Hawke 2025-07-12 22:43:56 -05:00
parent 109c02b889
commit 77ee6e4161
4 changed files with 233 additions and 264 deletions

View file

@ -1,260 +0,0 @@
package fr.free.nrw.commons.explore;
import static androidx.viewpager.widget.ViewPager.SCROLL_STATE_IDLE;
import static fr.free.nrw.commons.ViewPagerAdapter.pairOf;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentPagerAdapter;
import androidx.viewpager.widget.ViewPager.OnPageChangeListener;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.ViewPagerAdapter;
import fr.free.nrw.commons.contributions.MainActivity;
import fr.free.nrw.commons.databinding.FragmentExploreBinding;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.theme.BaseActivity;
import fr.free.nrw.commons.utils.ActivityUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import javax.inject.Inject;
import javax.inject.Named;
import kotlin.Pair;
public class ExploreFragment extends CommonsDaggerSupportFragment {
private static final String FEATURED_IMAGES_CATEGORY = "Featured_pictures_on_Wikimedia_Commons";
private static final String MOBILE_UPLOADS_CATEGORY = "Uploaded_with_Mobile/Android";
private static final String EXPLORE_MAP = "Map";
private static final String MEDIA_DETAILS_FRAGMENT_TAG = "MediaDetailsFragment";
public FragmentExploreBinding binding;
ViewPagerAdapter viewPagerAdapter;
private ExploreListRootFragment featuredRootFragment;
private ExploreListRootFragment mobileRootFragment;
private ExploreMapRootFragment mapRootFragment;
@Inject
@Named("default_preferences")
public JsonKvStore applicationKvStore;
// Nearby map state (for if we came from Nearby fragment)
private double prevZoom;
private double prevLatitude;
private double prevLongitude;
public void setScroll(boolean canScroll) {
if (binding != null) {
binding.viewPager.setCanScroll(canScroll);
}
}
@NonNull
public static ExploreFragment newInstance() {
ExploreFragment fragment = new ExploreFragment();
fragment.setRetainInstance(true);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadNearbyMapData();
binding = FragmentExploreBinding.inflate(inflater, container, false);
viewPagerAdapter = new ViewPagerAdapter(requireContext(), getChildFragmentManager(),
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
binding.viewPager.setAdapter(viewPagerAdapter);
binding.viewPager.setId(R.id.viewPager);
binding.tabLayout.setupWithViewPager(binding.viewPager);
binding.viewPager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
if (position == 2) {
binding.viewPager.setCanScroll(false);
} else {
binding.viewPager.setCanScroll(true);
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
setTabs();
setHasOptionsMenu(true);
// if we came from 'Show in Explore' in Nearby, jump to Map tab
if (isCameFromNearbyMap()) {
binding.viewPager.setCurrentItem(2);
}
return binding.getRoot();
}
/**
* Sets the titles in the tabLayout and fragments in the viewPager
*/
public void setTabs() {
Bundle featuredArguments = new Bundle();
featuredArguments.putString("categoryName", FEATURED_IMAGES_CATEGORY);
Bundle mobileArguments = new Bundle();
mobileArguments.putString("categoryName", MOBILE_UPLOADS_CATEGORY);
Bundle mapArguments = new Bundle();
mapArguments.putString("categoryName", EXPLORE_MAP);
// if we came from 'Show in Explore' in Nearby, pass on zoom and center to Explore map root
if (isCameFromNearbyMap()) {
mapArguments.putDouble("prev_zoom", prevZoom);
mapArguments.putDouble("prev_latitude", prevLatitude);
mapArguments.putDouble("prev_longitude", prevLongitude);
}
featuredRootFragment = new ExploreListRootFragment(featuredArguments);
mobileRootFragment = new ExploreListRootFragment(mobileArguments);
mapRootFragment = new ExploreMapRootFragment(mapArguments);
((MainActivity) getActivity()).showTabs();
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPagerAdapter.setTabs(
pairOf(R.string.explore_tab_title_featured, featuredRootFragment),
pairOf(R.string.explore_tab_title_mobile, mobileRootFragment),
pairOf(R.string.explore_tab_title_map, mapRootFragment)
);
viewPagerAdapter.notifyDataSetChanged();
}
/**
* Fetch Nearby map camera data from fragment arguments if any.
*/
public void loadNearbyMapData() {
// get fragment arguments
if (getArguments() != null) {
prevZoom = getArguments().getDouble("prev_zoom");
prevLatitude = getArguments().getDouble("prev_latitude");
prevLongitude = getArguments().getDouble("prev_longitude");
}
}
/**
* Checks if fragment arguments contain data from Nearby map. if present, then the user
* navigated from Nearby using 'Show in Explore'.
*
* @return true if user navigated from Nearby map
**/
public boolean isCameFromNearbyMap() {
return prevZoom != 0.0 || prevLatitude != 0.0 || prevLongitude != 0.0;
}
public boolean onBackPressed() {
if (binding.tabLayout.getSelectedTabPosition() == 0) {
if (featuredRootFragment.backPressed()) {
((BaseActivity) getActivity()).getSupportActionBar()
.setDisplayHomeAsUpEnabled(false);
return true;
}
} else if (binding.tabLayout.getSelectedTabPosition() == 1) { //Mobile root fragment
if (mobileRootFragment.backPressed()) {
((BaseActivity) getActivity()).getSupportActionBar()
.setDisplayHomeAsUpEnabled(false);
return true;
}
} else { //explore map fragment
if (mapRootFragment.backPressed()) {
((BaseActivity) getActivity()).getSupportActionBar()
.setDisplayHomeAsUpEnabled(false);
return true;
}
}
return false;
}
/**
* This method inflates the menu in the toolbar
*/
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// if logged in 'Show in Nearby' menu item is visible
if (applicationKvStore.getBoolean("login_skipped") == false) {
inflater.inflate(R.menu.explore_fragment_menu, menu);
MenuItem others = menu.findItem(R.id.list_item_show_in_nearby);
if (binding.viewPager.getCurrentItem() == 2) {
others.setVisible(true);
}
// if on Map tab, show all menu options, else only show search
binding.viewPager.addOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
others.setVisible((position == 2));
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == SCROLL_STATE_IDLE && binding.viewPager.getCurrentItem() == 2) {
onPageSelected(2);
}
}
});
} else {
inflater.inflate(R.menu.menu_search, menu);
}
super.onCreateOptionsMenu(menu, inflater);
}
/**
* This method handles the logic on ItemSelect in toolbar menu Currently only 1 choice is
* available to open search page of the app
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_search:
ActivityUtils.startActivityWithFlags(getActivity(), SearchActivity.class);
return true;
case R.id.list_item_show_in_nearby:
mapRootFragment.loadNearbyMapFromExplore();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
}
}

View file

@ -0,0 +1,229 @@
package fr.free.nrw.commons.explore
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import androidx.viewpager.widget.ViewPager.OnPageChangeListener
import fr.free.nrw.commons.R
import fr.free.nrw.commons.ViewPagerAdapter
import fr.free.nrw.commons.contributions.MainActivity
import fr.free.nrw.commons.databinding.FragmentExploreBinding
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment
import fr.free.nrw.commons.kvstore.JsonKvStore
import fr.free.nrw.commons.theme.BaseActivity
import fr.free.nrw.commons.utils.ActivityUtils.startActivityWithFlags
import javax.inject.Inject
import javax.inject.Named
class ExploreFragment : CommonsDaggerSupportFragment() {
@JvmField
@Inject
@Named("default_preferences")
var applicationKvStore: JsonKvStore? = null
private var featuredRootFragment: ExploreListRootFragment? = null
private var mobileRootFragment: ExploreListRootFragment? = null
private var mapRootFragment: ExploreMapRootFragment? = null
private var prevZoom = 0.0
private var prevLatitude = 0.0
private var prevLongitude = 0.0
private var viewPagerAdapter: ViewPagerAdapter? = null
var binding: FragmentExploreBinding? = null
fun setScroll(canScroll: Boolean) {
if (binding != null) {
binding!!.viewPager.canScroll = canScroll
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
super.onCreate(savedInstanceState)
loadNearbyMapData()
binding = FragmentExploreBinding.inflate(inflater, container, false)
viewPagerAdapter = ViewPagerAdapter(
requireContext(), childFragmentManager,
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
)
binding!!.viewPager.adapter = viewPagerAdapter
binding!!.viewPager.id = R.id.viewPager
binding!!.tabLayout.setupWithViewPager(binding!!.viewPager)
binding!!.viewPager.addOnPageChangeListener(object : OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) = Unit
override fun onPageScrollStateChanged(state: Int) = Unit
override fun onPageSelected(position: Int) {
binding!!.viewPager.canScroll = position != 2
}
})
setTabs()
setHasOptionsMenu(true)
// if we came from 'Show in Explore' in Nearby, jump to Map tab
if (isCameFromNearbyMap) {
binding!!.viewPager.currentItem = 2
}
return binding!!.root
}
/**
* Sets the titles in the tabLayout and fragments in the viewPager
*/
fun setTabs() {
val featuredArguments = Bundle()
featuredArguments.putString("categoryName", FEATURED_IMAGES_CATEGORY)
val mobileArguments = Bundle()
mobileArguments.putString("categoryName", MOBILE_UPLOADS_CATEGORY)
val mapArguments = Bundle()
mapArguments.putString("categoryName", EXPLORE_MAP)
// if we came from 'Show in Explore' in Nearby, pass on zoom and center to Explore map root
if (isCameFromNearbyMap) {
mapArguments.putDouble("prev_zoom", prevZoom)
mapArguments.putDouble("prev_latitude", prevLatitude)
mapArguments.putDouble("prev_longitude", prevLongitude)
}
featuredRootFragment = ExploreListRootFragment(featuredArguments)
mobileRootFragment = ExploreListRootFragment(mobileArguments)
mapRootFragment = ExploreMapRootFragment(mapArguments)
(activity as MainActivity).showTabs()
(activity as BaseActivity).supportActionBar!!.setDisplayHomeAsUpEnabled(false)
viewPagerAdapter!!.setTabs(
R.string.explore_tab_title_featured to featuredRootFragment!!,
R.string.explore_tab_title_mobile to mobileRootFragment!!,
R.string.explore_tab_title_map to mapRootFragment!!
)
viewPagerAdapter!!.notifyDataSetChanged()
}
/**
* Fetch Nearby map camera data from fragment arguments if any.
*/
private fun loadNearbyMapData() {
// get fragment arguments
if (arguments != null) {
with (requireArguments()) {
prevZoom = getDouble("prev_zoom")
prevLatitude = getDouble("prev_latitude")
prevLongitude = getDouble("prev_longitude")
}
}
}
/**
* Checks if fragment arguments contain data from Nearby map. if present, then the user
* navigated from Nearby using 'Show in Explore'.
*
* @return true if user navigated from Nearby map
*/
private val isCameFromNearbyMap: Boolean
get() = prevZoom != 0.0 || prevLatitude != 0.0 || prevLongitude != 0.0
fun onBackPressed(): Boolean {
if (binding!!.tabLayout.selectedTabPosition == 0) {
if (featuredRootFragment!!.backPressed()) {
(activity as BaseActivity).supportActionBar!!.setDisplayHomeAsUpEnabled(false)
return true
}
} else if (binding!!.tabLayout.selectedTabPosition == 1) { //Mobile root fragment
if (mobileRootFragment!!.backPressed()) {
(activity as BaseActivity).supportActionBar!!.setDisplayHomeAsUpEnabled(false)
return true
}
} else { //explore map fragment
if (mapRootFragment!!.backPressed()) {
(activity as BaseActivity).supportActionBar!!.setDisplayHomeAsUpEnabled(false)
return true
}
}
return false
}
/**
* This method inflates the menu in the toolbar
*/
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
// if logged in 'Show in Nearby' menu item is visible
if (applicationKvStore!!.getBoolean("login_skipped") == false) {
inflater.inflate(R.menu.explore_fragment_menu, menu)
val others = menu.findItem(R.id.list_item_show_in_nearby)
if (binding!!.viewPager.currentItem == 2) {
others.setVisible(true)
}
// if on Map tab, show all menu options, else only show search
binding!!.viewPager.addOnPageChangeListener(object : OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) = Unit
override fun onPageSelected(position: Int) {
others.setVisible((position == 2))
}
override fun onPageScrollStateChanged(state: Int) {
if (state == ViewPager.SCROLL_STATE_IDLE && binding!!.viewPager.currentItem == 2) {
onPageSelected(2)
}
}
})
} else {
inflater.inflate(R.menu.menu_search, menu)
}
super.onCreateOptionsMenu(menu, inflater)
}
/**
* This method handles the logic on ItemSelect in toolbar menu Currently only 1 choice is
* available to open search page of the app
*/
override fun onOptionsItemSelected(item: MenuItem): Boolean {
// Handle item selection
when (item.itemId) {
R.id.action_search -> {
startActivityWithFlags(requireActivity(), SearchActivity::class.java)
return true
}
R.id.list_item_show_in_nearby -> {
mapRootFragment!!.loadNearbyMapFromExplore()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
override fun onDestroy() {
super.onDestroy()
binding = null
}
companion object {
private const val FEATURED_IMAGES_CATEGORY = "Featured_pictures_on_Wikimedia_Commons"
private const val MOBILE_UPLOADS_CATEGORY = "Uploaded_with_Mobile/Android"
private const val EXPLORE_MAP = "Map"
fun newInstance(): ExploreFragment = ExploreFragment().apply {
retainInstance = true
}
}
}

View file

@ -98,7 +98,7 @@ class ExploreListRootFragment : CommonsDaggerSupportFragment, MediaDetailProvide
binding!!.exploreContainer.visibility = View.VISIBLE
}
if ((parentFragment as ExploreFragment).binding != null) {
(parentFragment as ExploreFragment).binding.tabLayout.visibility =
(parentFragment as ExploreFragment).binding!!.tabLayout.visibility =
View.GONE
}
mediaDetails = MediaDetailPagerFragment.newInstance(false, true)
@ -155,7 +155,7 @@ class ExploreListRootFragment : CommonsDaggerSupportFragment, MediaDetailProvide
fun backPressed(): Boolean {
if (null != mediaDetails && mediaDetails!!.isVisible) {
if ((parentFragment as ExploreFragment).binding != null) {
(parentFragment as ExploreFragment).binding.tabLayout.visibility =
(parentFragment as ExploreFragment).binding!!.tabLayout.visibility =
View.VISIBLE
}
removeFragment(mediaDetails!!)

View file

@ -109,7 +109,7 @@ class ExploreMapRootFragment : CommonsDaggerSupportFragment, MediaDetailProvider
override fun onMediaClicked(position: Int) {
binding!!.exploreContainer.visibility = View.VISIBLE
(parentFragment as ExploreFragment).binding.tabLayout.visibility = View.GONE
(parentFragment as ExploreFragment).binding!!.tabLayout.visibility = View.GONE
mediaDetails = MediaDetailPagerFragment.newInstance(false, true)
(parentFragment as ExploreFragment).setScroll(false)
setFragment(mediaDetails!!, mapFragment)
@ -173,7 +173,7 @@ class ExploreMapRootFragment : CommonsDaggerSupportFragment, MediaDetailProvider
*/
fun backPressed(): Boolean {
if (null != mediaDetails && mediaDetails!!.isVisible) {
(parentFragment as ExploreFragment).binding.tabLayout.visibility = View.VISIBLE
(parentFragment as ExploreFragment).binding!!.tabLayout.visibility = View.VISIBLE
removeFragment(mediaDetails!!)
(parentFragment as ExploreFragment).setScroll(true)
setFragment(mapFragment!!, mediaDetails)