Android flip animation flashes after orientation change - android

I'm working on a flashcard like app and i've been wrestling with the flip animation. I've based my code on the AnimationsDemo from android with the difference being that it is done inside a fragment instead of an activity.
It works fine, not entirely as the preview of the aforementioned demo, but decent enough. Except... after changing orientation.
If the app is started in landscape, it works fine in landscape, but freaks in portrait and if the app is launched in portrait it works in portrait and freaks in landscape.
This is my code ( i skimmed the datamodel obviously)
public class MyFlashCardFragment extends Fragment {
private MyDataModel model;
private Handler mHandler = new Handler();
private boolean mShowingBack = false;
FrameLayout frameLayout;
public static MyFlashCardFragment create(MyDataModel m) {
MyFlashCardFragment fragment = new MyFlashCardFragment();
Bundle bundle = new Bundle();
bundle.putString(AppKeys.FRONT_KEY,m.getFrontText());
bundle.putString(AppKeys.BACK_KEY,m.getBackText());
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!getArguments().isEmpty()) {
model = new MyDataModel();
model.setFrontText(getArguments().getString(AppKeys.FRONT_KEY));
model.setBackText(getArguments().getString(AppKeys.BACK_KEY));
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
if (model == null) {
return super.onCreateView(inflater, container, savedInstanceState);
} else {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_flashcard, container, false);
frameLayout = (FrameLayout) root.findViewById(R.id.chilfd_frame);
Button btn_overlay = (Button) root.findViewById(R.id.overlaybutton);
btn_overlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flipCard();
}
});
return root;
}
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if(savedInstanceState == null) {
getChildFragmentManager()
.beginTransaction()
.add(R.id.chilfd_frame, CardFrontFragment.create(model.getFrontText()))
.commit();
} else {
mShowingBack = (getChildFragmentManager().getBackStackEntryCount() > 0);
}
getChildFragmentManager().addOnBackStackChangedListener(new android.app.FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
mShowingBack = (getChildFragmentManager().getBackStackEntryCount() > 0);
getActivity().invalidateOptionsMenu();
}
});
}
private void flipCard() {
if (mShowingBack) {
getChildFragmentManager().popBackStack();
return;
}
mShowingBack = true;
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(frameLayout.getId(), CardBackFragment.create(model.getBackText()))
.addToBackStack(null)
.commit();
mHandler.post(new Runnable() {
#Override
public void run() {
getActivity().invalidateOptionsMenu();
}
});
}
/**
* A fragment representing the front of the card.
*/
public static class CardFrontFragment extends Fragment {
String frontText;
public static CardFrontFragment create(String frontText) {
CardFrontFragment fragment = new CardFrontFragment();
Bundle bundle = new Bundle();
bundle.putString(AppKeys.FRONT_KEY,frontText);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!getArguments().isEmpty()) {
frontText = getArguments().getString(AppKeys.FRONT_KEY);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (TextUtils.isEmpty(frontText)) {
return super.onCreateView(inflater, container, savedInstanceState);
} else {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_flashcard_front, container, false);
((TextView) rootView.findViewById(R.id.tv_name)).setText(frontText);
return rootView;
}
}
}
/**
* A fragment representing the back of the card.
*/
public static class CardBackFragment extends Fragment {
String backText;
public static CardBackFragment create(String backText) {
CardBackFragment fragment = new CardBackFragment();
Bundle bundle = new Bundle();
bundle.putString(AppKeys.BACK_KEY,backText);
fragment.setArguments(bundle);
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!getArguments().isEmpty()) {
backText = getArguments().getString(AppKeys.BACK_KEY);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (TextUtils.isEmpty(backText)) {
return super.onCreateView(inflater, container, savedInstanceState);
} else {
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_flashcard_back, container, false);
((TextView) rootView.findViewById(R.id.tv_name)).setText(backText);
return rootView;
}
}
}
}
The parentfragment is loaded form a viewpager:
pager = (ViewPager) findViewById(R.id.pager);
adapter = new FlashCardPageAdapter(getFragmentManager(), getAllFrom(ref));
pager.setAdapter(adapter);
pager.setCurrentItem(position,true);
pager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
invalidateOptionsMenu();
}
});
and the adapter used is:
public class FlashCardPageAdapter extends FragmentStatePagerAdapter {
private ArrayList<MyDataModel> Models;
public FlashCardPageAdapter(FragmentManager fm, ArrayList<MyDataModel> list) {
super(fm);
this.Models = list;
}
#Override
public Fragment getItem(int position) {
return FlashCardFragment.create(Models.get(position));
}
#Override
public int getCount() {
return Models.size();
}
}
I also tried to create the animations form an Animator object and add that to a transparent button and animating views in and out and toggling the visibility and the result is the same.
Any ideas/suggestions would be welcome.

