WPF - последовательная анимация простой пример

На onCreate вызове метода registerForContextMenu как это:

registerForContextMenu(getListView());

и затем заполняют меню на onCreateContextMenu (меню ContextMenu, представление View, ContextMenuInfo menuInfo) . menuInfo аргумент может предоставить информацию, о которой объект был долго нажат таким образом:

AdapterView.AdapterContextMenuInfo info;
try {
    info = (AdapterView.AdapterContextMenuInfo) menuInfo;
} catch (ClassCastException e) {
    Log.e(TAG, "bad menuInfo", e);
    return;
}
long id = getListAdapter().getItemId(info.position);

и Вы добавляете пункты меню в обычном способе звонить menu.add:

menu.add(0, MENU_ITEM_ID, 0, R.string.menu_string);

и когда пользователь выбирает опцию, , onContextItemSelected называют. Также onMenuItemSelected и этот факт явно не объяснены в документации кроме сказать использование другого метода для получения вызовов из контекстного меню; просто знайте, не совместно используйте идентификаторы.

На onContextItemSelected можно схватить MenuInfo и таким образом идентификатора объекта, выбранного путем вызова getMenuInfo () :

try {
    info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException e) {
    Log.e(TAG, "bad menuInfo", e);
    return false;
}
long id = getListAdapter().getItemId(info.position);

6
задан David Hodgson 2 October 2009 в 21:24
поделиться

2 ответа

Должно быть событие ani.Completed - обработайте это событие и запустите следующую фазу анимации, затем запустите первую, и каждая фаза будет запускать следующую .

ColorAnimation ani = // whatever...

ani.Completed += (s, e) => 
   {
       ColorAnimation ani2 = // another one...

       // and so on
   };

newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);

ОБНОВЛЕНИЕ:

public partial class Window1 : Window
{
    Rectangle blueRect;
    Rectangle redRect;
    Rectangle greenRect;
    Rectangle yellowRect;

    public Window1()
    {
        InitializeComponent();
        blueRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Blue, Name = "Blue" };
        redRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Red, Name = "Yellow" };
        greenRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Green, Name = "Green" };
        yellowRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Yellow, Name = "Yellow" };

        UniformGrid1.Children.Add(blueRect);
        UniformGrid1.Children.Add(redRect);
        UniformGrid1.Children.Add(greenRect);
        UniformGrid1.Children.Add(yellowRect);
    }

    IEnumerable<Action<Action>> AnimationSequence()
    {
        for (; ; )
        {
            yield return AnimateCell(blueRect, Colors.Blue);
            yield return AnimateCell(redRect, Colors.Red);
            yield return AnimateCell(greenRect, Colors.Green);
            yield return AnimateCell(yellowRect, Colors.Yellow);
        }
    }

    private IEnumerator<Action<Action>> _actions;

    private void RunNextAction()
    {
        if (_actions.MoveNext())
            _actions.Current(RunNextAction);
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        _actions = AnimationSequence().GetEnumerator();
        RunNextAction();
    }

    private Action<Action> AnimateCell(Rectangle rectangle, Color fromColor)
    {
        return completed =>
        {
            Color toColor = Colors.White;
            ColorAnimation ani = new ColorAnimation(toColor, 
                                    new Duration(TimeSpan.FromMilliseconds(300)));
            ani.AutoReverse = true;
            ani.Completed += (s, e) => completed();

            SolidColorBrush newBrush = new SolidColorBrush(fromColor);
            ani.BeginTime = TimeSpan.FromSeconds(2);
            rectangle.Fill = newBrush;
            newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
        };
    }
}

Попытайтесь вставить вышеуказанное в свою программу. Он делает то, что вам нужно, но может быть полезно для вас в других контекстах. Он по-прежнему управляется событиями, но использует «метод итератора» (с возвратом yield), чтобы создать впечатление, что это последовательное кодирование, которое блокирует, пока продолжается анимация.

Хорошая вещь в этом - то, что вы можете поиграть с помощью метода AnimationSequence очень интуитивно понятным способом - вы можете записать временную шкалу анимации в виде серии операторов, или использовать циклы, или что угодно.

8
ответ дан 8 December 2019 в 17:23
поделиться

Решение, которое я пробовал, - использовать подобную очередь. Это позволит вам динамически добавлять в цепочку анимации. Я не уверен, нужна ли блокировка, но я оставил ее на всякий случай.

Queue<Object[]> animationQueue = new Queue<Object[]>();

void sequentialAnimation(DoubleAnimation da, Animatable a, DependencyProperty dp)
{
    da.Completed += new EventHandler(da_Completed);

    lock (animationQueue)
    {
        if (animationQueue.Count == 0) // no animation pending
        {
            animationQueue.Enqueue(new Object[] { da, a, dp });
            a.BeginAnimation(dp, da);
        }
        else
        {
            animationQueue.Enqueue(new Object[] { da, a, dp });
        }
    }
}

void da_Completed(object sender, EventArgs e)
{
    lock (animationQueue)
    {
        Object[] completed = animationQueue.Dequeue();
        if (animationQueue.Count > 0)
        {
            Object[] next = animationQueue.Peek();
            DoubleAnimation da = (DoubleAnimation)next[0];
            Animatable a = (Animatable)next[1];
            DependencyProperty dp = (DependencyProperty)next[2];

            a.BeginAnimation(dp, da);
        }
    }
}
3
ответ дан 8 December 2019 в 17:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: