CNN TürkResmen başladı: Karma çalışma yönetmeliğinde neler değişti?PunchMorning recap: Sex workers scramble as anti–HIV jab runs out, Obi, Momodu condemn El-Rufai’s prolonged detention, other top storiesThe Jerusalem PostSaudi coalition says it intercepts Houthi missiles, drones targeting Khamis Mushait, RiyadhESPN DeportesLos Grizzlies cortan al veterano D'Angelo RussellHet Laatste NieuwsRepublikeinen bijten in het zand: Hooggerechtshof wijst nieuwe kiesdistricten Missouri afThe Sydney Morning HeraldAFL grand final LIVE: Dockers rise against champion Lions with a quarter to play after injured skipper declares ‘I’m done’VilaWebOpenAI admet que els seus agents d’IA van accedir indegudament a webs del govern dels Estats UnitsOnet"Niedługo wyślą mnie, bym zabijał. Chcę do domu". Jak ludzie z drugiego końca świata podstępem stają się mięsem armatnim Putina [REPORTAŻ]CNN بالعربيةفيديو يوثق إنقاذ فيل صغير من الغرق في نهر بالهند한겨레‘중국 연안 사정권’…일 자위대, 미일 연합훈련서 공격용 미사일 전개키로SözcüEl Nino'nun 'Godzilla' versiyonu geliyor: En az 450 bin kişi hayatını kaybedecekSky TG24Tra ex-bunker e vecchie stazioni di servizio, viaggio nella Berlino “riqualificata”
The Daily Newsstand · Free, Always
Saturday, September 26, 2026

«Щелчок Таноса» или искусство в разработке

Translate

Ресурсы Вселенной ограничены, а постоянно растущее население планеты может привести к голодному вымиранию всего человечества в ближайшем будущем. Чтобы спасти людей от голодного вымирания, киновселенная Marvel придумала оригинальный способ решения проблемы. Она создала могущественного титана по имени Танос, взявшего на себя миссию спасителя. Идея Таноса состояла в том, чтобы собрав шесть Камней Бесконечности и объединив их силу в специальной Перчатке, раз и навсегда избавиться от половины населения планеты, просто щелкнув пальцами.

Эта история породила метафорическое значение, а фраза "Щелчок Таноса" стала крылатой и приобрела вполне реальные события. К примеру в бизнесе такое действие иронично называют жесткими антикризисными мерами, когда руководство компании одним махом увольняет большое количество сотрудников, дабы сократить расходы и спастись от банкротства.

Искусство программирования

В этой статье я хочу поделиться своим видением относительно применения нестандартных методов решения задач в программировании. Возможно, некоторым читателям тема покажется абсурдной, но то, что получится в финале, поистине вас впечатлит. Для разработчиков наступает новая эра, где можно и нужно уходить от рутинной практики разработки удивляя своих заказчиков.

Крылатая фраза Стива Джобса гласит: "Думай иначе". Это означает, что сегодня уже недостаточно просто уметь программировать - нужно создавать нечто неожиданное. Уже не достаточно того, чтобы приложение просто работало, важно, чтобы оно увлекало пользователя и не оставляло ни единого шанса конкурентам. В общем, настало время превращать программный код в настоящее искусство. О том как это сделать и пойдёт речь в данной статье.

Так как статья расчитана на Java-разработчиков, я расскажу о том, как можно применить метод "Щелчка Таноса" при решении задач построения графического интерфейса приложения. В качестве примера я расскажу, как реализовать удаление элементов списка сообщений в чате с применением эффекта взрыва, при котором сообщение будто разрывается на мелкие кусочки и растворяется в пространстве.

Итак представьте, что вы создали некий чат и в нём присутствуют вьюшки отображающие текст, картинки и прочие информационные блоки. Здача состоит в том, чтобы при удалении сообщений пользователь видел не просто исчезновение элементов с экрана но и распыляющую эти частицы анимацию. Это выглядит завораживающе и хочется повторять этот процесс снова и снова. Это отличный способ принудить пользователя удалять лишние сообщения из чата дабы не перегружать память устройства и не хранить лишние записи в базе данных.

Магия

В этом примере будут использоваться только нативные компоненты ОС Андроид, поэтому дополнительные библиотеки не потребуются. Это сделает код чистым и легковесным без лишнего "шума и пыли". Итак, для реализации задуманного будем работать с растровым изображением (Bitmap) и аниматором ValueAnimator. Нам потребуется создать кастомный View который и возьмёт на себя всю работу.

На первом этапе нужно получить целевой View (TextView или любой другой) из списка сообщений и сконвертировать его в Bitmap. Иными словами создадим скриншот этого элемента а сам элемент сделаем невидимым View.GONE Далее мы будем работать с картинкой уже скрытого сообщения а само сообщение можно будет просто удалить.

Далее полученное растровое изображение нужно просканировать по сетке с определенным шагом (меньший шаг - лучше эффект но выше нагрузка на процессор). Для каждого полученного пикселя нужно создать объект-частицу (Particle) с исходными координатами (x, y) и цветом.

Каждой полученной частице нужно задать случайное направление движения по осям X и Y, а также придать ускорение и время жизни, чтобы частица не существовала бесконечно. Это определит общую физику движения для всего облака частиц.

С помощью ValueAnimator от 0 до 1 запускается цикл перерисовки. На каждом кадре в методе onDraw кастомного View координаты частиц должны изменяться, а их прозрачность alpha уменьшаться. После частицы нужно нарисовать на холсте через drawPoint или drawCircle.

Для хранения параметров частиц создадим специальный класс:

public class Particle {
    float cx; // Текущая координата X
    float cy; // Текущая координата Y
    float originalX;
    float originalY;
    int color;
    float radius;
    
    // Скорости и направление разлета
    float vx;
    float vy;
    float alpha = 1.0f;
}

Теперь получим растровое изображение самого элемента сообщения:

// Конвертируем View в Bitmap
targetView.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(targetView.getDrawingCache());
targetView.setDrawingCacheEnabled(false);
targetView.setVisibility(View.GONE); // Скрываем оригинал
// Получаем размеры изображения
int width = bitmap.getWidth();
int height = bitmap.getHeight();

Теперь нужно нарезать картинку на пиксели и задать необходимые параметры частицам:

// Задаём переменные
List<Particle> particles;
Random random = new Random();

// Шаг сетки
int step = 4; 

// Нарезаем Bitmap на пиксели-частицы
for (int y = 0; y < height; y += step) {
    for (int x = 0; x < width; x += step) {
        int color = bitmap.getPixel(x, y);
        // Пропускаем полностью прозрачные пиксели
        if (color == 0) continue; 

        Particle particle = new Particle(); // <- класс частиц описанный выше
        particle.originalX = x;
        particle.originalY = y;
        particle.cx = x;
        particle.cy = y;
        particle.color = color;
        particle.radius = step / 2f;

        // Задаём случайный вектор разлета
        particle.vx = (random.nextFloat() - 0.5f) * 20f;
        particle.vy = (random.nextFloat() - 0.7f) * 15f;

        particles.add(particle);
    }
}

Когда частицы собраны в коллекцию можно запускать анимацию:

// Задаём переменные
ValueAnimator animator;
// Настраиваем и запускаем аниматор
animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(1200); // Длительность анимации в мс
animator.setInterpolator(new AccelerateDecelerateInterpolator());
        
animator.addUpdateListener(animation -> {
    float progress = (float) animation.getAnimatedValue();
    updateParticles(progress);
    invalidate(); // Перерисовка холста
});

animator.addListener(new android.animation.AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(android.animation.Animator.AnimatorListener animation) {
        if (endListener != null) endListener.onEnd();
    }
});

animator.start();

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

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    if (particles == null) return;

    for (Particle p : particles) {
        paint.setColor(p.color);
        paint.setAlpha((int) (p.alpha * 255));
        canvas.drawCircle(p.cx, p.cy, p.radius, paint);
    }
}

Ниже представлен цикл обновления состояния каждой частицы на каждом шаге симуляции. Если предыдущая функция только рисовала частицы, то этот код управляет их движением, физикой и плавным исчезновением.

for (Particle p : particles) {
    // Изменяем координаты с учетом скорости
    p.cx += p.vx;
    p.cy += p.vy;
    p.vy += 0.5f; // Гравитация тянет частицы вниз
            
    // Плавное исчезновение (alpha от 1 до 0 во второй половине анимации)
    if (progress > 0.5f) {
        p.alpha = 1.0f - ((progress - 0.5f) * 2f);
    }
}

Интегрировать можно как в Activity так и во Fragment. Чтобы запустить эффект "Щелчок Таноса" или разрыва сообщения на частицы для конкретного сообщения (например, по клику или таймеру автоудаления), нужно добавить описанный выше кастомный View поверх корневого макета и выполнить код.

// Корневой контейнер (например, FrameLayout или ConstraintLayout)
ViewGroup rootLayout = findViewById(id.root_layout); 

// Само сообщение
TextView messageTextView = findViewById(id.tvMessage); 

// Создаем оверлей для анимации поверх экрана используя наш кастомный View
DisappearAnimationView animView = new DisappearAnimationView(this);
rootLayout.addView(animView, new ViewGroup.LayoutParams(
    ViewGroup.LayoutParams.MATCH_PARENT, 
    ViewGroup.LayoutParams.MATCH_PARENT
));

Для повышения производительности в манифесте нужно включить аппаратное ускорение - android:hardwareAccelerated="true".

Выводы

Добавление таких красивых эффектов делает приложение живым и запоминающимся. Вместо скучного исчезновения текста пользователь видит классную анимацию, которая превращает обычное удаление сообщения в маленькое эстетическое удовольствие. Это создает ощущение премиального продукта, над которым по-настоящему старались. Такие детали вызывают у пользователей "вау-эффект", повышают доверие к приложению и заставляют пользователя возвращаться в него снова просто потому, что им приятно пользоваться.

Ниже представлено демо видео примера как работает описанный мною выше код.

Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.