SDK рдкрд░ рдЖрд╢рд╛ рдХрд░реЗрдВ рдФрд░ рдЧрд▓рдд рди рдХрд░реЗрдВ: рдмреЙрдЯрдорд╢реАрдЯрдмрд╣реЗрд╡рд┐рдпрд░ рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рд╕реНрдХреНрд░реЙрд▓ рдХреА рд╕рдорд╕реНрдпрд╛

рд╢рд╛рдпрдж рд╣рд░ рдХреЛрдИ, рд╕реБрдВрджрд░ рдЦрд┐рдбрд╝рдХрд┐рдпреЛрдВ, рдЯреВрд▓рдмрд╛рд░ рдФрд░ рдЕрдиреНрдп рджреГрд╢реНрдпреЛрдВ рдХреЛ рдЬрд╛рджреБрдИ рд░реВрдк рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рджрд┐рд╢рд╛рдУрдВ рдореЗрдВ рдЖрдЧреЗ рдмрдврд╝рд╛рддреЗ рд╣реБрдП рдирд┐рд╣рд╛рд░рддрд╛ рд╣реИ, рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рд╢рд╛рдпрдж рд╕рдордиреНрд╡рдпрдХ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рднреА рдкрдврд╝реЗрдВ, рд╡рд┐рднрд┐рдиреНрди рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ, рдЬреЛ рдЖрдкрдХреЛ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╢рд╛рдмреНрджрд┐рдХ рдЬрд╛рджреВ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдмреЗрд╢рдХ, рдЖрдк рдЗрдЪреНрдЫрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд╕рд╛рде рдХрд╕реНрдЯрдо рджреГрд╢реНрдп рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХреЗрд╡рд▓ рдЖрдкрдХреА рдХрд▓реНрдкрдирд╛ рдпрд╛ рдПрдВрдбреНрд░реЙрдЗрдб рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рдЖрдкрдХреЗ рдЬреНрдЮрд╛рди рддрдХ рд╕реАрдорд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдПрдХ рдФрд░ рд╕реАрдорд╛ рд╣реИ - рд╕рдордп, рдЖрдкрдиреЗ рд╣реИрдХрдереЙрди рдкрд░ рдХрд╕реНрдЯрдо рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рд▓рд┐рдЦреЗ рд╣реИрдВ, рдПрдХ рд╕рдордпрдмрджреНрдз рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ, рдФрд░ рдХрд╕реНрдЯрдо рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд╕рд╛рде рдЕрдЧреНрд░рд┐рдо рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рдирд┐рд░реНрдгрдпреЛрдВ рдХреЛ рдХрдо рд╕рдордп рдореЗрдВ рдЯреАрдо рдХреЗ рд╕рджрд╕реНрдпреЛрдВ рджреНрд╡рд╛рд░рд╛ рдорд╣рд╛рд░рдд рд╣рд╛рд╕рд┐рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рддрдм рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдФрд░ рд╕рдмрд╕реЗ рддрд╛рд░реНрдХрд┐рдХ рд╕рдорд╛рдзрд╛рди рдЖрддрд╛ рд╣реИ - рджрд┐рдЦрд╛рд╡рд╛ рди рдХрд░реЗрдВ, рдорд╛рдирдХ рдПрдВрдбреНрд░реЙрдЗрдб рдЯреВрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрд╕реНрдорд╛рд░реНрдЯ рд▓реЛрдЧ рд╡рд╣рд╛рдВ рдмреИрдареЗ рд╣реИрдВ, рд╕рдм рдХреБрдЫ рдЪреЙрдХрд▓реЗрдЯ рдореЗрдВ рд╣реЛрдЧрд╛ (рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ, рдпрд╛ рдЕрдиреНрдп рдПрдВрдбреНрд░реЙрдЗрдб рдорд┐рдард╛рдИ рдореЗрдВ)ред


