2010-12-21 79 views
35

我有一個包含項目列表的活動,當您單擊某個項目時,我想讓該項目的播放控件從屏幕底部向上滑動並變爲可見。我爲幻燈片定義了一個動畫集,並將其滑出,並且它們可以工作。我在我的活動中設置了我的animationListener,並開始使用動畫onClick的幻燈片。我的問題是,我第一次運行應用程序,當我點擊一個項目,onClick回調被執行,但動畫不會發生。第二次點擊,動畫中的幻燈片發生,但不是滑出。第三次及以後,它按預期工作。這是我的動畫集。佈局動畫在第一次運行時不工作

vm_slide_in.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
      android:fillAfter="true"> 
    <translate 
     android:fromYDelta="800" 
     android:toYDelta="0" 
     android:duration="600" /> 
</set> 

vm_slide_out.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
      android:fillAfter="true"> 
    <translate 
     android:fromYDelta="0" 
     android:toYDelta="800" 
     android:duration="600" /> 
</set> 

這裏是我的活動佈局

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    style="@style/AppBG"> 
    <RelativeLayout 
     style="@style/LogoBar" 
     android:id="@+id/logo_bar"  
     android:layout_alignParentTop="true"> 
     <include layout="@layout/logobar"></include> 
    </RelativeLayout> 
    <RelativeLayout 
     style="@style/TitleBar" 
     android:id="@+id/title_bar"  
     android:layout_below="@+id/logo_bar"> 
     <include layout="@layout/titlebar"></include>" 
     <Button style="@style/TitleBarButton" 
      android:id="@+id/vm_speaker_btn" 
      android:text="@string/vm_speaker_btn_label" 
      android:layout_alignParentLeft="true" 
      android:layout_margin="4dp"> 
     </Button> 
     <Button style="@style/TitleBarButton" 
      android:id="@+id/vm_edit_btn" 
      android:text="@string/vm_edit_btn_label" 
      android:layout_alignParentRight="true" 
      android:layout_margin="4dp"> 
     </Button> 
    </RelativeLayout> 
    <ListView 
     android:id="@+id/@android:id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/title_bar"/> 
    <RelativeLayout 
     android:id="@+id/vm_control_panel" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_above="@+id/footer" 
     android:visibility="gone"> 
     <include layout="@layout/vm_control"/> 
    </RelativeLayout> 
    <RelativeLayout 
     android:id="@+id/footer" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentBottom="true"> 
     <include layout="@layout/taskbar"/> 
    </RelativeLayout> 
</RelativeLayout> 

下面是包括控制

<?xml version="1.0" encoding="utf-8"?> 
<merge xmlns:android="http://schemas.android.com/apk/res/android"> 
    <RelativeLayout 
     android:id="@+id/vm_control" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:background="@color/dark_grey"> 
     <TextView 
      android:id="@+id/vm_ctl_branding" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_alignParentTop="true" 
      android:layout_centerHorizontal="true" 
      android:layout_marginTop="5dp" 
      android:text="@string/branding" 
      android:textColor="@color/white"> 
     </TextView> 
     <TextView style="@style/TimeMark" 
      android:id="@+id/vm_timestamp" 
      android:layout_toLeftOf="@+id/vm_progress" 
      android:layout_below="@+id/vm_ctl_branding" 
      android:layout_marginRight="3dp" 
      android:text="0:00"> 
     </TextView> 
     <SeekBar 
      android:id="@+id/vm_progress" 
      android:layout_width="200dp" 
      android:layout_height="wrap_content" 
      android:layout_below="@+id/vm_ctl_branding" 
      android:layout_centerHorizontal="true"> 
     </SeekBar> 
     <TextView style="@style/TimeMark" 
      android:id="@+id/vm_timeleft" 
      android:layout_toRightOf="@+id/vm_progress" 
      android:layout_below="@+id/vm_ctl_branding" 
      android:layout_marginLeft="3dp" 
      android:text="-0:00"> 
     </TextView> 
     <LinearLayout 
      android:id="@+id/vm_action_button_layout" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:layout_alignLeft="@+id/vm_timestamp" 
      android:layout_alignRight="@+id/vm_timeleft" 
      android:orientation="horizontal" 
      android:layout_below="@+id/vm_progress"> 
      <TextView style="@style/Vm_Action_Button" 
       android:background="@drawable/vm_action_btn_call" 
       android:id="@+id/vm_callback_btn" 
       android:layout_marginRight="5dp" 
       android:text="@string/vm_action_btn_callback"> 
      </TextView> 
      <TextView style="@style/Vm_Action_Button" 
       android:background="@drawable/vm_action_btn_delete" 
       android:id="@+id/vm_delete_btn" 
       android:layout_marginLeft="5dp" 
       android:text="@string/vm_action_btn_delete"> 
      </TextView> 
     </LinearLayout> 
    </RelativeLayout> 
</merge> 
佈局

從我的onCreate方法...

// Handle list item selections 
ListView lv = getListView(); 
lv.setOnItemClickListener(new OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     final Voicemail vmItem = (Voicemail) vmla.getItem(position); 
     Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT) 
       .show(); 
     vVm_controls.startAnimation(mSlideIn); 
    } 
}); 

