WedX - журнал о программировании и компьютерных науках

Android — панель инструментов поднимается выше строки состояния при прокрутке списка

Я пытаюсь скрыть панель инструментов при прокрутке списка, используя макет координатора. Я использовал app:layout_scrollFlags="scroll|enterAlways" на панели инструментов и android:nestedScrollingEnabled="true" в списке.

Панель инструментов корректно скрывается, когда я прокручиваю свой список, но она идет «выше» строки состояния. В терминологии веб-разработки это выглядит так, будто «Z-индекс» панели инструментов выше, чем строка состояния. Вот как это выглядит -

введите здесь описание изображения Панель инструментов над строкой состояния

Вот мой activity_main.xml

<android.support.design.widget.CoordinatorLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    xmlns:app="https://schemas.android.com/apk/res-auto" android:id="@+id/main_content"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:fitsSystemWindows="true" tools:context=".MainActivity"
    android:background="#FFFFFF" >

    <android.support.design.widget.AppBarLayout android:id="@+id/appbar"
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar android:id="@+id/toolbar"
            android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"
            app:layout_scrollFlags="scroll|enterAlways" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager android:id="@+id/container"
        android:layout_width="match_parent" android:layout_height="match_parent"
        android:background="#FFFFFF"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>

Вот мой код fragment_main.xml

<RelativeLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollingCache="false"
        android:nestedScrollingEnabled="true" />

</RelativeLayout>

Как решить эту проблему? Заранее спасибо!

ОБНОВЛЕНИЕ: я разместил свой ответ ниже! Проверьте принятый ответ.


  • Возможности прокрутки не поддерживаются в ListView для нового CoordinatorLayout. Вместо этого вы должны использовать RecyclerView. 06.12.2015

Ответы:


1

Я наконец исправил это. Если кто-то еще застрял здесь, вот как я это исправил. Не нужно менять макеты на Recyclerview и все такое! Вот шаги.

1) Установите для fitsSystemWindows значение false для CoordinatorLayout.

android:fitsSystemWindows="false"

2) Теперь моя строка состояния стала белой. Чтобы исправить это, добавьте следующие строки в метод onCreate в MainActivity.java.

Window window = getWindow();

// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);

// finally change the color
window.setStatusBarColor(getResources().getColor(R.color.colorPrimaryDark));

Вуаля! Теперь все работает идеально.

Вот мое содержимое activity_main.xml, если я что-то пропустил.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:ads="https://schemas.android.com/apk/res-auto"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="false"
    tools:context=".MainActivity">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay"
        app:contentScrim="@color/colorPrimaryDark"
        app:layout_scrollFlags="scroll|enterAlways">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/AppTheme.PopupOverlay"
            app:layout_scrollFlags="scroll|enterAlways" />

        <android.support.design.widget.TabLayout android:id="@+id/tabs"
            android:layout_width="match_parent" android:layout_height="wrap_content"
            app:tabIndicatorColor="@android:color/white"
            app:tabIndicatorHeight="3dp"
            android:textStyle="bold"/>

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FFFFFF"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

