แสดง DialogFragment พร้อมภาพเคลื่อนไหวที่เติบโตจากจุดหนึ่ง


97

ฉันกำลังแสดงDialogFragmentเมื่อผู้ใช้แตะที่แถวในไฟล์ListView. ฉันต้องการทำให้การแสดงกล่องโต้ตอบเป็นภาพเคลื่อนไหวเพื่อให้โตขึ้นจากกึ่งกลางของแถว คุณสามารถเห็นเอฟเฟกต์ที่คล้ายกันได้เมื่อเปิดโฟลเดอร์จากตัวเรียกใช้งาน

หนึ่งความคิดที่ว่าฉันเคยเป็นส่วนผสมของและTranslateAnimation ScaleAnimationมีวิธีอื่นอีกไหม


1
อ้างถึงลิงก์สำหรับภาพเคลื่อนไหวบน DialogFragment
ASH

คำตอบ:


176

ในการDialogFragmentเป็น Wrapper สำหรับDialogชั้นเรียนคุณควรกำหนดธีมเป็นฐานDialogเพื่อให้ได้ภาพเคลื่อนไหวที่คุณต้องการ

public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 
    {
        // Set a theme on the dialog builder constructor!
        AlertDialog.Builder builder = 
            new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );

        builder  
        .setTitle( "Your title" )
        .setMessage( "Your message" )
        .setPositiveButton( "OK" , new DialogInterface.OnClickListener() 
            {      
              @Override
              public void onClick(DialogInterface dialog, int which) {
              dismiss();                  
            }
        });
        return builder.create();
    }
}

จากนั้นคุณเพียงแค่กำหนดธีมที่จะรวมภาพเคลื่อนไหวที่คุณต้องการ ในstyles.xmlเพิ่มธีมที่คุณกำหนดเอง:

<style name="MyCustomTheme" parent="@android:style/Theme.Panel">
    <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item>
</style>

<style name="MyAnimation.Window" parent="@android:style/Animation.Activity"> 
    <item name="android:windowEnterAnimation">@anim/anim_in</item>
    <item name="android:windowExitAnimation">@anim/anim_out</item>
</style>    

ตอนนี้เพิ่มไฟล์ภาพเคลื่อนไหวในโฟลเดอร์res / anim :

( android:pivotYคือกุญแจสำคัญ)

anim_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="0.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:fillAfter="false"
        android:startOffset="200"
        android:duration="200" 
        android:pivotX = "50%"
        android:pivotY = "-90%"
    />
    <translate
        android:fromYDelta="50%"
        android:toYDelta="0"
        android:startOffset="200"
        android:duration="200"
    />
</set>

anim_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="1.0"
        android:toXScale="0.0"
        android:fromYScale="1.0"
        android:toYScale="0.0"
        android:fillAfter="false"
        android:duration="200" 
        android:pivotX = "50%"        
        android:pivotY = "-90%"        
    />
    <translate
        android:fromYDelta="0"
        android:toYDelta="50%"
        android:duration="200"
    />
</set>

สุดท้ายสิ่งที่ยุ่งยากก็คือการทำให้ภาพเคลื่อนไหวของคุณเติบโตขึ้นจากกึ่งกลางของแต่ละแถว ฉันคิดว่าแถวนั้นเต็มหน้าจอในแนวนอนดังนั้นในแง่หนึ่งandroid:pivotXค่าจะคงที่ ในทางกลับกันคุณไม่สามารถแก้ไขandroid:pivotYค่าโดยใช้โปรแกรมได้

สิ่งที่ฉันแนะนำคือคุณกำหนดภาพเคลื่อนไหวหลายภาพซึ่งแต่ละภาพมีค่าเปอร์เซ็นต์ที่แตกต่างกันในandroid:pivotYแอตทริบิวต์ (และมีหลายธีมที่อ้างอิงถึงภาพเคลื่อนไหวเหล่านั้น) จากนั้นเมื่อผู้ใช้แตะแถวให้คำนวณตำแหน่ง Y เป็นเปอร์เซ็นต์ของแถวบนหน้าจอ รู้ตำแหน่งเป็นเปอร์เซ็นต์กำหนดธีมให้กับกล่องโต้ตอบของคุณที่มีandroid:pivotYค่าที่เหมาะสม

ไม่ใช่วิธีการแก้ปัญหาที่สมบูรณ์แบบ แต่สามารถช่วยคุณได้ หากคุณไม่ชอบผลลัพธ์ฉันขอแนะนำให้ลืมDialogFragmentและสร้างภาพเคลื่อนไหวที่Viewเพิ่มขึ้นอย่างง่ายจากกึ่งกลางของแถว

โชคดี!


เป็นความคิดที่ดีกับภาพเคลื่อนไหวหลายรายการสำหรับตำแหน่งต่างๆบนหน้าจอ มันเป็นการแฮ็ก แต่ดูเหมือนจะเป็นวิธีเดียว
Edward Dale

สิ่งนี้จะใช้กับ> API 11 @Kiran Babu เท่านั้นคำตอบคือวิธีแก้ปัญหา
Blundell

คุณทราบหรือไม่ว่ามีวิธีที่เป็นไปได้ในการติดต่อกลับเมื่อภาพเคลื่อนไหวเหล่านี้เสร็จสมบูรณ์ ฉันต้องการทำแอนิเมชั่น 2 ตอนโดยที่ไดอะล็อกเลื่อนเข้ามาแล้วทำให้มุมมองจางลงฉันจะแนบผู้ฟังไปที่ windowAnimations ได้อย่างไร
android_student

สุดยอด! มันเป็นสิ่งที่ฉันมองหา!
Aleksey Timoshchenko

2
การตั้งค่าชุดรูปแบบสามารถทำได้ง่ายเพียงแค่ทำsetStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)บนonCreate(bundle)See: developer.android.com/reference/android/app/DialogFragment.html
tropicalfish

126

ลองดูรหัสนี้มันใช้ได้กับฉัน

// เลื่อนภาพเคลื่อนไหว

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="100%"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="0" />

</set>

// สไลด์ภาพเคลื่อนไหว dowm

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="0%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="100%p" />

</set>

// สไตล์

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

// Inside Dialog Fragment

@Override
public void onActivityCreated(Bundle arg0) {
    super.onActivityCreated(arg0);
    getDialog().getWindow()
    .getAttributes().windowAnimations = R.style.DialogAnimation;
}

8
ขออภัยสิ่งนี้ไม่ตอบคำถามของฉันเลย
Edward Dale

3
นี่อาจไม่ใช่สิ่งที่ OP ขอ แต่ฉันคิดว่ามันเป็นจุดเริ่มต้นที่ดี
mdelolmo

3
ตัวอย่างยอดเยี่ยม! ตัวอย่างเดียวที่เหมาะกับฉัน เคล็ดลับคือการตั้งค่าแอนิเมชัน / ธีมในเมธอด onActivityCreated (... )
tomurka

3
สิ่งนี้อาจมีประโยชน์ แต่ไม่ตอบคำถามเลย
Olayinka

คุณทราบหรือไม่ว่ามีวิธีที่เป็นไปได้ในการติดต่อกลับเมื่อภาพเคลื่อนไหวเหล่านี้เสร็จสมบูรณ์แล้ว? ฉันต้องการทำแอนิเมชั่น 2 ตอนโดยที่ไดอะล็อกเลื่อนเข้ามาแล้วทำให้มุมมองจางลงฉันจะแนบผู้ฟังไปที่ windowAnimations ได้อย่างไร
android_student

23

DialogFragment มีเมธอด getTheme () สาธารณะที่คุณสามารถข้ามได้ด้วยเหตุผลที่แน่นอนนี้ โซลูชันนี้ใช้โค้ดน้อยกว่า:

public class MyCustomDialogFragment extends DialogFragment{
    ...
    @Override
    public int getTheme() {
        return R.style.MyThemeWithCustomAnimation;
    }
}

1
ไม่ต้องกังวลอีกต่อไป ... วิธีแก้ปัญหาที่ง่ายและตรงประเด็น
Noundla Sandeep

นี่คือคำตอบที่ดีที่สุดสำหรับฉัน!
superuser

แม้ว่าจะไม่เกี่ยวข้องกับคำถามเดิม แต่ฉันมีแกลเลอรีที่แสดงใน MainAcitvity โดยที่ผู้ใช้คลิกจะเปิดใช้งานสไลด์โชว์ใน DialogFragment อย่างไรก็ตามมีการกระตุกใน MainActivity ทุกครั้งที่กลับจากสไลด์โชว์ นี่คือสาเหตุที่ MainActivity ใช้AppTheme.NoActionBarในขณะที่ DialogFragment AppThemeจะใช้ค่าเริ่มต้น วิธีการข้างต้นแก้ไขปัญหาของฉันโดยมีธีมที่สอดคล้องกันทั้งในส่วนและกิจกรรม
tingyik90

พี่คืออัจฉริยะ
Jacky Chong

วิธีนี้ใช้ได้ผลสำหรับฉัน อย่างไรก็ตามสิ่งหนึ่งที่ทำให้ฉันสับสน การตั้งค่า windowEnterAnimation หรือ windowExitAnimation โดยตรงใน Theme จะไม่สร้างความแตกต่างในแอนิเมชั่น DialogFragments ของฉัน สิ่งเดียวที่ใช้ได้ผลสำหรับฉันคือการตั้งค่า windowAnimationStyle เป็นไฟล์ XML แยกต่างหากที่กำหนดสไตล์และตั้งค่าการเข้าและออกภาพเคลื่อนไหวที่นั่น
szaske

10

หากต้องการรับกล่องโต้ตอบแบบเต็มหน้าจอพร้อมภาพเคลื่อนไหวให้เขียนสิ่งต่อไปนี้ ...

รูปแบบ:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="actionModeBackground">?attr/colorPrimary</item>
    <item name="windowActionModeOverlay">true</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.NoActionBar.FullScreenDialog">
    <item name="android:windowAnimationStyle">@style/Animation.WindowSlideUpDown</item>
</style>

<style name="Animation.WindowSlideUpDown" parent="@android:style/Animation.Activity">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

res / anim / slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="100%"
        android:toYDelta="0%"/>
</set>

res / anim / slide_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="0%"
        android:toYDelta="100%"/>
</set>

รหัส Java:

public class MyDialog extends DialogFragment {

    @Override
    public int getTheme() {
        return R.style.AppTheme_NoActionBar_FullScreenDialog;
    }
}

private void showDialog() {
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    Fragment previous = getSupportFragmentManager().findFragmentByTag(MyDialog.class.getName());
    if (previous != null) {
        fragmentTransaction.remove(previous);
    }
    fragmentTransaction.addToBackStack(null);

    MyDialog dialog = new MyDialog();
    dialog.show(fragmentTransaction, MyDialog.class.getName());
}

4

ใช้มุมมองการตกแต่งภายใน onStart ในส่วนโต้ตอบของคุณ

@Override
public void onStart() {
    super.onStart();


    final View decorView = getDialog()
            .getWindow()
            .getDecorView();

    decorView.animate().translationY(-100)
            .setStartDelay(300)
            .setDuration(300)
            .start();

}

1
มุมมองพื้นฐานดูเหมือนจะไม่สามารถคลิกได้ในภายหลัง
HaydenKai

3

ใน DialogFragment ภาพเคลื่อนไหวแบบกำหนดเองเรียกว่า onCreateDialog 'DialogAnimation' คือรูปแบบภาพเคลื่อนไหวที่กำหนดเองในคำตอบก่อนหน้า

public Dialog onCreateDialog(Bundle savedInstanceState) 
{
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
    return dialog;
}

3

หากคุณต้องการทำงานผ่าน API คุณต้องทำภายใน DialogFragemnt-> onStart และไม่อยู่ใน onCreateDialog

@Override
    public void onStart() 
    {
        if (getDialog() == null) 
        {
            return;
        }

        getDialog().getWindow().setWindowAnimations(
                  R.style.DlgAnimation);

        super.onStart();
    }

ทางออกที่ดีที่สุดในความคิดของฉัน มันใช้ได้กับ AlertDialogs เช่นกันเพียงแค่ใช้ใน onShowListener ขอบคุณ!
Gabor Novak

1

คุณเคยดูการฝึกอบรมนักพัฒนา Android เกี่ยวกับการซูมมุมมองหรือไม่ อาจเป็นจุดเริ่มต้นที่ดี

คุณอาจต้องการสร้างคลาสแบบกำหนดเองDialogFragmentเพื่อขยายการทำงานนี้

นอกจากนี้โปรดดูที่ Jake Whartons NineOldAndroidsสำหรับความเข้ากันได้ของ Honeycomb Animation API ตลอดทางกลับไปที่ API ระดับ 1


-1

เพิ่มรหัสนี้ในการเคลื่อนไหวของค่า

 <scale
    android:duration="@android:integer/config_longAnimTime"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:toXScale="1.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"/>
<alpha
    android:fromAlpha="0.1"
    android:toAlpha="1.0"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>

โทรไปที่ styles.xml

<style name="DialogScale">
    <item name="android:windowEnterAnimation">@anim/scale_in</item>
    <item name="android:windowExitAnimation">@anim/scale_out</item>
</style>

ในรหัส java: ตั้งค่า Onclick

public void onClick(View v) {
        fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView());
      //  Dialogs.fab_onclick(R.style.DialogScale, "Scale");

    }

ตั้งค่าวิธีการ:

alertDialog.getWindow().getAttributes().windowAnimations = type;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.