與我的動畫回調...

@Override 
public void onAnimationStart(Animation animation) { 
    vm_controls_in = !vm_controls_in; 
    if (vm_controls_in) { 
     vVm_controls.setVisibility(View.GONE); 
    } else { 
     vVm_controls.setVisibility(View.VISIBLE); 
     // vVm_controls.bringToFront(); 
    } 
} 

@Override 
public void onAnimationEnd(Animation animation) { 
    if (!vm_controls_in) { 
     try { 
      Thread.sleep(1000); 
      vVm_controls.startAnimation(mSlideOut); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

@Override 
public void onAnimationRepeat(Animation animation) { 
    // TODO Auto-generated method stub 

} 

回答

98

正如你發現的,問題是可見性。當視圖初始設置爲xml文件時,Android將不會呈現佈局,直到可見性更改爲可見或不可見。如果您嘗試在尚未呈現的視圖上設置動畫效果,則動畫將在沒有佈局的視圖上進行。動畫完成後,它將渲染它,並突然顯示視圖而不顯示動畫。隨着時間的推移,它會工作,因爲該視圖即使設置爲消失也具有佈局。

關鍵是將可見性設置爲不可見,而不是放在xml文件中,以使其呈現爲隱藏狀態。動畫在第一次出現時會出現,並會按預期移動。

9

當然沒有張貼這個問題,20分鐘後我想通了,我的問題。由於我將佈局的可見性設置爲「GONE」,因此當我試圖在其上啓動動畫時,它不是第一次觸發。不知道爲什麼它會在第二次及以後出現,但如果在開始動畫之前將可見性設置爲「可見」,它就解決了問題。這裏是我改變它的代碼...

// Handle list item selections 
ListView lv = getListView(); 
lv.setOnItemClickListener(new OnItemClickListener() { 
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
     final Voicemail vmItem = (Voicemail) vmla.getItem(position); 
     Toast.makeText(ctx, "Name: " + vmItem.getCallerName() + " Position: " + position, Toast.LENGTH_SHORT) 
       .show(); 
     vVm_controls.setVisibility(View.VISIBLE); 
     vVm_controls.startAnimation(mSlideIn); 
    } 
}); 
+0

你的解決方案是不是「公開範圍設置爲不可見」 – breceivemail 2013-02-24 07:07:31

+0

不,這不是因爲你不必擔心您的觀點被定位成更好用戶看不到跳轉。如果動畫是從視圖的位置開始的,但沒有將動畫帶到視圖的位置(或其他偏移動畫),則無需動畫。 – 2013-10-10 16:44:04

0

我有完全相同的問題,但通過使用ViewPropertyAnimator。例如,您聲明一個GridView,稱爲mGridView。你現在所要​​做的就是致電mGridView.animate()與你想要的變化。

我的GridView動畫被觸發,但由於未知情況,沒有實際的動畫可見。我也將所有View.GONE更改爲View.VISIBLE,但它沒有改變任何東西。在我的情況下,我想通了,我只需要刪除這個特定GridView的XML中的android:requiresFadingEdge="vertical"。可能無法將衰落邊緣與ViewPropertyAnimator結合使用。

3

我不知道它是否仍然是最新的,但是,這是一個與知名度有關的問題。所以我設置的xml文件不可見的知名度和在地方叫您的觀點被初始化:

view.post(new Runnable() { 
    @Override 
    public void run() { 
     view.animate().translationY(view.getHeight()); 
    } 
}; 

現在呼叫

view.animate().translationY(0).setListener(new AnimatorListenerAdapter() { 
    @Override 
    public void onAnimationStart(Animator animation) { 
     super.onAnimationStart(animation); 
     view.setVisibility(View.VISIBLE); 
    } 
} 

作品也首次。

0

我在Android 4.4.3中遇到了類似的問題。我嘗試了大部分解決方案,但只有一種解決方案適合我。 您必須在窗口完成渲染後運行動畫,最好的方法是在onWindowFocusChanged內運行它。不要在可運行時使用延遲,因爲這會影響高速手機中的應用程序性能。

@Override 
public void onWindowFocusChanged (boolean hasFocus) { 
    super.onWindowFocusChanged(hasFocus); 
    if (hasFocus) 
     yourView.startAnimation(anim); 
} 

更多的信息可以在這個帖子中找到: https://damianflannery.wordpress.com/2011/06/08/start-animation-in-oncreate-or-onresume-on-android/

1

假如即使我在動畫開始的視圖設置爲可見完全相同的問題。在開始動畫之前,我遵循了brockoli的建議並將其設置爲可見,並且它像魅力一樣起作用。

BEFORE:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); 
animation.setAnimationListener(new Animation.AnimationListener() { 
    @Override 
    public void onAnimationStart(Animation animation) { 
     view.setVisibility(View.VISIBLE); 
    } 

    @Override 
    public void onAnimationEnd(Animation animation) { } 

    @Override 
    public void onAnimationRepeat(Animation animation) {  } 
); 
view.startAnimation(animation); 

AFTER:

Animation animation = AnimationUtils.loadAnimation(getContext(), R.anim.slide_left); 
view.setVisibility(View.VISIBLE); 
view.startAnimation(animation);