Форум программистов, компьютерный форум CyberForum.ru

Программирование Android

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Igor-vrn
7 / 7 / 2
Регистрация: 14.12.2013
Сообщений: 93
#1

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

13.04.2014, 09:40. Просмотров 1150. Ответов 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);
    }
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2014, 09:40     Как реализовать анимацию перемещения в таком приложении.?
Посмотрите здесь:
Android Как перенести из 3d max анимацию в приложении на андроиде?
Как реализовать анимацию в андроид? Android
Android Как убрать анимацию?
Как запустить анимацию Android
Android Как остановить анимацию
Android Как крутить анимацию по кругу
Как сделать анимацию объемного поворота? Android
Как сделать анимацию при загрузки приложения Android
Frame animation или как сделать анимацию Android
Android Как установить Gif анимацию в качестве фона?
Как создать анимацию при переходе между экранами? Android
Android Как создать выдвигающееся слева меню (как в приложении вконтакте)?

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Ответ Создать тему
Опции темы

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