Issue
on this app, When I trying to navigate from "HomeFragment"
to "DetailsActivity"
then pressed back it's back to the same fragment and also the hamburger icon on click doesn't work
nav grpah
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="com.blogspot.abtallaldigital.ui.home.HomeFragment"
android:label="@string/home"
tools:layout="@layout/fragment_home"/>
<fragment
android:id="@+id/nav_Accessory"
android:name="com.blogspot.abtallaldigital.ui.accessory.AccessoryFragment"
android:label="@string/accessory"
tools:layout="@layout/fragment_accessory" />
<fragment
android:id="@+id/nav_Arcade"
android:name="com.blogspot.abtallaldigital.ui.arcade.ArcadeFragment"
android:label="@string/arcade"
tools:layout="@layout/fragment_arcade" />
<fragment
android:id="@+id/nav_Fashion"
android:name="com.blogspot.abtallaldigital.ui.fashion.FashionFragment"
android:label="@string/fashion"
tools:layout="@layout/fashion_fragment" />
<fragment
android:id="@+id/nav_Food"
android:name="com.blogspot.abtallaldigital.ui.food.FoodFragment"
android:label="@string/food"
tools:layout="@layout/food_fragment" />
<fragment
android:id="@+id/nav_Heath"
android:name="com.blogspot.abtallaldigital.ui.heath.HeathFragment"
android:label="@string/heath"
tools:layout="@layout/heath_fragment" />
<fragment
android:id="@+id/nav_Lifestyle"
android:name="com.blogspot.abtallaldigital.ui.lifestyle.LifestyleFragment"
android:label="@string/lifestyle"
tools:layout="@layout/lifestyle_fragment" />
<fragment
android:id="@+id/nav_Sports"
android:name="com.blogspot.abtallaldigital.ui.sports.SportsFragment"
android:label="@string/sports"
tools:layout="@layout/sports_fragment" />
<dialog
android:id="@+id/about"
android:name="com.blogspot.abtallaldigital.ui.about.AboutFragment"
android:label="about"
tools:layout="@layout/about" />
<activity
android:id="@+id/detailsActivity"
android:name="com.blogspot.abtallaldigital.ui.DetailsActivity"
android:label="activity_details"
tools:layout="@layout/activity_details" />
</navigation>
HomeFragment navigtion code
@Override
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.homeRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(requireContext(),
binding.homeRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Item item = itemArrayList.get(position);
bundle.putParcelable("item",item);
Navigation.findNavController(requireView())
.navigate(R.id.detailsActivity, bundle,
new NavOptions.Builder()
.setPopUpTo(R.id.nav_home, true).build()
);
}
@Override
public void onLongItemClick(View view, int position) {
}
}
));
}
DetailsActivity
@AndroidEntryPoint
public class DetailsActivity extends AppCompatActivity {
private static final String TAG = "DetailsActivity";
private ActivityDetailsBinding binding;
String url, title, content, youtubeThumbnailImageSrc, youTubeLink;
int youtubeThumbnailImageSetVisibility;
private PostViewModel postViewModel;
private Item postItem;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityDetailsBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
postViewModel = new ViewModelProvider(this).get(PostViewModel.class);
postItem = getIntent().getParcelableExtra("item");
if (postItem != null) {
Log.d(TAG, "onItemClick: item" + postItem.getTitle());
final Document document = Jsoup.parse(postItem.getContent());
// final Elements elements = document.select("img");
Element element = document.body();
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc == null) {
youtubeThumbnailImageSetVisibility = 8;
}
url = postItem.getUrl();
title = postItem.getTitle();
content = postItem.getContent();
}
// blogImage = (ImageView) findViewById(R.id.blogImage);
setSupportActionBar(binding.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
binding.progressBar.setVisibility(View.VISIBLE);
binding.titleTextView.setText(title);
binding.blogContent.setMovementMethod(LinkMovementMethod.getInstance());
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
binding.fab.bringToFront();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
// Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
if (scrollY > 0 && binding.fab.isShown()) {
binding.fab.hide();
} else if (scrollY < 22) {
binding.fab.show();
}
});
} else {
binding.scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
int mScrollY = binding.scrollView.getScrollY();
if (mScrollY > 0 && binding.fab.isShown()) {
binding.fab.hide();
} else if (mScrollY < 22) {
binding.fab.show();
}
});
}
binding.fab.setOnClickListener(view -> {
String shareContent = title + "\n" + url;
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, shareContent);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
try {
startActivity(Intent.createChooser(shareIntent, title));
} catch (Exception exception) {
Log.e(TAG, "onCreate: " + exception);
}
});
// String imageSrc = getIntent().getStringExtra("blogImage");
// Glide.with(getApplicationContext()).load(imageSrc).into(blogImage);
binding.youtubeThumbnailImage.setVisibility(youtubeThumbnailImageSetVisibility);
binding.youtubeThumbnailImage.setAdjustViewBounds(true);
Picasso.get().load(youtubeThumbnailImageSrc).into(binding.youtubeThumbnailImage);
binding.youtubeThumbnailImage.setOnClickListener(view -> {
Intent youTube = new Intent
(Intent.ACTION_VIEW, Uri.parse(youTubeLink));
startActivity(youTube);
});
PicassoImageGetter imageGetter = new PicassoImageGetter(binding.blogContent, this);
Spannable html;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
html = (Spannable) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY, imageGetter, null);
} else {
html = (Spannable) Html.fromHtml(content, imageGetter, null);
}
binding.blogContent.setText(html);
binding.visitSite.setOnClickListener(view -> openCustomTab(this, Uri.parse(url)));
binding.progressBar.setVisibility(View.GONE);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_details_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_add_to_favorites) {
saveTogFavorites(item);
} else if (item.getItemId() == R.id.action_share) {
ShareActionProvider shareActionProvider =
(ShareActionProvider) MenuItemCompat.getActionProvider(item);
shareActionProvider.setShareIntent(createShareIntent());
return true;
} else if (item.getItemId() == R.id.copyTheLink) {
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText("link", url);
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(this, getString(R.string.linkCopied), Toast.LENGTH_LONG).show();
return true;
}
return super.onOptionsItemSelected(item);
}
private void saveTogFavorites(MenuItem menuItem) {
// Bundle bundle = getIntent().getParcelableExtra("postList");
FavoritesEntity favoritesEntity = new FavoritesEntity(0,
postItem);
postViewModel.insertFavorites(favoritesEntity);
menuItem.setIcon(R.drawable.ic_favorite);
Snackbar.make(binding.getRoot(), "Saved", Snackbar.LENGTH_LONG).show();
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
MainActivity
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
@SuppressWarnings("unused")
private AppBarConfiguration mAppBarConfiguration;
public static Utils.DataStoreRepository DATA_STORE_REPOSITORY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
DATA_STORE_REPOSITORY = new Utils.DataStoreRepository(this);
setSupportActionBar(binding.appBarMain.toolbar);
mAppBarConfiguration = new AppBarConfiguration.Builder(R.id.nav_home, R.id.nav_Accessory,
R.id.nav_Arcade, R.id.nav_Fashion,
R.id.nav_Food, R.id.nav_Heath,
R.id.nav_Lifestyle, R.id.nav_Sports, R.id.about)
.setOpenableLayout(binding.drawerLayout)
.build();
NavHostFragment navHostFragment = (NavHostFragment)
getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
assert navHostFragment != null;
NavController navController = navHostFragment.getNavController();
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(binding.navView, navController);
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
}
While I searching for the solution of this issue, I saw the similar question and I use viewModel with MutableLiveData
but not to handle the events
Solution
Try this solution
- Create new fragment
DetailsFragment
and move your code fromDetailsActivity
to it,
Don't overrideonSupportNavigateUp
public class DetailsFragment extends Fragment {
private static final String TAG = "DetailsFragment";
private FragmentDetailsBinding binding;
String url, title, content, youtubeThumbnailImageSrc, youTubeLink;
int youtubeThumbnailImageSetVisibility;
private PostViewModel postViewModel;
@Override
public void onViewCreated(@NonNull @NotNull View view, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
postViewModel = new ViewModelProvider(this).get(PostViewModel.class);
Log.d(TAG, "onCreate checkSavedFavoritesItems: " + postFavoritesSavedId);
postItem = DetailsFragmentArgs.fromBundle(getArguments()).getPostItem();
final Document document = Jsoup.parse(postItem.getContent());
// final Elements elements = document.select("img");
Element element = document.body();
for (Element e : element.getElementsByClass
("YOUTUBE-iframe-video")) {
youtubeThumbnailImageSrc = e.attr("data-thumbnail-src");
youTubeLink = e.attr("src");
Log.e("YouTube thumbnail", youtubeThumbnailImageSrc);
Log.e("Youtube link", youTubeLink);
}
if (youtubeThumbnailImageSrc == null) {
youtubeThumbnailImageSetVisibility = 8;
}
url = postItem.getUrl();
title = postItem.getTitle();
content = postItem.getContent();
// blogImage = (ImageView) findViewById(R.id.blogImage);
setHasOptionsMenu(true);
// Objects.requireNonNull(getSupportActionBar()).setDisplayShowTitleEnabled(false);
Objects.requireNonNull( ((MainActivity) requireActivity())
.getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
// getSupportActionBar().setDisplayShowHomeEnabled(true);
binding.progressBar.setVisibility(View.VISIBLE);
binding.titleTextView.setText(title);
binding.blogContent.setMovementMethod(LinkMovementMethod.getInstance());
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
binding.fab.bringToFront();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
binding.scrollView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
// Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
if (scrollY > 0 && binding.fab.isShown()) {
binding.fab.hide();
} else if (scrollY < 22) {
binding.fab.show();
}
});
} else {
binding.scrollView.getViewTreeObserver().addOnScrollChangedListener(() -> {
int mScrollY = binding.scrollView.getScrollY();
if (mScrollY > 0 && binding.fab.isShown()) {
binding.fab.hide();
} else if (mScrollY < 22) {
binding.fab.show();
}
});
}
binding.fab.setOnClickListener(view2 -> {
String shareContent = title + "\n" + url;
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, shareContent);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
try {
startActivity(Intent.createChooser(shareIntent, title));
} catch (Exception exception) {
Log.e(TAG, "onCreate: " + exception);
}
});
// String imageSrc = getIntent().getStringExtra("blogImage");
// Glide.with(getApplicationContext()).load(imageSrc).into(blogImage);
binding.youtubeThumbnailImage.setVisibility(youtubeThumbnailImageSetVisibility);
binding.youtubeThumbnailImage.setAdjustViewBounds(true);
Picasso.get().load(youtubeThumbnailImageSrc).into(binding.youtubeThumbnailImage);
binding.youtubeThumbnailImage.setOnClickListener(view1 -> {
Intent youTube = new Intent
(Intent.ACTION_VIEW, Uri.parse(youTubeLink));
startActivity(youTube);
});
PicassoImageGetter imageGetter = new PicassoImageGetter(binding.blogContent, requireContext());
Spannable html;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
html = (Spannable) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY, imageGetter, null);
} else {
html = (Spannable) Html.fromHtml(content, imageGetter, null);
}
binding.blogContent.setText(html);
binding.visitSite.setOnClickListener(view3 -> openCustomTab(requireContext(), Uri.parse(url)));
binding.progressBar.setVisibility(View.GONE);
}
private Item postItem;
private boolean postFavoritesSaved = false;
private int postFavoritesSavedId = 0;
private MenuItem menuItem;
@Override
public View onCreateView(@NotNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentDetailsBinding.inflate(inflater, container, false);
return binding.getRoot();
}
@Override
public void onCreateOptionsMenu(@NonNull Menu menu,
@NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.activity_details_menu, menu);
menuItem = menu.findItem(R.id.action_add_to_favorites);
checkSavedFavoritesItems(menuItem);
}
@Override
public void onDestroyView() {
super.onDestroyView();
menuItem.setIcon(R.drawable.ic_favorite_border);
}
private void checkSavedFavoritesItems(MenuItem menuItem) {
postViewModel.getAllFavorites().observe(this, favoritesEntity -> {
try {
for (FavoritesEntity savedPost: favoritesEntity) {
if (savedPost.getItem().getId().equals(postItem.getId())) {
menuItem.setIcon(R.drawable.ic_favorite);
postFavoritesSavedId = savedPost.getId();
Log.d(TAG, "checkSavedFavoritesItems: " + postFavoritesSavedId);
postFavoritesSaved = true;
}
}
} catch (Exception exception) {
Log.e(TAG, "checkSavedFavoritesItems: " + exception.getMessage());
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
if (menuItem.getItemId() == R.id.action_add_to_favorites && !postFavoritesSaved) {
saveTogFavorites(menuItem);
} else if (menuItem.getItemId() == R.id.action_add_to_favorites && postFavoritesSaved) {
removePostFromFavorites(menuItem);
} else if (menuItem.getItemId() == R.id.action_share) {
ShareActionProvider shareActionProvider =
(ShareActionProvider) MenuItemCompat.getActionProvider(menuItem);
shareActionProvider.setShareIntent(createShareIntent());
return true;
} else if (menuItem.getItemId() == R.id.copyTheLink) {
ClipboardManager clipboardManager = (ClipboardManager)
requireActivity().getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clipData = ClipData.newPlainText("link", url);
assert clipboardManager != null;
clipboardManager.setPrimaryClip(clipData);
Toast.makeText(requireContext(), getString(R.string.linkCopied), Toast.LENGTH_LONG).show();
return true;
}
return super.onOptionsItemSelected(menuItem);
}
private void saveTogFavorites(MenuItem menuItem) {
FavoritesEntity favoritesEntity = new FavoritesEntity(0,
postItem);
postViewModel.insertFavorites(favoritesEntity);
menuItem.setIcon(R.drawable.ic_favorite);
Snackbar.make(binding.getRoot(), "Saved", Snackbar.LENGTH_LONG).show();
postFavoritesSaved = true;
}
private void removePostFromFavorites(MenuItem menuItem) {
FavoritesEntity favoritesEntity = new FavoritesEntity(postFavoritesSavedId,
postItem);
Log.d(TAG, "checkSavedFavoritesItems: " + postFavoritesSavedId);
postViewModel.deleteFavoritePost(favoritesEntity);
menuItem.setIcon(R.drawable.ic_favorite_border);
Snackbar.make(binding.getRoot(),
"Post deleted from favorites", Snackbar.LENGTH_LONG).show();
postFavoritesSaved = false;
}
- add
DetailsFragment
tonav_graph
and add argument to itpostItem
as Parcelable
<?xml version="1.0" encoding="utf-8"?>
<navigation 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/mobile_navigation"
app:startDestination="@id/nav_home">
<fragment
android:id="@+id/nav_home"
android:name="com.blogspot.abtallaldigital.ui.home.HomeFragment"
android:label="@string/home"
tools:layout="@layout/fragment_home">
<action
android:id="@+id/action_nav_home_to_detailsFragment"
app:destination="@id/detailsFragment"
app:popUpTo="@id/nav_home" />
</fragment>
<fragment
android:id="@+id/nav_Accessory"
android:name="com.blogspot.abtallaldigital.ui.accessory.AccessoryFragment"
android:label="@string/accessory"
tools:layout="@layout/fragment_accessory" >
<action
android:id="@+id/action_nav_Accessory_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Arcade"
android:name="com.blogspot.abtallaldigital.ui.arcade.ArcadeFragment"
android:label="@string/arcade"
tools:layout="@layout/fragment_arcade" >
<action
android:id="@+id/action_nav_Arcade_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Fashion"
android:name="com.blogspot.abtallaldigital.ui.fashion.FashionFragment"
android:label="@string/fashion"
tools:layout="@layout/fashion_fragment" >
<action
android:id="@+id/action_nav_Fashion_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Food"
android:name="com.blogspot.abtallaldigital.ui.food.FoodFragment"
android:label="@string/food"
tools:layout="@layout/food_fragment" >
<action
android:id="@+id/action_nav_Food_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Heath"
android:name="com.blogspot.abtallaldigital.ui.heath.HeathFragment"
android:label="@string/heath"
tools:layout="@layout/heath_fragment" >
<action
android:id="@+id/action_nav_Heath_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Lifestyle"
android:name="com.blogspot.abtallaldigital.ui.lifestyle.LifestyleFragment"
android:label="@string/lifestyle"
tools:layout="@layout/lifestyle_fragment" >
<action
android:id="@+id/action_nav_Lifestyle_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<fragment
android:id="@+id/nav_Sports"
android:name="com.blogspot.abtallaldigital.ui.sports.SportsFragment"
android:label="@string/sports"
tools:layout="@layout/sports_fragment" >
<action
android:id="@+id/action_nav_Sports_to_detailsFragment"
app:destination="@id/detailsFragment" />
</fragment>
<dialog
android:id="@+id/about"
android:name="com.blogspot.abtallaldigital.ui.about.AboutFragment"
android:label="about"
tools:layout="@layout/about" />
<fragment
android:id="@+id/detailsFragment"
android:name="com.blogspot.abtallaldigital.ui.DetailsFragment"
android:label="Post details"
tools:layout="@layout/fragment_details" >
<argument
android:name="postItem"
app:argType="com.blogspot.abtallaldigital.pojo.Item" />
</fragment>
</navigation>
- Finally in HomeFragment write the navigation code with pass the parcelable item like this
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
navController = Navigation.findNavController(requireView());
binding.homeRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(requireContext(),
binding.homeRecyclerView, new RecyclerItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Item item = itemArrayList.get(position);
if (Objects.requireNonNull(navController.getCurrentDestination()).getId() == R.id.nav_home) {
Navigation.findNavController(requireView())
.navigate(HomeFragmentDirections.actionNavHomeToDetailsFragment(item));
}
}
@Override
public void onLongItemClick(View view, int position) {
}
}
));
}
about the toolbars issue you can choose either use the fragment custom toolbar or use the app theme toolbar not both, please let me know if soultion working
Answered By - MML
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.