рд▓реЗрдХрд┐рди рдирд╣реАрдВ рд╕рдм рдХреБрдЫ, рдмрд╣реБрдд рдЖрд╕рд╛рди рд╣реИ рдпрд╣ рд╡рд╣ рдЬрдЧрд╣ рд╣реИ рдЬрд╣рд╛рдБ CoordinatorLayout рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рд▓реЛрдЧреЛрдВ рдХреЗ рдЬрд╛рджреВ рдХреЗ рд╕рд╛рде рдореЗрд░реЗ рдХрд░реАрдмреА рдкрд░рд┐рдЪрд┐рдд, BottomSheetBehavior рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдпрд╛ рдмрд▓реНрдХрд┐ рдПрдХ рдмрдЧ рдХреЗ рд╕рд╛рде рдХрд┐ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЕрдирджреЗрдЦреА рдХреА, рдЬрдм рд╡реЗ рдЙрдиреНрд╣реЗрдВ рд▓рд┐рдЦрд╛ рдерд╛ред рд▓реЗрдЦ рдмреЙрдЯрд╕реН рд╕реНрдХреНрд░реЙрд▓рд┐рдВрдЧ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдмрдЧ рдХреА рдкрд╣рдЪрд╛рди рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрддрд╛рдПрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдмреЙрдЯрдорд╢реАрдЯрдмрд╣реЗрд╡рд┐рдпрд░ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред


рд╕рдордиреНрд╡рдпрдХ рд▓реЗрдЖрдЙрдЯ рдПрдиреАрдореЗрд╢рди


рдкрд╣рд▓реА рдмреИрдардХ


рдореЗрд░рд╛ рдХрд╛рдо рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рд╕реНрдХреНрд░реЙрд▓ рдХреЗ рд╕рд╛рде рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрдирд╛рдирд╛ рдерд╛, рдЬрд┐рд╕рдореЗрдВ рдХреНрд╖реИрддрд┐рдЬ RecyclerView, ScrollView рдФрд░ CoordinatorLayout рд╢рд╛рдорд┐рд▓ рдереЗ, рдпрд╣ рд╡рд╣ рд╣реИ рдЬреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░рддрд╛ рд╣реИ, рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЗ рдиреЗрд╕реНрдЯреЗрдб рд╡рд┐рдЪрд╛рд░реЛрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджреЗрд╢рд┐рдд, рд╡рд┐рднрд┐рдиреНрди рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рд╕реБрдЪрд╛рд░реВ рдордирдорд╛рдиреЗ рдкрд╛рд░рд┐рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрд░реЛрдмрд┐рдХ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдПред


рдЙрджреНрджреЗрд╢реНрдп рдПрдиреАрдореЗрд╢рди


: CoordinatorLayout, , RecyclerView, android.material BottomSheetBehavior, , . item- , TextView тАФ item-, NestedScrollView, ( TextView).


NestedScrollViewMeme


activity_main.xml


<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="false"
        app:behavior_hideable="false"
        app:behavior_peekHeight="80dp"
        app:layout_behavior="com.google.android.material.bottomsheet.BottomSheetBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

recycler_item.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item_bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="?attr/colorControlHighlight"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="80dp"
        android:background="@color/colorAccent"
        android:text="@string/head_text"
        android:textAlignment="center"
        android:textColor="@android:color/white"
        android:textSize="24sp" />

    <androidx.core.widget.NestedScrollView
        android:id="@+id/scroll_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:id="@+id/item_text_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAlignment="center"
            android:textSize="24sp" />
    </androidx.core.widget.NestedScrollView>
</LinearLayout>

NestedScrollView? , Android, , ScrollView, , , , .


layout, RecyclerView.Adapter RecyclerView.ViewHolder, , , ...


RecyclerViewAdapter.kt


import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

class RecyclerViewAdapter(private val context: Context, private val itemList: List<ItemModel>) :
    RecyclerView.Adapter<RecyclerViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        return RecyclerViewHolder.create(context, parent)
    }

    override fun getItemCount() = itemList.size

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        holder.bind(itemList[position])
    }
}

RecyclerViewHolder.kt


import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.widget.NestedScrollView
import androidx.recyclerview.widget.RecyclerView

class RecyclerViewHolder(view: View) : RecyclerView.ViewHolder(view) {

    fun bind(model: ItemModel) {
        val textView: TextView = itemView.findViewById(R.id.item_text_view)
        val scrollView = itemView.findViewById(R.id.scroll_view) as NestedScrollView
        textView.text = ""
        for (i in 1..50) {
            textView.append(model.number.toString() + "\n")
        }
    }

    companion object {
        fun create(context: Context, parent: ViewGroup): RecyclerViewHolder {
            return RecyclerViewHolder(
                LayoutInflater.from(context).inflate(
                    R.layout.recycler_item,
                    parent,
                    false
                )
            )
        }
    }
}

