sigmabeta
sigmabeta

Reputation: 1184

How to animate & control Android PreferenceFragment screens?

I have a PreferenceFragment whose contents are defined in XML. These contents include a child PreferenceScreen. When I click on the PreferenceScreen, the new screen is rendered successfully, but it has no animation (it just shows up on screen, even before the Material ripple is finished on Lollipop devices).

Even worse, if I had any complex layout going on (for example, the PreferenceFragment was in a tab on one side of the screen) that layout is blown away and replaced with a full-screen fragment.

I suspect that if I find the callback or event that occurs when a PreferenceScreen is clicked, I can solve both problems, but I don't really know where to start.

Upvotes: 1

Views: 1257

Answers (1)

Andrei Verdes
Andrei Verdes

Reputation: 1062

I did this for a slide in right-to-left animation of the PreferenceFragment... I extended the PreferenceFragment and overridden the onCreateView() like this:

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = super.onCreateView(inflater, container, savedInstanceState);
    AnimRelativeLayout animRelativeLayout = new AnimRelativeLayout(getActivity());
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    animRelativeLayout.setLayoutParams(layoutParams);
    animRelativeLayout.addView(view);
    return animRelativeLayout;
}

where AnimRelativeLayout.java is

public class AnimRelativeLayout extends RelativeLayout {

private IMovementListener mMovementListener;

public AnimRelativeLayout(Context context) {
    super(context);
    this.initMembers();
}

public AnimRelativeLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.initMembers();
}

public AnimRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.initMembers();
}

private void initMembers() {
    this.mMovementListener = new SimpleMovementListener();
}

public float getXFraction() {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int width = size.x;
    return (width == 0) ? 0 : getX() / (float) width;
}

public void setXFraction(float xFraction) {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int width = size.x;
    this.mMovementListener.onSetXFraction(xFraction);
    setX((width > 0) ? (xFraction * width) : 0);
}

public float getYFraction() {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int height = size.y;
    return (height == 0) ? 0 : getY() / (float) height;
}

public void setYFraction(float yFraction) {
    final WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int height = size.y;
    this.mMovementListener.onSetYFraction(yFraction);
    setY((height > 0) ? (yFraction * height) : 0);
}

public interface IMovementListener {
    public void onSetXFraction(float pXFraction);

    public void onSetYFraction(float pYFraction);
}

private class SimpleMovementListener implements IMovementListener {

    @Override
    public void onSetXFraction(float pXFraction) {

    }

    @Override
    public void onSetYFraction(float pYFraction) {

    }
}

and then did this:

pFragmentManager.beginTransaction()
            .setCustomAnimations(
                    R.animator.slide_in_right_to_left, R.animator.slide_out_right_to_left,
                    R.animator.slide_in_left_to_right, R.animator.slide_out_left_to_right
            )
            .replace(R.id.fragment_container, fragment)
            .commit();

and an example for R.animator.slide_in_right_to_left is:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="300"
        android:propertyName="xFraction"
        android:valueFrom="1.0"
        android:valueTo="0"
        android:valueType="floatType"/>
</set>

Upvotes: 1

Related Questions