Sealed классы используются для представления ограниченного набора типов, похожих на перечисления, но с возможностью иметь классы с разными свойствами и методами. Это помогает обеспечить безопасное использование при работе с типами во время компиляции, улучшая обработку ошибок и логику ветвления.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5❤1
Создание активности. Вызывается при создании активности. Здесь инициализируются основные компоненты (например, настройка пользовательского интерфейса).
Активность становится видимой для пользователя. Вызывается после
onCreate и каждый раз, когда активность становится видимой.Активность становится доступной для взаимодействия с пользователем. Вызывается после
onStart и каждый раз, когда активность возвращается на передний план (например, после паузы).Активность перестает быть доступной для взаимодействия. Вызывается, когда активность переходит в состояние паузы (например, при открытии новой активности или диалога).
Активность становится невидимой для пользователя. Вызывается, когда активность больше не видна (например, при переходе к другой активности).
Уничтожение активности. Вызывается перед окончательным уничтожением активности. Здесь освобождаются ресурсы.
Активность снова становится активной после остановки. Вызывается после
onStop, перед onStart.Сохранение состояния активности. Вызывается перед уничтожением активности для сохранения ее текущего состояния.
Восстановление состояния активности. Вызывается после
onStart, если активность была ранее уничтожена и существует сохраненное состояние.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Async используется для запуска сопрограммы, которая возвращает Deferred — промис для результата. Await используется для получения этого результата, при этом ожидание результата suspend'ит (приостанавливает) текущую сопрограмму до его получения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥4
Фрагменты предназначены для повторного использования интерфейса и логики. Разделение методов
onCreate и onCreateView позволяет разделить код, связанный с настройкой фрагмента, и код, связанный с созданием и настройкой пользовательского интерфейса.onCreate: Используется для выполнения общей логики фрагмента, такой как инициализация переменных, настройка адаптеров и других объектов, которые не зависят от представления.onCreateView: Используется для создания и настройки пользовательского интерфейса фрагмента, включая инфлейтинг макета и инициализацию виджетов.Фрагменты могут использоваться в разных макетах для разных устройств (например, планшеты и телефоны) или ориентаций экрана (портретный и ландшафтный режимы). Использование
onCreateView позволяет гибко создавать и настраивать пользовательский интерфейс в зависимости от текущей конфигурации устройства.Фрагменты могут быть добавлены или заменены динамически в различных контейнерах активностей. Метод
onCreateView позволяет гибко создавать интерфейс каждый раз, когда фрагмент добавляется или заменяется.class MyFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Инициализация логики фрагмента, например, настройка адаптера
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Инфлейтинг макета для фрагмента
val view = inflater.inflate(R.layout.fragment_layout, container, false)
// Инициализация элементов пользовательского интерфейса
val textView: TextView = view.findViewById(R.id.textView)
textView.text = "Hello, World!"
return view
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Выбор макета для фрагмента осуществляется в методе
onCreateView с помощью LayoutInflateroverride fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_example, container, false)
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3👍1
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Для списка из большого количества элементов следует использовать
RecyclerView. Это наиболее эффективный и рекомендуемый компонент для отображения больших данных в виде списка или сетки в Android.RecyclerView использует механизм повторного использования (рециклинга) элементов, что значительно повышает производительность при работе с большими наборами данных.Поддержка различных компоновок через
LayoutManager (например, LinearLayoutManager, GridLayoutManager, StaggeredGridLayoutManager).Простая интеграция анимаций для добавления, удаления и перемещения элементов.
Возможность добавления специальных эффектов и декораций, таких как разделители и отступы.
RecyclerView в XML макет<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
RecyclerViewpublic class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private List<String> data;
public MyAdapter(List<String> data) {
this.data = data;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.list_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
String item = data.get(position);
holder.textView.setText(item);
}
@Override
public int getItemCount() {
return data.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView textView;
public ViewHolder(View view) {
super(view);
textView = view.findViewById(R.id.textView);
}
}
}RecyclerView в Activity или Fragmentpublic class MyActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
List<String> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("Item " + i);
}
MyAdapter adapter = new MyAdapter(data);
recyclerView.setAdapter(adapter);
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5😁4
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
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