ItemModel.kt


data class ItemModel(val number: Int)

MainActvity.kt


import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

    private val itemList = arrayListOf<ItemModel>().apply {
        for (i in 0..100) {
            this.add(ItemModel(i))
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        recycler_view.layoutManager =
            LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
        recycler_view.adapter = RecyclerViewAdapter(this, itemList)
    }
}

, , , тАж ? , NestedScrollView , ? recycler item, тАж тАж item- , , item-. RecyclerView, тАФ View, Recycler , . , - NestedScrollView, .



, тАФ item- . onScrollChange:


scrollView.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
    Log.i("TAG", "OnScrollChange")
}

item , тАж , - , :


scrollView.setOnTouchListener { view, motionEvent ->
    Log.i("TAG", motionEvent.toString())
    false
}

, , , , , , , , , , - - , , .



Interceptmeme


, , . ? , NestedScrollView OnTouch. item-:


itemView.setOnTouchListener { view, motionEvent ->
    Log.i("TAG", motionEvent.toString())
    false
}

. , recycler, , . : CoordinatorLayout, тАФ item-, .


, CoordinatorLayout, , , тАФ CoordinatorLayout, , FrameLayout. , RecyclerView material тАФ BottomSheetBehavior. , , .


BottomSheetBehavior


BottomSheetBehavior тАФ java , CoordinatorLayout.Behavior, (CoordinatorLayout). , , . ? BottomSheetBehavior TestBehavior, , , -. RecyclerView .

TestBehavior.java


import android.content.Context;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.bottomsheet.BottomSheetBehavior;

public class TestBehavior<V extends View> extends BottomSheetBehavior<V> {

    public TestBehavior(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(@NonNull CoordinatorLayout parent, @NonNull V child, @NonNull MotionEvent event) {
        Log.i("TAG", "onInterceptTouchEvent");
        return super.onInterceptTouchEvent(parent, child, event);
    }

    @Override
    public void onRestoreInstanceState(
            @NonNull CoordinatorLayout parent, @NonNull V child, @NonNull Parcelable state) {
        Log.i("TAG", "onRestoreInstanceState");
        super.onRestoreInstanceState(parent, child, state);
    }

    @Override
    public void onAttachedToLayoutParams(@NonNull CoordinatorLayout.LayoutParams layoutParams) {
        Log.i("TAG", "onAttachedToLayoutParams");
        super.onAttachedToLayoutParams(layoutParams);
    }

    @Override
    public void onDetachedFromLayoutParams() {
        Log.i("TAG", "onDetachedFromLayoutParams");
        super.onDetachedFromLayoutParams();
    }

    @Override
    public boolean onLayoutChild(
            @NonNull CoordinatorLayout parent, @NonNull V child, int layoutDirection) {
        Log.i("TAG", "onLayoutChild");
        return super.onLayoutChild(parent, child, layoutDirection);
    }

    @Override
    public boolean onTouchEvent(
            @NonNull CoordinatorLayout parent, @NonNull V child, @NonNull MotionEvent event) {
        Log.i("TAG", "onTouchEvent " + event.toString());
        return super.onTouchEvent(parent, child, event);
    }

    @Override
    public boolean onStartNestedScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View directTargetChild,
            @NonNull View target,
            int axes,
            int type) {
        Log.i("TAG", "onStartNestedScroll");
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
    }

    @Override
    public void onNestedPreScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View target,
            int dx,
            int dy,
            @NonNull int[] consumed,
            int type) {
        Log.i("TAG", "onNestedPreScroll");
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
    }

    @Override
    public void onStopNestedScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View target,
            int type) {
        Log.i("TAG", "onStopNestedScroll");
        super.onStopNestedScroll(coordinatorLayout, child, target, type);
    }

    @Override
    public void onNestedScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View target,
            int dxConsumed,
            int dyConsumed,
            int dxUnconsumed,
            int dyUnconsumed,
            int type,
            @NonNull int[] consumed) {
        Log.i("TAG", "onNestedScroll");
        super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, type, consumed);
    }

    @Override
    public boolean onNestedPreFling(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View target,
            float velocityX,
            float velocityY) {
        Log.i("TAG", "onNestedPreFling");
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }
}

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="false"
        app:behavior_hideable="false"
        app:behavior_peekHeight="80dp"
        app:layout_behavior=".TestBehavior" />