It turns out there's nothing missing in my code and the problem is emulator related. Well at least it seems that way. I tried it on 2 real devices (1 phone/1 tablet) and the problem didn't manifest on them, so might be an AVD bug or simple shortcoming of the simulated orientation change.

Related

Replacing Fragment inside ViewPager from Fragment RecycerView Adapter Return Blank Screen?

I am trying to replace the current active fragment inside ViewPager when item inside fragment's recycelerview is clicked. So far, I manage to pop up the Toast on the second fragment when the item on the first fragment is clicked, but the all the view of the second fragment is blank.
Here is my code:
MainActivity.class
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
viewPager = findViewById(R.id.view_pager);
FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(adapter.getCount() - 1);
}
// ..........
private static class FragmentAdapter extends FragmentStatePagerAdapter {
public FragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return AllGenreFragment.newInstance();
case 1:
return DashboardFragment.newInstance();
case 2:
return NotificationFragment.newInstance();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
// ..........
}
AllGenreFragment.class
public class AllGenreFragment extends Fragment {
RecyclerView genreRV;
private AllGenreAdapter allGenreAdapter;
private List<Genre> genreList;
public static AllGenreFragment newInstance() {
return new AllGenreFragment();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_genre, container, false);
genreRV = v.findViewById(R.id.rv);
genreRV.setHasFixedSize(true);
GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 2);
genreRV.setLayoutManager(layoutManager);
genreList = new ArrayList<>();
allGenreAdapter = new AllGenreAdapter(genreList, getContext());
genreRV.setAdapter(allGenreAdapter);
return v;
}
}
AllGenreAdapter.class
public class AllGenreAdapter extends RecyclerView.Adapter<AllGenreAdapter.ViewHolder> {
// .......
class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder {
public ViewHolder(final View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Genre: " + genre_title.getText().toString(), Toast.LENGTH_SHORT).show();
AppCompatActivity activity = (AppCompatActivity) itemView.getContext();
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment allAnimeFragment = new AllAnimeFragment();
Bundle bundle = new Bundle();
bundle.putString("genreid", genre_id.getText().toString().trim());
allAnimeFragment.setArguments(bundle);
fragmentTransaction.replace(R.id.view_pager, allAnimeFragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
}
// .......
}
AllAnimeFragment.class
public class AllAnimeFragment extends Fragment {
RecyclerView animeRV;
private AllAnimeAdapter allAnimeAdapter;
private List<Anime> animeList;
String genreid;
public static AllAnimeFragment newInstance() {
return new AllAnimeFragment();
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_anime, container, false);
Bundle arguments = getArguments();
genreid = arguments.getString("genreid");
Toast.makeText(getContext(), genreid, Toast.LENGTH_SHORT).show();
// .....
return v;
}
}
Your approach is not really good, try below way:
Create a container fragment, called ContainerFragment, example, you will be using this fragment for your ViewPager.
The ContainerFragment should contain a container view, and add AllGenreFragment in the first them it is invoked.
In AllGenreFragment, create a callback, when an item in the RecyclerView be clicked, then in ContainerFragment will replace (or add) current fragment (AllGenreFragment) to AllAnimeFragment
First, create ContainerFragment,
public class ContainerFragment extends Fragment implements AllGenreFragment.OnAllGenreFragmentListener {
#Nullable #Override public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_container, container, false);
}
#Override public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initialLoad();
}
private void initialLoad() {
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, AllGenreFragment.newInstance())
.commit();
}
#Override public void onItemClicked() {
getChildFragmentManager()
.beginTransaction()
.replace(R.id.container, AllAnimeFragment.newInstance())
.commit();
}
}
This Fragment should implement a callback from AllGenreFragment for handling fragment transaction.
also, the xml layout
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Next step, add above fragment into ViewPager, we using ContainerFragment instead of AllGenreFragment.
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return ContainerFragment().newInstance();
case 1:
return DashboardFragment.newInstance();
case 2:
return NotificationFragment.newInstance();
}
return null;
}
Ok, so now come back to AllGenreFragment, we should create a CallBack that we implement in ContainerFragment
public interface AllGenreFragmentListener {
onItemClicked();
}
and then,
private AllGenreFragmentListener listener;
#Override public void onAttach(Context context) {
super.onAttach(context);
if (getParentFragment() instanceof AllGenreFragmentListener) {
listener = (AllGenreFragmentListener) getParentFragment();
}
}
so we have an instance of AllGenreFragmentListener, from now, whenever listener call onItemClicked, the method onItemClicked in ContainerFragment will be invoked.
Ok, let do it,
create below variable and method in your AllGenreAdapter:
private AllGenreFragmentListener listener;
public void setListener(AllGenreFragmentListener listener) {
this.listener = listener;
}
and update your ViewHodler
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "Genre: " + genre_title.getText().toString(), Toast.LENGTH_SHORT).show();
if (listener != null)
listener.onItemClicked()
});
}
Don't forget call setListener method in your AllGenreFragment, so please add
#Override public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (allGenreAdapter != null) allGenreAdapter.setListener(listener);
}
That all,
I type this code by hand, not in my IDE so maybe it not compile, so please fix it if you face any compile error.
Note
If you want to keep the behavior of the BACK button, override onBackPressed in your MainActivity
#Override public void onBackPressed() {
Fragment f = getCurrentFragment();
if (f != null) {
if (f.getChildFragmentManager().getBackStackEntryCount() > 1) {
f.getChildFragmentManager().popBackStack();
} else {
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
public Fragment getCurrentFragment() {
return (Fragment) viewPager.getAdapter()
.instantiateItem(viewPager, viewPager.getCurrentItem());
}
Also, add fragment into backStack whenever we add them to the container view (in your ContainerFragment)
private void initialLoad() {
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, AllGenreFragment.newInstance())
.addToBackStack(null)
.commit();
}
#Override public void onItemClicked() {
// change `replace` to `add` and add more `.addToBackStack(null)`
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, AllAnimeFragment.newInstance())
.addToBackStack(null)
.commit();
}
you should add a context in the constructor of your adapter
public class AllGenreAdapter(Context context) extends RecyclerView.Adapter<AllGenreAdapter.ViewHolder> {
// .......
}
then pass your activity to your adapter, use it to replace your fragment

