package com.afollestad.silk.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* The base of all other fragments in the library; contains methods that help maintain consistency among all fragments,
* also provides various convenience methods.
*
* @author Aidan Follestad (afollestad)
*/
public abstract class SilkFragment extends Fragment {
private boolean mAttached;
/**
* Gets the fragment layout to be inflated.
*/
protected abstract int getLayout();
/**
* Gets the title set to the activity when the Fragment is attached.
*/
public abstract String getTitle();
/**
* Called when the Fragment becomes visible or invisible to the user.
* <p/>
* This works even when in a ViewPager when Fragments that are not actually visible are initialized off to the side.
* <p/>
* Sometimes {#getUserVisibleHint}, {#isVisible}, {#setUserVisibleHint}, etc. can be deceiving. This is the answer.
*/
protected void onVisibilityChanged(boolean visible) {
// Nothing is done by default
}
private void notifyVisibility(boolean visible) {
if (visible) {
if (getActivity() != null && getTitle() != null)
getActivity().setTitle(getTitle());
if (mAttached) {
// Don't allow multiple notifications
return;
}
}
mAttached = visible;
onVisibilityChanged(visible);
}
/**
* Gets whether or not the fragment is attached and visible to the user.
*/
public final boolean isActuallyVisible() {
return mAttached;
}
@Override
public void onResume() {
super.onResume();
if (getUserVisibleHint())
notifyVisibility(true);
else if (mAttached)
notifyVisibility(true);
}
@Override
public void onPause() {
super.onPause();
if (mAttached)
notifyVisibility(false);
}
@Override
public final void setUserVisibleHint(boolean isVisibleToUser) {
if (isVisibleToUser) notifyVisibility(true);
else if (isVisible()) notifyVisibility(false);
super.setUserVisibleHint(isVisibleToUser);
}
@Override
public final void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
// This is overridden so sub-classes can't override it, use onVisibilityChange() instead.
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(getLayout(), null);
}
public final void runOnUiThread(Runnable runnable) {
if (getActivity() == null)
return;
getActivity().runOnUiThread(runnable);
}
}