. item- : onInterceptTouchEvent, onStartNestedScroll, onNestedPreScroll, onNestedScroll, onStopNestedScroll. : onInterceptTouchEvent, onStartNestedScroll, onNestedPreScroll, onStopNestedScroll. , onNestedPreScroll . onNestedPreScroll BottomSheetBehavior , , , :


View scrollingChild = nestedScrollingChildRef != null ? nestedScrollingChildRef.get() : null;
if (target != scrollingChild) {
  return;
}

, nestedScrollingChildRef? View, View, CoordinatorLayout View, .


  @Nullable WeakReference<View> nestedScrollingChildRef;

, onLayoutChild:


  @Override
  public boolean onLayoutChild(
      @NonNull CoordinatorLayout parent, @NonNull V child, int layoutDirection) {
      ...
      nestedScrollingChildRef = new WeakReference<>(findScrollingChild(child));
      return true;
  }

Recycler, , item, View, BottomSheetBehavior, , , View , , тАФ . , .



, ? - view Recycler-, , , BottomSheetBehavior , , : (: , ) Java Reflection API. , .


Java Reflection API


Reflectionmeme


Java Reflection API, TestBeahvior, Runtime , , , onStartNestedScroll, onNestedPreScroll.


import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.coordinatorlayout.widget.CoordinatorLayout;

import com.google.android.material.bottomsheet.BottomSheetBehavior;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;

public class TestBeahvior<V extends View> extends BottomSheetBehavior<V> {

    public TestBeahvior(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    public boolean onStartNestedScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View directTargetChild,
            @NonNull View target,
            int axes,
            int type) {
        try {
            Field nestedScrollingChildRefField = this.getClass().getSuperclass().getDeclaredField("nestedScrollingChildRef");
            nestedScrollingChildRefField.setAccessible(true);
            nestedScrollingChildRefField.set(this, new WeakReference<>(target));
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, axes, type);
    }
}


рдпрд╣рд╛рдВ рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рдмреЙрдЯрдорд╢реАрдЯрдмрд┐рд╣реЗрд╡рд┐рдпрд░ рдХреНрд▓рд╛рд╕ рдХреЛ рдХреЙрдкреА рдХрд░реЗрдВ, рдкреНрд░рд╛рдЗрд╡реЗрдЯ рдореЗрдердб рдХреЛ рд░рд┐рдлреНрд░реЗрд╢ рдХрд░реЗрдВред рдиреЗрдХрд╛рдВрд╕реНрдХреНрд░реЛрд▓рд┐рдВрдЧрдЪрд┐рд▓реНрдбрд░рдл, рдЬреЛ рд▓рд┐рдВрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдХрдВрдЯреЗрдВрдЯ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдЧрд╛, рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдСрдирд╕реНрдЯрд╛рд░реНрдЯрдиреИрд╕реНрдЯрдХреНрд▓рд╛рдЗрдВрдб рдореЗрдердб рдореЗрдВ рдХреЙрд▓ рдХрд░реЗрдВред рд╣реЛ рдЧрдпрд╛, рд╕рдм рдХреБрдЫ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред


private void refreshNestedScrollingChildRef(View view) {
    nestedScrollingChildRef = new WeakReference<>(view);
}

    @Override
    public boolean onStartNestedScroll(
            @NonNull CoordinatorLayout coordinatorLayout,
            @NonNull V child,
            @NonNull View directTargetChild,
            @NonNull View target,
            int axes,
            int type) {
        refreshNestedScrollingChildRef(target);
        ...
    }

рдирд┐рд╖реНрдХрд░реНрд╖


рдПрдВрдбреНрд░реЙрдЗрдб рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХрдИ рд╢рд╛рдВрдд рдФрд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдХрд░рдг рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╡реЗ рд╕рднреА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рддреБрдо рд╣рдореЗрд╢рд╛ рдПрдХ рдорд╛рдорд▓рд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдорд╛рдирдХ рдЙрдкрдХрд░рдг рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╕рднреА рджрд┐рд▓рдЪрд╕реНрдк рдорд╛рдорд▓реЛрдВ!

Source: https://habr.com/ru/post/undefined/


All Articles