Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Forwarded from Идущий к IT
Твое резюме на HeadHunter — ОК, если ты видишь это.
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
HeadHunter сравнивает ключевые навыки в твоем резюме и в вакансии и в момент отклика отображает, насколько % ты соответствуешь требованиям.
Специальный бейджик «Подходит по навыкам на 100%» отображается, если соответствие составляет более 60%.
Если при просмотре вакансий ты видишь такой бейджик, это значит, что список навыков в твоем резюме качественно составлен.
Это важный параметр, так как рекрутерам чаще показываются резюме с лучшим соответствием.
О том, как правильно указывать ключевые навыки и оптимизировать свое резюме я уже рассказывал в этом видео
ItemDecoration в RecyclerView позволяет добавлять украшения (декорации) к элементам списка. Это может включать в себя отступы, разделительные линии, рамки и любые другие визуальные элементы, которые не являются частью содержимого элементов списка.Вы можете добавлять отступы (margin) между элементами списка, чтобы улучшить визуальное разделение.
Легко добавлять разделительные линии между элементами списка, что делает его более читаемым.
Позволяет рисовать фоновые элементы, такие как цветные блоки или изображения, за элементами списка.
Добавление разделительных линий между элементами
class DividerItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private val divider: Drawable? = ContextCompat.getDrawable(context, R.drawable.line_divider)
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
val left = parent.paddingLeft
val right = parent.width - parent.paddingRight
val childCount = parent.childCount
for (i in 0 until childCount - 1) {
val child = parent.getChildAt(i)
val params = child.layoutParams as RecyclerView.LayoutParams
val top = child.bottom + params.bottomMargin
val bottom = top + (divider?.intrinsicHeight ?: 0)
divider?.setBounds(left, top, right, bottom)
divider?.draw(c)
}
}
}Применение
ItemDecoration в RecyclerViewval recyclerView: RecyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = MyAdapter(data)
recyclerView.addItemDecoration(DividerItemDecoration(this, LinearLayoutManager.VERTICAL))
Добавление отступов между элементами
class SpacesItemDecoration(private val space: Int) : RecyclerView.ItemDecoration() {
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
outRect.left = space
outRect.right = space
outRect.bottom = space
// Добавляем верхний отступ только для первого элемента, чтобы избежать двойного отступа между элементами
if (parent.getChildAdapterPosition(view) == 0) {
outRect.top = space
}
}
}Применение
SpacesItemDecoration в RecyclerViewval recyclerView: RecyclerView = findViewById(R.id.recyclerView)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = MyAdapter(data)
recyclerView.addItemDecoration(SpacesItemDecoration(16)) // 16 пикселей отступа
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2😁1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥2
DefaultItemAnimator для стандартных анимаций
recyclerView.setItemAnimator(new DefaultItemAnimator());
Custom ItemAnimator для пользовательских анимаций
public class CustomItemAnimator extends DefaultItemAnimator {
@Override
public boolean animateRemove(RecyclerView.ViewHolder holder) {
holder.itemView.animate().alpha(0).setDuration(300).start();
return super.animateRemove(holder);
}
}
recyclerView.setItemAnimator(new CustomItemAnimator());Анимации в Adapter для анимаций элементов
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemView.setAlpha(0);
holder.itemView.animate().alpha(1).setDuration(500).start();
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1👍1👀1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
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