13.05.2016
  • Я думаю, что это может быть более простым ответом на то, что вы пытаетесь сделать: stackoverflow.com/questions/33989984/ 10.09.2016
  • @Amit Но это только изменит цвет строки состояния на сплошной. Как иметь градиентные цвета в строке состояния 19.07.2020

  • 2

    Почему у вас есть макет AppBarlayout и toolbar, если вам не нужна панель инструментов, которая расширяется и сжимается? в основном, AppBarlayout используется, когда кто-то хочет, чтобы он расширялся и сжимался, и он используется с android.support.v4.widget.NestedScrollView, поэтому есть вероятность, что проблема возникает оттуда, они несовместимы, вы можете использовать android.support.v7.widget.RecyclerView вместо listview, а viewpager имеет атрибут appbar_scrolling_view_behavior, который запускает appbarlayout, чтобы начать прослушивание входных данных прокрутки, я архивирую панель инструментов с нормальным поведением, не имея AppBarlayout, а только toolbar, чтобы вы могли удалить AppBarlayout, глядя на вещи, которые на самом деле не нужны, так как вы хотите, чтобы это расширять и сокращать ниже — пример того, как должен выглядеть ваш код.

    <FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    
    
    
    
        <android.support.v7.widget.RecyclerView
        android:id="@+id/scrollableview"
        android:layout_width="match_parent"
        android:visibility="gone"
        android:background="#FFFFFF"
        android:paddingTop="?attr/actionBarSize"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />
    
        <!-- Your content, maybe a ListView? -->
        <android.support.design.widget.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"
        android:id="@+id/fabAddItem"
        android:src="@drawable/ic_action_add"
        app:backgroundTint="@color/google_lightblue"
        app:layout_anchor="@+id/toolbar"
        app:layout_anchorGravity="bottom|right|end" />
    
        <aubry.chromio.com.dressup.view.CollapsingTitleLayout
        android:id="@+id/backdrop_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
        app:expandedTextSize="40dp"
        app:expandedMargin="16dp">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_height="?attr/actionBarSize"
            android:layout_width="match_parent" />
    
    </aubry.chromio.com.dressup.view.CollapsingTitleLayout>
    
    </FrameLayout>
    

    а вот мой CollapingsTitleLayout

     import android.content.Context;
        import android.content.res.TypedArray;
        import android.graphics.Bitmap;
        import android.graphics.Canvas;
        import android.graphics.Color;
        import android.graphics.Paint;
        import android.graphics.Rect;
        import android.os.Build;
        import android.support.v4.view.ViewCompat;
        import android.support.v7.widget.Toolbar;
        import android.text.TextPaint;
        import android.text.TextUtils;
        import android.util.AttributeSet;
        import android.util.DisplayMetrics;
        import android.util.TypedValue;
        import android.view.View;
        import android.view.ViewGroup;
        import android.view.animation.AnimationUtils;
        import android.view.animation.Interpolator;
        import android.widget.FrameLayout;
    
        import aubry.chromio.com.dressup.R;
    
    
     public class CollapsingTitleLayout extends FrameLayout {
    
    // Pre-JB-MR2 doesn't support HW accelerated canvas scaled text so we will workaround it
    // by using our own texture
    private static final boolean USE_SCALING_TEXTURE = Build.VERSION.SDK_INT < 18;
    
    private static final boolean DEBUG_DRAW = false;
    private static final Paint DEBUG_DRAW_PAINT;
    static {
        DEBUG_DRAW_PAINT = DEBUG_DRAW ? new Paint() : null;
        if (DEBUG_DRAW_PAINT != null) {
            DEBUG_DRAW_PAINT.setAntiAlias(true);
            DEBUG_DRAW_PAINT.setColor(Color.MAGENTA);
        }
    }
    
    private Toolbar mToolbar;
    private View mDummyView;
    
    private float mScrollOffset;
    
    private final Rect mToolbarContentBounds;
    
    private float mExpandedMarginLeft;
    private float mExpandedMarginRight;
    private float mExpandedMarginBottom;
    
    private int mRequestedExpandedTitleTextSize;
    private int mExpandedTitleTextSize;
    private int mCollapsedTitleTextSize;
    
    private float mExpandedTop;
    private float mCollapsedTop;
    
    private String mTitle;
    private String mTitleToDraw;
    private boolean mUseTexture;
    private Bitmap mExpandedTitleTexture;
    
    private float mTextLeft;
    private float mTextRight;
    private float mTextTop;
    
    private float mScale;
    
    private final TextPaint mTextPaint;
    private Paint mTexturePaint;
    
    private Interpolator mTextSizeInterpolator;
    
    public CollapsingTitleLayout(Context context) {
        this(context, null);
    }
    
    public CollapsingTitleLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
    public CollapsingTitleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    
        mTextPaint = new TextPaint();
        mTextPaint.setAntiAlias(true);
    
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CollapsingTitleLayout);
    
        mExpandedMarginLeft = mExpandedMarginRight = mExpandedMarginBottom =
                a.getDimensionPixelSize(R.styleable.CollapsingTitleLayout_expandedMargin, 0);
    
        final boolean isRtl = ViewCompat.getLayoutDirection(this)
                == ViewCompat.LAYOUT_DIRECTION_RTL;
        if (a.hasValue(R.styleable.CollapsingTitleLayout_expandedMarginStart)) {
            final int marginStart = a.getDimensionPixelSize(
                    R.styleable.CollapsingTitleLayout_expandedMarginStart, 0);
            if (isRtl) {
                mExpandedMarginRight = marginStart;
            } else {
                mExpandedMarginLeft = marginStart;
            }
        }
        if (a.hasValue(R.styleable.CollapsingTitleLayout_expandedMarginEnd)) {
            final int marginEnd = a.getDimensionPixelSize(
                    R.styleable.CollapsingTitleLayout_expandedMarginEnd, 0);
            if (isRtl) {
                mExpandedMarginLeft = marginEnd;
            } else {
                mExpandedMarginRight = marginEnd;
            }
        }
        if (a.hasValue(R.styleable.CollapsingTitleLayout_expandedMarginBottom)) {
            mExpandedMarginBottom = a.getDimensionPixelSize(
                    R.styleable.CollapsingTitleLayout_expandedMarginBottom, 0);
        }
    
        final int tp = a.getResourceId(R.styleable.CollapsingTitleLayout_android_textAppearance,
                android.R.style.TextAppearance);
        setTextAppearance(tp);
    
        if (a.hasValue(R.styleable.CollapsingTitleLayout_collapsedTextSize)) {
            mCollapsedTitleTextSize = a.getDimensionPixelSize(
                    R.styleable.CollapsingTitleLayout_collapsedTextSize, 0);
        }
    
        mRequestedExpandedTitleTextSize = a.getDimensionPixelSize(
                R.styleable.CollapsingTitleLayout_expandedTextSize, mCollapsedTitleTextSize);
    
        final int interpolatorId = a
                .getResourceId(R.styleable.CollapsingTitleLayout_textSizeInterpolator,
                        android.R.anim.accelerate_interpolator);
        mTextSizeInterpolator = AnimationUtils.loadInterpolator(context, interpolatorId);
    
        a.recycle();
    
        mToolbarContentBounds = new Rect();
    
        setWillNotDraw(false);
    }
    
    public void setTextAppearance(int resId) {
        TypedArray atp = getContext().obtainStyledAttributes(resId,
                R.styleable.CollapsingTextAppearance);
        mTextPaint.setColor(atp.getColor(
                R.styleable.CollapsingTextAppearance_android_textColor, Color.WHITE));
        mCollapsedTitleTextSize = atp.getDimensionPixelSize(
                R.styleable.CollapsingTextAppearance_android_textSize, 0);
        atp.recycle();
    
        recalculate();
    }
    
    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);
    
        if (child instanceof Toolbar) {
            mToolbar = (Toolbar) child;
            mDummyView = new View(getContext());
            mToolbar.addView(mDummyView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        }
    }
    
    /**
     * Set the value indicating the current scroll value. This decides how much of the
     * background will be displayed, as well as the title metrics/positioning.
     *
     * A value of {@code 0.0} indicates that the layout is fully expanded.
     * A value of {@code 1.0} indicates that the layout is fully collapsed.
     */
    public void setScrollOffset(float offset) {
        if (offset != mScrollOffset) {
            mScrollOffset = offset;
            calculateOffsets();
        }
    }
    
    private void calculateOffsets() {
        final float offset = mScrollOffset;
        final float textSizeOffset = mTextSizeInterpolator != null
                ? mTextSizeInterpolator.getInterpolation(mScrollOffset)
                : offset;
    
        mTextLeft = interpolate(mExpandedMarginLeft, mToolbarContentBounds.left, offset);
        mTextTop = interpolate(mExpandedTop, mCollapsedTop, offset);
        mTextRight = interpolate(getWidth() - mExpandedMarginRight, mToolbarContentBounds.right, offset);
    
        setInterpolatedTextSize(
                interpolate(mExpandedTitleTextSize, mCollapsedTitleTextSize, textSizeOffset));
    
        ViewCompat.postInvalidateOnAnimation(this);
    }
    
    private void calculateTextBounds() {
        final DisplayMetrics metrics = getResources().getDisplayMetrics();
    
        // We then calculate the collapsed text size, using the same logic
        mTextPaint.setTextSize(mCollapsedTitleTextSize);
        float textHeight = mTextPaint.descent() - mTextPaint.ascent();
        float textOffset = (textHeight / 2) - mTextPaint.descent();
        mCollapsedTop = mToolbarContentBounds.centerY() + textOffset;
    
        // First, let's calculate the expanded text size so that it fit within the bounds
        // We make sure this value is at least our minimum text size
        mExpandedTitleTextSize = (int) Math.max(mCollapsedTitleTextSize,
                getSingleLineTextSize(mTitle, mTextPaint,
                        getWidth() - mExpandedMarginLeft -mExpandedMarginRight, 0f,
                        mRequestedExpandedTitleTextSize, 0.5f, metrics));
        mExpandedTop = getHeight() - mExpandedMarginBottom;
    
        // The bounds have changed so we need to clear the texture
        clearTexture();
    }
    
    @Override
    public void draw(Canvas canvas) {
        final int saveCount = canvas.save();
    
        final int toolbarHeight = mToolbar.getHeight();
        canvas.clipRect(0, 0, canvas.getWidth(),
                interpolate(canvas.getHeight(), toolbarHeight, mScrollOffset));
    
        // Now call super and let it draw the background, etc
        super.draw(canvas);
    
        if (mTitleToDraw != null) {
            float x = mTextLeft;
            float y = mTextTop;
    
            final float ascent = mTextPaint.ascent() * mScale;
            final float descent = mTextPaint.descent() * mScale;
            final float h = descent - ascent;
    
            if (DEBUG_DRAW) {
                // Just a debug tool, which drawn a Magneta rect in the text bounds
                canvas.drawRect(mTextLeft,
                        y - h + descent,
                        mTextRight,
                        y + descent,
                        DEBUG_DRAW_PAINT);
            }
    
            if (mUseTexture) {
                y = y - h + descent;
            }
    
            if (mScale != 1f) {
                canvas.scale(mScale, mScale, x, y);
            }
    
            if (mUseTexture && mExpandedTitleTexture != null) {
                // If we should use a texture, draw it instead of text
                canvas.drawBitmap(mExpandedTitleTexture, x, y, mTexturePaint);
            } else {
                canvas.drawText(mTitleToDraw, x, y, mTextPaint);
            }
        }
    
        canvas.restoreToCount(saveCount);
    }
    
    private void setInterpolatedTextSize(final float textSize) {
        if (mTitle == null) return;
    
        if (isClose(textSize, mCollapsedTitleTextSize) || isClose(textSize, mExpandedTitleTextSize)
                || mTitleToDraw == null) {
            // If the text size is 'close' to being a decimal, then we use this as a sync-point.
            // We disable our manual scaling and set the paint's text size.
            mTextPaint.setTextSize(textSize);
            mScale = 1f;
    
            // We also use this as an opportunity to ellipsize the string
            final CharSequence title = TextUtils.ellipsize(mTitle, mTextPaint,
                    mTextRight - mTextLeft,
                    TextUtils.TruncateAt.END);
            if (title != mTitleToDraw) {
                // If the title has changed, turn it into a string
                mTitleToDraw = title.toString();
            }
    
            if (USE_SCALING_TEXTURE && isClose(textSize, mExpandedTitleTextSize)) {
                ensureExpandedTexture();
            }
            mUseTexture = false;
        } else {
            // We're not close to a decimal so use our canvas scaling method
            if (mExpandedTitleTexture != null) {
                mScale = textSize / mExpandedTitleTextSize;
            } else {
                mScale = textSize / mTextPaint.getTextSize();
            }
    
            mUseTexture = USE_SCALING_TEXTURE;
        }
    
        ViewCompat.postInvalidateOnAnimation(this);
    }
    
    private void ensureExpandedTexture() {
        if (mExpandedTitleTexture != null) return;
    
        int w = (int) (getWidth() - mExpandedMarginLeft - mExpandedMarginRight);
        int h = (int) (mTextPaint.descent() - mTextPaint.ascent());
    
        mExpandedTitleTexture = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    
        Canvas c = new Canvas(mExpandedTitleTexture);
        c.drawText(mTitleToDraw, 0, h - mTextPaint.descent(), mTextPaint);
    
        if (mTexturePaint == null) {
            // Make sure we have a paint
            mTexturePaint = new Paint();
            mTexturePaint.setAntiAlias(true);
            mTexturePaint.setFilterBitmap(true);
        }
    }
    
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
    
        mToolbarContentBounds.left = mDummyView.getLeft();
        mToolbarContentBounds.top = mDummyView.getTop();
        mToolbarContentBounds.right = mDummyView.getRight();
        mToolbarContentBounds.bottom = mDummyView.getBottom();
    
        if (changed && mTitle != null) {
            // If we've changed and we have a title, re-calculate everything!
            recalculate();
        }
    }
    
    private void recalculate() {
        if (getHeight() > 0) {
            calculateTextBounds();
            calculateOffsets();
        }
    }
    
    /**
     * Set the title to display
     *
     * @param title
     */
    public void setTitle(String title) {
        if (title == null || !title.equals(mTitle)) {
            mTitle = title;
    
            clearTexture();
    
            if (getHeight() > 0) {
                // If we've already been laid out, calculate everything now otherwise we'll wait
                // until a layout
                recalculate();
            }
        }
    }
    
    private void clearTexture() {
        if (mExpandedTitleTexture != null) {
            mExpandedTitleTexture.recycle();
            mExpandedTitleTexture = null;
        }
    }
    
    /**
     * Recursive binary search to find the best size for the text
     *
     * Adapted from https://github.com/grantland/android-autofittextview
     */
    private static float getSingleLineTextSize(String text, TextPaint paint, float targetWidth,
                                               float low, float high, float precision, DisplayMetrics metrics) {
        final float mid = (low + high) / 2.0f;
    
        paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, metrics));
        final float maxLineWidth = paint.measureText(text);
    
        if ((high - low) < precision) {
            return low;
        } else if (maxLineWidth > targetWidth) {
            return getSingleLineTextSize(text, paint, targetWidth, low, mid, precision, metrics);
        } else if (maxLineWidth < targetWidth) {
            return getSingleLineTextSize(text, paint, targetWidth, mid, high, precision, metrics);
        } else {
            return mid;
        }
    }
    
    /**
     * Returns true if {@code value} is 'close' to it's closest decimal value. Close is currently
     * defined as it's difference being < 0.01.
     */
    private static boolean isClose(float value, float targetValue) {
        return Math.abs(value - targetValue) < 0.01f;
    }
    
    /**
     * Interpolate between {@code startValue} and {@code endValue}, using {@code progress}.
     */
    private static float interpolate(float startValue, float endValue, float progress) {
        return startValue + ((endValue - startValue) * progress);
    }
    

    }

    06.12.2015
  • Я действительно хочу, чтобы панель инструментов сжималась при прокрутке списка. Но я хочу вести себя правильно - то есть заходить за строку состояния, когда она сжимается. 06.12.2015
  • тогда ваш подход очень плохой, я обновляю свой ответ, даю вам пример того, как это должно быть, но вам придется заменить listview на recyclerview 06.12.2015
  • Есть ли способ добиться этого с помощью собственных компонентов? Я предполагаю, что aubry.chromio.com.dressup.view.CollapsingTitleLayout является внешним компонентом? 06.12.2015
  • Я добавил CollapsingTitileLayout 06.12.2015
  • Спасибо за помощь :) Попробую внести изменения 06.12.2015
  • библиотека дизайна Android предоставляет встроенные атрибуты в своем макете панели приложений для расширения и сжатия панели инструментов при событиях прокрутки. 21.04.2016
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]