【问题标题】:Listen for animation end on the Android Gallery control在 Android Gallery 控件上监听动画结束
【发布时间】:2012-08-17 05:11:40
【问题描述】:

我有一个标准的 Android Gallery 控件:

<Gallery
    android:id="@+id/galArt"
    android:spacing="10dp"
    android:fadingEdgeLength="0dp"
    android:unselectedAlpha="1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" />

我用这段代码监听事件:

galArt.setOnItemSelectedListener(new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
            showMessageToast("Selected: " + pos);           
        }
        public void onNothingSelected(AdapterView<?> arg0) {}
    });

我猜它的目的是这样的:当我滑动图像时,我得到一个 toast 告诉我现在选择了哪个图像。

然而,这个 toast 出现在之前图像停止滑动,而动画仍在运行。我想在它停止滑动后采取行动,以避免中断动画。

为了在动画完成后获得通知,我可以听什么?

【问题讨论】:

    标签: android android-layout android-animation


    【解决方案1】:

    好的,我找到了解决方案。请注意,这只是一个解决方案,不一定是最佳解决方案。

    我的解决方案是忽略所有逻辑事件(如 onScroll 或 onAnimationEnd,因为无论如何我都无法让它们工作),并监听子视图位置的变化。当子视图静止时,动画就结束了。

    这样做的一个实际好处是它既适用于拖动也适用于抛掷。

    一个问题是 onItemSelected 函数将从您的 UI 线程之外的另一个线程调用。使用 Activity 的 runOnUIThread 函数解决这个问题,如示例所示。

    监听变化的方式(注意这不是常规的onItemSelected函数,而是我自己的onItemReallySelected):

    galArt.setOnItemReallySelectedListener(new OnItemSelectedListener() {
        public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                _activity.runOnUiThread(new Runnable() {
                    public void run() {
                        //Do your stuff here ...
                    }
                });
        }
        public void onNothingSelected(AdapterView<?> arg0) {
            //... or here.
        }
    });
    

    我对 Android Gallery 的实现:

    import java.util.Timer;
    import java.util.TimerTask;
    
    import android.content.Context;
    import android.util.AttributeSet;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.widget.Gallery;
    
    public class ArtGallery extends Gallery {
    
        OnItemSelectedListener _listener;
        Timer _timer = new Timer();
    
        public ArtGallery(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public ArtGallery(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public ArtGallery(Context context) {
            super(context);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if(event.getAction()==MotionEvent.ACTION_UP){
                setTimer();
            }
            return super.onTouchEvent(event);
        }
    
        private int _lastScrollX = Integer.MIN_VALUE;
        private void setTimer() {
            //Cancel existing tasks (if any), and create a new timer.
            _timer.cancel();
            _timer = new Timer();
    
            //Schedule our animation check.
            _timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    //Just some value that will change while the animation is running.
                    int x = getSelectedView().getLeft(); 
                    if(_lastScrollX != x){
                        //Value has changed; save current value, and reset the timer.
                        _lastScrollX = x;
                        setTimer();
                    }else{
                        //The value hasn't changed during the last 50ms. That probably means that the animation has stopped.
                        fireOnSelected();
                    }
                }
            }, 50); 
        }
    
        public void setOnItemReallySelectedListener(OnItemSelectedListener listener){
            _listener = listener;
        }
    
        //This function is copied from the Android Gallery source code, and works exactly like the original one.
        private void fireOnSelected() {
            if (_listener == null)
                return;
    
            int selection = this.getSelectedItemPosition();
            if (selection >= 0) {
                _listener.onItemSelected(this, getSelectedView(), selection, getAdapter().getItemId(selection));
            } else {
                _listener.onNothingSelected(this);
            }
    
        }
    }
    

    【讨论】:

    • 您好,Erlend,我尝试了您的解决方案,它有效。唯一的问题是,当您启动图库时,它不会在第一个项目上触发。你有解决办法吗?
    • 不,我从来不需要它来启动画廊的初始化。我建议您在第一次设置后手动调用 yourFunction() 。或者你可以在 ArtGallery 类中覆盖 setAdapter 或类似的东西,然后从那里调用 fireOnSelected。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 2015-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多