1

我有一個PreferenceFragment其內容是用XML定義的。這些內容包括兒童PreferenceScreen。當我點擊PreferenceScreen時,新屏幕呈現成功,但它沒有動畫(它只是在屏幕上顯示,即使在棒棒糖設備上的材質漣漪完成之前)。如何設置和控制Android PreferenceFragment屏幕?

更糟糕的是,如果我有任何複雜的佈局(例如,PreferenceFragment位於屏幕一側的選項卡中),則該佈局會被吹走並替換爲全屏幕片段。

我懷疑如果我發現點擊時發生的回調或事件,我可以解決這兩個問題,但我真的不知道從哪裏開始。

回答

1

我在PreferenceFragment的從右到左的動畫就是這樣做的一個幻燈片... 我延長了PreferenceFragment並覆蓋了onCreateView()這樣的:

@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; 
} 

其中AnimRelativeLayout.java

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) { 

    } 
} 

然後做到這一點:

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(); 

R.animator.slide_in_right_to_left的一個示例是:

<?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>