Fragments in ViewPager is not displayer after popBackStack

I have problem: A Fragment is not reattached to its hosting ViewPager after returning from another fragment by using popBackStack.
One Activity hosting a Fragment whose layout holds a ViewPager. The ViewPager is populated by a FragmentStateViewPagerAdapter. The Fragment hosted inside the pager can open sub page lists, containing a new set of pages. All works fine as long as the back button is not pressed. As soon as the user closes one of the sub Page the previous Page is recreated, but without the Page that was displayed previously (Empty page with whiteblank page). I have searching but still not resolve my problem.
Full Code of TestProject can be found on Github
MainActivity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val ft = supportFragmentManager.beginTransaction()
ft.add(R.id.frameLayout, HomeFragment.newInstance())
ft.commit()
}
}
HomeFragment:
public class HomeFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
TabLayout tabLayout = v.findViewById(R.id.tabLayout);
ViewPager viewPager = v.findViewById(R.id.viewPager);
VPAdapter adapter = new VPAdapter(getFragmentManager());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
return v;
}
public static Fragment newInstance() {
return new HomeFragment();
}
}
VPAdapter:
public class VPAdapter extends FragmentStatePagerAdapter{
public VPAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return TabFragment.newInstance(position);
}
#Override
public CharSequence getPageTitle(int position) {
return "TAB " + position;
}
#Override
public int getCount() {
return 2;
}
}
TabFragment:
public class TabFragment extends Fragment {
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TAB", "onCreate");
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.e("TAB", "onCreateView");
return inflater.inflate(R.layout.fragment_tab, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bundle args = getArguments();
if (args != null) {
int tabIndex = args.getInt("tab_index", 0);
TextView tv = view.findViewById(R.id.textView);
tv.setText(String.format(Locale.getDefault(), "TAB FRAGMENT INDEX %d", tabIndex));
}
Button button = view.findViewById(R.id.button);
button.setText("Open Next Fragment");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frameLayout, LastFragment.newInstance());
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("TAB", "onDestroy");
}
public static Fragment newInstance(int index) {
Bundle args = new Bundle();
args.putInt("tab_index", index);
TabFragment tab = new TabFragment();
tab.setArguments(args);
return tab;
}
}
LastFragment:
public class LastFragment extends Fragment {
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_last, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
getFragmentManager().popBackStack();
}
});
}
public static Fragment newInstance() {
return new LastFragment();
}
}
You have to Use getChildFragmentManager() For Viewpager to adapt Popback Feature.
VPAdapter adapter = new VPAdapter(getChildFragmentManager());
You Can Refer this Documentation on ChildFragmentManager()

