Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Igor-vrn
7 / 7 / 2
Регистрация: 14.12.2013
Сообщений: 94
1

Как реализовать анимацию перемещения в таком приложении.?

13.04.2014, 09:40. Просмотров 1327. Ответов 0
Метки нет (Все метки)

задача:
блок движется по горизонтали за пальцем (onTouch). Причем блок движется как бы по сетке 10x10, то есть по достижении положения пальца блок должен оказаться в ячейке под пальцем (ближайшей). Независимо от скорости свайпа блок должен перемещаться со своей скоростью как бы вдогонку и останавливаться по достижению координат пальца.

"Почему бы не привязать координаты пальца к блоку через FrameLayout.LayoutParams и при каждом вызове обновлять .leftMargin?"
- удобно, но к сожалению, не актуально для моего случая. Блоки должны обладать гравитацией, что при падении блока вызовет разногласие между координатами пальца и leftMatgin блока. Блок должен двигаться со своей скоростью, независимо от скорости свайпа.

"Почему бы не организовать собственный алгоритм анимации с помощью leftMargin и сделать ее в время от времени засыпающем отдельном потоке?"
- первое о чем я подумал. Но. отдельный поток не может управлять GUI. Это Exception.

"Сделать цивильную, штатную анимацию перемещения TranslateAnimation"
- сделал. То ли я трижды неправильно написал алгоритм, то ли и правда TranslateAnimation туго связать с onTouch. Все же это можно переписать в четвертый раз и добиться адекватности перемещения. Но. Опять же есть косяки:
В моем случае перемещение равнялось ширине блоке (Animation.RELATIVE_TO_SELF, 1.0f). Моя логика проста:
при начале движения пальца срабатывает onTouch (OnTouchListener реализуется перемещаемым блоком), сверяются координаты. Если есть куда двигаться вызывается запуск анимации на одно перемещение. По окончании анимации OnAnimationEnd снова сверяются координаты и, если нужно, снова запускается анимация на одно перемещение.

Проблема в идее. Анимация идет не равномерно, а рывками - естественно на стыках блоков сетки. Да и сама реализация сомнительна - примерно как трусы через голову. Должно быть что-то адекватнее. Посоветуйте. Плюс проблема - после выполнения анимации блок остается на старом месте. fillAfter помогает только оставить его там. Повторная анимация все равно делается от положения по LayoutParams.

* При каждом проходе стыка сетки должен быть выход на некоторые методы (применить гравитацию)

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
* super.X - положение блока в сетке Grid по оси Х (0 -> 10)
* IsMoving - флаг выполнения анимации. Чтобы движения пальца не вызывали хаотичную анимацию
*/
 
@Override
    public boolean onTouch(View v, MotionEvent event) {
        // TODO Auto-generated method stub
        switch(event.getAction()) {
        case MotionEvent.ACTION_MOVE:
            curX = event.getX(); // обновляем каждый раз
            if(checkFirstCondition())LaunchAnimation(); 
            break;
        case MotionEvent.ACTION_DOWN:
            startX = super.X; // фиксируем начальное положение в ячейке Х
            BrixActivity.b.setText(X + " ,  " + Y);
            break;
        case MotionEvent.ACTION_UP:
            IsMoving = false;
            break;
        }
        
        return true;
    }
 
private boolean checkFirstCondition() {
        if(!IsMoving) {
            if(curX < 0 || curX > SizeOfElement()) return true;
        }
        return false;
    }
 
private void LaunchAnimation() {
        IsMoving = true;
        if(curX < 0) { // для движения влево
            float s = ((int)(curX / SizeOfElement()) - 1) + startX;
            if(s < super.X && Grid.CheckCellForVacant(super.X - 1, super.Y)) AnimMoveLeft();
        }
        if(curX > SizeOfElement()) { // движение вправо
            float s = (int)(curX / SizeOfElement()) + startX;
            if(s > super.X && Grid.CheckCellForVacant(super.X + 1, super.Y)) AnimMoveRight();
        }
    }
 
private void AnimMoveLeft() {
        Animation move = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0.0f, 
                Animation.RELATIVE_TO_SELF, -1.0f,
                Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f);
        move.setDuration(AnimationDuration);
        move.setAnimationListener(this);
        //move.setFillAfter(true);
        Grid.MoveElement(super.X, --super.X, super.Y, super.Y);
        this.startAnimation(move);
    }
    
    private void AnimMoveRight() {
        Animation move = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0.0f, 
                Animation.RELATIVE_TO_SELF, 1.0f,
                Animation.RELATIVE_TO_SELF, 0.0f,
                Animation.RELATIVE_TO_SELF, 0.0f);
        move.setDuration(AnimationDuration);
        move.setAnimationListener(this);
        //move.setFillAfter(true);
        Grid.MoveElement(super.X, ++super.X, super.Y, super.Y);
        this.startAnimation(move);
    }
    
    private int SizeOfElement() {
        return super.block.getHeight();
    }
 
    @Override
    public void onAnimationEnd(Animation animation) {
        // TODO Auto-generated method stub
        
        FrameLayout.LayoutParams t = new FrameLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        t.topMargin = super.Y * SizeOfElement();
        t.leftMargin = (super.X + 1) * SizeOfElement();
        super.setLayoutParams(t);
        LaunchAnimation();
        BrixActivity.b.setText("(" + super.X + ", " + super.Y + "), " + IsMoving + "," + super.X + "," + super.Y);
    }
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2014, 09:40
Ответы с готовыми решениями:

Как перенести из 3d max анимацию в приложении на андроиде?
Единственное что приходит на ум сохранять в формате stl каждый кадр, но...

Как реализовать анимацию в Android?
Есть ли какие то хорошие уроке по анимации в андроид пло прорисовке графики...

Как остановить анимацию
Доброго времени суток. Есть две анимации которые работают по очереди,...

Как запустить анимацию
Мне необходимо запустить анимацию без вызова startAnimation. В чем суть. Есть...

Как убрать анимацию?
Можно ли в полностью убрать анимацию при открытии форм? Слишком медленно, если...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.04.2014, 09:40

Как крутить анимацию по кругу
анимация прокручивается всего 1 раз, пробовал использовать метод...

Как сделать анимацию объемного поворота?
Что то типа этого: С помощью каких методов или что для этого используют?

Frame animation или как сделать анимацию
Здравствуйте. Подскажите, пожалуйста, как сделать анимацию? У меня есть...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru