Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
Используйте
ObjectAnimator для анимации свойств объектов.ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationX", 0f, 100f);
animation.setDuration(1000);
animation.start();
Используйте XML-анимации для представлений. XML-анимация (res/anim/slide_in.xml)
<translate xmlns:android="https://schemas.android.com/apk/res/android"
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="500" />
Применение анимации
Animation animation = AnimationUtils.loadAnimation(context, R.anim.slide_in);
view.startAnimation(animation);
Используйте анимации кадров для изображений. Анимация кадров (res/drawable/animation.xml)
<animation-list xmlns:android="https://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="@drawable/frame1" android:duration="50" />
<item android:drawable="@drawable/frame2" android:duration="50" />
</animation-list>
Применение анимации
ImageView imageView = findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.animation);
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.start();
Используйте
MotionLayout для сложных анимаций. XML (res/layout/activity_main.xml)<androidx.constraintlayout.motion.widget.MotionLayout
xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/scene">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image" />
</androidx.constraintlayout.motion.widget.MotionLayout>
MotionScene (res/xml/scene.xml)
<MotionScene xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto">
<Transition app:constraintSetStart="@+id/start" app:constraintSetEnd="@+id/end" app:duration="1000">
<OnSwipe app:dragDirection="dragUp" app:touchAnchorId="@+id/imageView" />
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@+id/imageView" app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@+id/imageView" app:layout_constraintBottom_toBottomOf="parent" />
</ConstraintSet>
</MotionScene>
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Это набор библиотек, инструментов и рекомендаций от Google, предназначенных для упрощения разработки высококачественных Android-приложений. Jetpack помогает разработчикам следовать лучшим практикам, сокращает количество шаблонного кода и делает разработку проще и быстрее.
AppCompat: Обратная совместимость с более старыми версиями Android.
Android KTX: Расширения для упрощения написания кода на Kotlin.
Multidex: Поддержка многодексных APK.
LiveData: Компонент для наблюдения за изменениями данных.
ViewModel: Управление данными UI с учётом жизненного цикла.
Room: Библиотека для работы с базой данных SQLite с использованием объектов.
WorkManager: Управление фоновыми задачами с учетом условий выполнения.
Navigation: Упрощает навигацию и управление фрагментами.
Paging: Загрузка данных постранично.
DataStore: Современная и более гибкая альтернатива SharedPreferences.
CameraX: Упрощение работы с камерой.
RecyclerView: Эффективное отображение больших списков.
Fragment: Управление фрагментами.
ConstraintLayout: Современный способ создания гибких и сложных макетов.
Jetpack Compose: Современная декларативная библиотека для создания UI.
Jetpack снижает количество шаблонного кода, что ускоряет процесс разработки.
Библиотеки Jetpack созданы с учётом лучших практик Android-разработки.
Многие библиотеки Jetpack поддерживают обратную совместимость, что позволяет использовать их на более старых версиях Android.
Библиотеки обновляются через Google Play, что позволяет использовать последние версии без обновления всей системы.
// ViewModel class
class MyViewModel : ViewModel() {
private val _data = MutableLiveData<String>()
val data: LiveData<String> get() = _data
fun updateData(newData: String) {
_data.value = newData
}
}
// Fragment or Activity
class MyFragment : Fragment() {
private lateinit var viewModel: MyViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_my, container, false)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
viewModel.data.observe(viewLifecycleOwner, Observer { newData ->
// Обновление UI
})
return view
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍2
Управляет данными UI с учётом жизненного цикла.
class MyViewModel : ViewModel() {
val data: MutableLiveData<String> = MutableLiveData()
}Наблюдаемые данные, автоматически обновляющиеся при изменениях.
val data: LiveData<String> = viewModel.data
data.observe(this, Observer { value ->
// Обновление UI
})
Работа с базой данных SQLite.
@Entity
data class User(@PrimaryKey val uid: Int, val firstName: String?, val lastName: String?)
@Dao
interface UserDao {
@Query("SELECT * FROM user")
fun getAll(): List<User>
@Insert
fun insertAll(vararg users: User)
}
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
}
Управление фоновыми задачами.
val uploadWorkRequest: WorkRequest = OneTimeWorkRequestBuilder<UploadWorker>().build()
WorkManager.getInstance(context).enqueue(uploadWorkRequest)
Привязка данных к элементам UI.
<layout xmlns:android="https://schemas.android.com/apk/res/android">
<data>
<variable name="viewModel" type="com.example.MyViewModel" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.data}" />
</LinearLayout>
</layout>
Постраничная загрузка данных.
val pager = Pager(PagingConfig(pageSize = 20)) {
UserPagingSource()
}.flow.cachedIn(viewModelScope) Навигация между компонентами приложения.
<fragment
android:id="@+id/firstFragment"
android:name="com.example.FirstFragment">
<action
android:id="@+id/action_firstFragment_to_secondFragment"
app:destination="@id/secondFragment" />
</fragment>
Современное хранилище данных.
val dataStore: DataStore<Preferences> = context.createDataStore(name = "settings")
val exampleCounter = dataStore.data.map { preferences -> preferences[EXAMPLE_COUNTER] ?: 0 }
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍3
Это библиотека в Android, которая позволяет связывать компоненты пользовательского интерфейса (UI) напрямую с источниками данных, снижая количество шаблонного кода.
Добавьте в файл
build.gradle модуляandroid {
...
viewBinding {
enabled = true
}
}В макете XML добавьте корневой элемент
<layout> и определите переменные данных:<!-- res/layout/activity_main.xml -->
<layout xmlns:android="https://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.example.MyViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.text}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.onButtonClick()}"
android:text="Click Me" />
</LinearLayout>
</layout>
Создайте ViewModel для управления данными:
// MyViewModel.kt
package com.example
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
class MyViewModel : ViewModel() {
private val _text = MutableLiveData("Hello, Data Binding!")
val text: LiveData<String> get() = _text
fun onButtonClick() {
_text.value = "Button Clicked!"
}
}
Инициализируйте Data Binding в вашей Activity и свяжите ViewModel с макетом:
// MainActivity.kt
package com.example
import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import com.example.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private val viewModel: MyViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
binding.viewModel = viewModel
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥2
Библиотека Lifecycle в Android Jetpack помогает управлять и контролировать жизненный цикл компонентов Android, таких как Activities и Fragments. Она упрощает создание компонентов, которые осведомлены о своем жизненном цикле и могут корректно реагировать на изменения в нем. Это позволяет избегать утечек памяти и некорректной работы компонентов при изменении конфигураций или переходах между состояниями.
Это интерфейс, который определяет класс как владеющий жизненным циклом. Activity и Fragment уже реализуют этот интерфейс.
class MyActivity : AppCompatActivity(), LifecycleOwner {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
}Это интерфейс, который позволяет классу наблюдать за изменениями в жизненном цикле компонента. Методы, аннотированные
@OnLifecycleEvent, будут вызываться при соответствующих событиях жизненного цикла.class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
// Код, который выполняется при старте жизненного цикла
Log.d("MyObserver", "onStart called")
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
// Код, который выполняется при остановке жизненного цикла
Log.d("MyObserver", "onStop called")
}
}Это класс, который содержит информацию о текущем состоянии и позволяет другим объектам наблюдать за изменениями в жизненном цикле.
class MyActivity : AppCompatActivity() {
private lateinit var myObserver: MyObserver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myObserver = MyObserver()
lifecycle.addObserver(myObserver)
}
}dependencies {
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
}class MyObserver : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume() {
Log.d("MyObserver", "Activity resumed")
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
Log.d("MyObserver", "Activity paused")
}
}class MyActivity : AppCompatActivity() {
private lateinit var myObserver: MyObserver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
myObserver = MyObserver()
lifecycle.addObserver(myObserver)
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍5
Автоматически управлять изменениями состояния компонентов.
Удалять ненужные ссылки на объекты при уничтожении Activity или Fragment.
Разделить код на логические модули и облегчить тестирование.
Интеграция с LiveData и ViewModel для реактивного подхода.
Уменьшить количество ручного кода для управления состояниями.
Без Lifecycle
public class MyActivity extends AppCompatActivity {
private MyAsyncTask myTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTask = new MyAsyncTask();
myTask.execute();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (myTask != null) {
myTask.cancel(true);
}
}
private static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... voids) {
return null;
}
}
}С Lifecycle
public class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getLifecycle().addObserver(new MyLifecycleObserver());
}
public class MyLifecycleObserver implements LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_START)
public void onStart() {
// Код запуска задач
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
public void onStop() {
// Код остановки задач
}
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁2
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥1
Архитектура и дизайн: Определение архитектуры проекта и разработка технического дизайна.
Код-ревью: Проверка кода команды для обеспечения качества и соответствия стандартам.
Технические решения: Принятие ключевых решений по технологиям, инструментам и методам разработки.
Наставничество и обучение: Поддержка и обучение членов команды, проведение тренингов и воркшопов.
Оценка производительности: Оценка работы команды, предоставление обратной связи и помощь в профессиональном развитии.
Мотивация: Поддержание мотивации и хорошей рабочей атмосферы в команде.
Планирование и приоритизация: Определение приоритетов задач, планирование релизов и распределение ресурсов.
Управление сроками: Обеспечение выполнения проектов в срок, контроль за соблюдением дедлайнов.
Коммуникация с заинтересованными сторонами: Взаимодействие с клиентами, менеджерами проектов и другими заинтересованными сторонами для согласования требований и сроков.
Внедрение лучших практик: Обеспечение использования лучших практик разработки, таких как CI/CD, тестирование, кодирование и документирование.
Управление версиями: Контроль за версионностью проекта, внедрение и использование систем контроля версий (например, Git).
Инструменты и среды разработки: Настройка и поддержка инструментов и сред разработки для команды.
Идентификация и управление рисками: Определение возможных рисков и разработка стратегий их минимизации.
Решение технических проблем: Быстрое реагирование и решение технических проблем, возникающих в процессе разработки.
Понимание бизнес-требований: Глубокое понимание бизнес-требований и целей проекта.
Перевод бизнес-требований в технические: Трансформация бизнес-требований в технические задачи и спецификации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚Базу Знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2😁1
Колбеки фрагмента отличаются от колбеков Activity, так как фрагменты управляют отдельными частями пользовательского интерфейса, могут динамически добавляться или удаляться, и имеют свои специфичные методы (onCreateView(), onAttach(), и т.д.), в то время как Activity управляет жизненным циклом всего экрана.
Activity: Основные стадии - onCreate(), onStart(), onResume(), onPause(), onStop(), onDestroy().
Fragment: Дополнительные стадии - onAttach(), onCreateView(), onViewCreated(), onDestroyView(), onDetach().
Activity: Независимая единица интерфейса.
Fragment: Модульная часть внутри Activity.
Activity: Управляет своим представлением.
Fragment: Управляет своим представлением внутри Activity.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍2
Мои три любимые фичи в Kotlin: Extension Functions для добавления новых функций к существующим классам без их изменения, Null Safety для защиты от NullPointerException и упрощенного управления null-значениями, а также Coroutines для удобной работы с асинхронным кодом и многопоточностью, делая его более простым и понятным.
Одной из главных проблем при программировании на Java является
NullPointerException, который возникает при попытке использовать объект, равный null. Kotlin решает эту проблему на уровне языка. Это помогает избежать неожиданных ошибок и делает код более надежным. Программист явно указывает, когда переменная может быть null, что уменьшает количество ошибок, связанных с null-значениями.var name: String? = "Kotlin"
name = null // Это допустимо, так как тип переменной может быть null
var length = name?.length // Вернет длину строки или null, если name равно null
Kotlin позволяет добавлять новые методы к существующим классам без необходимости наследования или использования паттернов, таких как Decorator. Это улучшает читаемость и поддерживаемость кода, позволяя добавлять функциональность к существующим классам на лету, не нарушая их.
fun String.lastChar(): Char = this[this.length - 1]
val c = "Kotlin".lastChar() // Вернет 'n'
Корутины предоставляют простой и эффективный способ выполнения асинхронных задач. Они легче и удобнее в использовании по сравнению с традиционными потоками. Корутины упрощают написание асинхронного и параллельного кода, делая его более понятным и управляемым. Они обеспечивают неблокирующие операции, что улучшает производительность и отзывчивость приложений.
import kotlinx.coroutines.*
fun main() = runBlocking {
launch {
delay(1000L)
println("World!")
}
println("Hello,")
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍4
В Kotlin все классы по умолчанию наследуются от класса Any. Этот класс является корневым (базовым) классом для всех других классов в Kotlin. Он аналогичен классу Object в Java.
Наследование от Any обеспечивает всем классам базовые методы, такие как:
equals(): Проверка на равенство объектов.
hashCode(): Возвращает хэш-код объекта.
toString(): Возвращает строковое представление объекта.
Когда вы создаете класс в Kotlin, вам не нужно явно указывать, что он наследуется от Any — это происходит автоматически. Например:
class Person(val name: String, val age: Int)
Эквивалентно:
class Person(val name: String, val age: Int) : Any()
Вы можете переопределить методы Any, чтобы адаптировать их под свои нужды. Например, переопределим метод toString:
class Person(val name: String, val age: Int) {
override fun toString(): String {
return "Person(name=$name, age=$age)"
}
}
fun main() {
val person = Person("Alice", 30)
println(person.toString()) // Вывод: Person(name=Alice, age=30)
}Это нужно для обеспечения базовой функциональности всех объектов в языке. Например, метод equals позволяет сравнивать два объекта, а toString предоставляет удобный способ представления объекта в виде строки.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8