Fragments and OnBackPressed

I'm using one Activity as container for fragments.
There is a problem:
If you open the ProfileEditFragment and press on the back button, then successfully call a method onBackPressed() in MainActivity and then happens next:
1)Open MapFragments past state
2)Open ProfileEditFragment from which we have pressed the back button(for unknown reasons)
I'm tried to use getSupportFragmentManager().popBackStack()but it did not help (there was no reaction to the press back).
I check the contents of the stack before the call onBackPressed() and it's not empty.
MainActivity:
#Override
public void showMapFragment() {
// getSupportFragmentManager().popBackStack(null,getSupportFragmentManager().POP_BACK_STACK_INCLUSIVE);
//mainPresenter.clearActiveLoginFragment();
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.ltContainer, MapFragment.newInstance())
.addToBackStack(null)
.commit();
}
#Override
public void showProfileEditFragment() {
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.ltContainer, ProfileEditFragment.newInstance())
.addToBackStack(null)
.commit()
;
}
#Override
public void onMainBackStack() {
int count = getSupportFragmentManager().getBackStackEntryCount();
Log.d("COunt in backstack", count + "");
// getSupportFragmentManager().popBackStack();
// Log.d("COunt in backstack",getSupportFragmentManager().popBackStackImmediate()
// +"");
// getSupportFragmentManager().popBackStack();
// getSupportFragmentManager().popBackStackImmediate();
super.onBackPressed();
}
ProfileEditFragment
private static final int LAYOUT = R.layout.fragment_profile_edit;
//#formatter:off
#InjectPresenter ProfileEditPresenter mProfileEditPresenter;
//#formatter:on
public static ProfileEditFragment newInstance() {
ProfileEditFragment fragment = new ProfileEditFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
View view=inflater.inflate(LAYOUT, container, false);
ButterKnife.bind(this,view);
return view;
}
#Override
public void onViewCreated(final View view, final Bundle savedInstanceState){
super.onViewCreated(view, savedInstanceState);
}
MapFragment
//#formatter:off
#InjectPresenter MapPresenter mapPresenter;
#BindView(R.id.map) ru.yandex.yandexmapkit.MapView mapView;
#BindView(R.id.fbMenu) FloatingActionButton fbMenu;
//#formatter:on
private MapController mapController; //// FIXME: 11.11.2016
public static MapFragment newInstance() {
MapFragment fragment = new MapFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
View view = inflater.inflate(LAYOUT, container, false);
ButterKnife.bind(this, view);
setupMap();
showMapButtons();
mapPresenter.checkPermission();
setupListeners();
return view;
}
private void setupListeners() {
fbMenu.setOnClickListener(v->mapPresenter.onClickMenu());
}
private void setupMap() {
mapController = mapView.getMapController();
mapController.getMapRotator().a(true);
}
#Override
public void showMapButtons() {
mapView.showZoomButtons(true);
mapView.showScaleView(false);
mapView.showJamsButton(false);
}
#Override
public void showProfileEditFragment() {
((MainActivity) getActivity()).showProfileEditFragment();
}

get fragment width, viewtreeobserver listener not working

I have a fragment that can be in a details activity (if the device has a small viewport) or on the main activity (if the viewport is big, e.g. a tablet).
Inside of the fragment there is an ImageView that I need to resize according to the width of the fragment. I did some research and I found out that the "canonical" way to achieve this is to add a listener to the viewtreeobserver. However, for some reason, it is not working:
This is my Fragment:
public class MediaDetailFragment extends Fragment implements DetailsMvpView {
private static final String RESOURCE = "resource";
#Inject DetailPresenter mPresenter;
#BindView(R.id.media_image_flipper)
ViewFlipper mImageFlipper;
#BindView(R.id.title_textview)
TextView mTitleTextView;
#BindView(R.id.button_share)
ImageButton mShare;
#BindView(R.id.button_trailers) ImageButton mTrailers;
#BindView(R.id.keyword_recyclerview)
RecyclerView mKeywordRecyclerView;
#BindView(R.id.overview_content_textview) TextView mOverviewTextView;
#BindView(R.id.main_image_holder) ViewGroup mImageHolder;
#BindView(R.id.parent_cardview)
CardView mParentCardView;
#BindString(R.string.youtube_base_url) String mYoutubeUrl;
#BindBool(R.bool.isTablet) boolean mIsTablet;
private Media mMedia;
private DisplayMetrics mDisplayMetrics = new DisplayMetrics();
public static MediaDetailFragment insertOnTarget(AppCompatActivity activity, int target, Media media) {
MediaDetailFragment fragment = MediaDetailFragment.instantiateWithArguments(media);
FragmentManager fm = activity.getSupportFragmentManager();
fm.beginTransaction()
.replace(target, fragment)
.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right)
.commit();
return fragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMedia = getArguments().getParcelable(RESOURCE);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.media_details_fragment, container, false);
((BaseActivity)getActivity()).activityComponent().inject(this);
ButterKnife.bind(this, rootView);
getActivity().getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);
mTitleTextView.setText(mMedia.title());
mOverviewTextView.setText(mMedia.overview());
mKeywordRecyclerView.setAdapter(new KeywordAdapter(getContext()));
return rootView;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
if (view == null) return;
view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
if (mIsTablet) {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(view.getWidth(), ViewUtil.PORTRAIT);
} else {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.PORTRAIT);
}
});
}
#Override
public void onStart() {
super.onStart();
mShare.setOnClickListener(v -> {startActivity(new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_TEXT, String.format(mYoutubeUrl, mMedia.overview())));});
mTrailers.setOnClickListener(v -> mPresenter.loadMovies(mMedia.id()));
mPresenter.attachView(this);
mPresenter.loadImages(mMedia.id());
mPresenter.loadKeywords(mMedia.id());
}
#Override
public void onStop() {
mPresenter.detachView();
super.onStop();
}
#Override
public void showImages(String images) {
ImageView imageView = new ImageView(getContext());
ViewUtil.loadImage(images, imageView, getContext(), true, true);
mImageFlipper.addView(imageView, new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
#Override
public void showKeywords(List<String> keywords) {
((KeywordAdapter) mKeywordRecyclerView.getAdapter()).setKeywords(keywords);
}
#Override
public void showVideos(List<Video> videos) {
TrailerDialogFragment.newInstance(videos).show(getFragmentManager(), null);
}
#Override
public void showError() {
}
private static MediaDetailFragment instantiateWithArguments(Media media) {
Bundle bundle = new Bundle();
bundle.putParcelable(RESOURCE, media);
MediaDetailFragment fragment = new MediaDetailFragment();
fragment.setArguments(bundle);
return fragment;
}
}
I call attach the listener on the onactivitycreated callback.
Can you help me to figure out the missing piece?
Thank you.
For some uncanny reason, the code works when I wrap it inside of a runnable. This is my solution:
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final View view = getView();
if (view == null) return;
view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
view.post(() -> {
if (mIsTablet) {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(view.getWidth(), ViewUtil.PORTRAIT);
} else {
mImageFlipper.getLayoutParams().height =
ViewUtil.setHeightForAspectRatio(mDisplayMetrics.widthPixels, ViewUtil.PORTRAIT);
}
});
});
}
I could finally solve it but I don't understand why. If anyone of you knows why this could've happened, please let me know.

Wrong fragment is loading when I am trying to load new one

When I am trying to load a new fragment it loads previous fragment.
I have a fragment profile fragment and on it some onclicks are there. I want to open a new fragment on the click event but it is opening the previous fragment, somewhere backstack is missing or something else i could not find out.
relativeLayoutManagement.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction transaction;
if(getParentFragment() == null){
transaction = childFragmentManager.beginTransaction();
}else {
transaction = childFragmentManagerOfParent.beginTransaction();
transaction.replace(R.id.frameLayoutChildContainer, HotelManagementFragment.newInstance(),FragmentTags.HOTEL_MANAGEMENT);
transaction.addToBackStack(FragmentTags.HOTEL_MANAGEMENT);
transaction.commit();
}
}
});
}
This is my new fragment code.
public class HotelManagementFragment extends BaseFragment {
public HotelManagementFragment() {
}
public static HotelManagementFragment newInstance() {
HotelManagementFragment fragment = new HotelManagementFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hotel_managment, container, false);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onDestroyView() {
super.onDestroyView();
}
}
If you are trying to load fragment on another fragment then Use that id which is in your main activity layout like this. //transaction.replace(R.id.main_activity_fragment_id,your_fragment);

Categories

Resources