public class

TemplateView

extends SliceChildView

implements SliceViewPolicy.PolicyChangeListener

 java.lang.Object

↳FrameLayout

androidx.slice.widget.SliceChildView

↳androidx.slice.widget.TemplateView

Gradle dependencies

compile group: 'androidx.slice', name: 'slice-view', version: '1.1.0-alpha02'

  • groupId: androidx.slice
  • artifactId: slice-view
  • version: 1.1.0-alpha02

Artifact androidx.slice:slice-view:1.1.0-alpha02 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.slice:slice-view com.android.support:slices-view

Summary

Fields
from SliceChildViewmInsetBottom, mInsetEnd, mInsetStart, mInsetTop, mLastUpdated, mLoadingListener, mMode, mObserver, mRowStyle, mShowLastUpdated, mSliceStyle, mTintColor, mViewPolicy
Constructors
publicTemplateView(Context context)

Methods
public intgetHiddenItemCount()

public java.util.Set<SliceItem>getLoadingActions()

The set of currently loading actions.

public voidonAttachedToWindow()

public voidonForegroundActivated(MotionEvent event)

Called when the foreground view handling touch feedback should be activated.

public voidonMaxHeightChanged(int newNewHeight)

public voidonMaxSmallChanged(int newMaxSmallHeight)

protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

public voidonModeChanged(int newMode)

public voidonScrollingChanged(boolean newScrolling)

public abstract voidresetView()

Called when the view should be reset.

public voidsetActionLoading(SliceItem item)

Indicates that a particular action is being loaded.

public voidsetAllowTwoLines(boolean allowTwoLines)

Sets whether this slice can have 2 lines of subtitle text in the first row.

public voidsetInsets(int l, int t, int r, int b)

Sets the insets (padding) for the slice.

public voidsetLastUpdated(long lastUpdated)

Sets when the content of this view was last updated.

public voidsetLoadingActions(java.util.Set<SliceItem> loadingActions)

Sets the actions that are being loaded.

public voidsetPolicy(SliceViewPolicy policy)

Sets the policy information for this view.

public voidsetShowLastUpdated(boolean showLastUpdated)

Sets whether the last updated time should be displayed.

public voidsetSliceActionListener(SliceView.OnSliceActionListener observer)

Sets the observer to notify when an interaction events occur on the view.

public voidsetSliceActions(java.util.List<SliceAction> actions)

Sets the slice actions for this view.

public voidsetSliceContent(ListContent content)

Sets the content to display in this slice.

public voidsetStyle(SliceStyle styles, RowStyle rowStyle)

Sets the style information for this view.

public voidsetTint(int tintColor)

Sets a custom color to use for tinting elements like icons for this view.

from SliceChildViewgetMode, setSliceActionLoadingListener, setSliceItem
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructors

public TemplateView(Context context)

Methods

public void onAttachedToWindow()

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

public void setInsets(int l, int t, int r, int b)

Sets the insets (padding) for the slice.

public void onForegroundActivated(MotionEvent event)

Called when the foreground view handling touch feedback should be activated.

Parameters:

event: the event to handle.

public void setPolicy(SliceViewPolicy policy)

Sets the policy information for this view.

public void setActionLoading(SliceItem item)

Indicates that a particular action is being loaded.

public void setLoadingActions(java.util.Set<SliceItem> loadingActions)

Sets the actions that are being loaded.

public java.util.Set<SliceItem> getLoadingActions()

The set of currently loading actions.

public void setTint(int tintColor)

Sets a custom color to use for tinting elements like icons for this view.

public void setSliceActionListener(SliceView.OnSliceActionListener observer)

Sets the observer to notify when an interaction events occur on the view.

public void setSliceActions(java.util.List<SliceAction> actions)

Sets the slice actions for this view.

public void setSliceContent(ListContent content)

Sets the content to display in this slice.

public void setStyle(SliceStyle styles, RowStyle rowStyle)

Sets the style information for this view.

public void setShowLastUpdated(boolean showLastUpdated)

Sets whether the last updated time should be displayed.

public void setLastUpdated(long lastUpdated)

Sets when the content of this view was last updated.

public void setAllowTwoLines(boolean allowTwoLines)

Sets whether this slice can have 2 lines of subtitle text in the first row.

public abstract void resetView()

Called when the view should be reset.

public void onScrollingChanged(boolean newScrolling)

public void onMaxHeightChanged(int newNewHeight)

public void onMaxSmallChanged(int newMaxSmallHeight)

public void onModeChanged(int newMode)

public int getHiddenItemCount()

Source

/*
 * Copyright 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.slice.widget;

import android.content.Context;
import android.os.Build;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RestrictTo;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slice.SliceItem;
import androidx.slice.core.SliceAction;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY)
@RequiresApi(19)
public class TemplateView extends SliceChildView implements
        SliceViewPolicy.PolicyChangeListener {

    private SliceView mParent;
    private final View mForeground;
    private final SliceAdapter mAdapter;
    private final RecyclerView mRecyclerView;
    private ListContent mListContent;
    private List<SliceContent> mDisplayedItems = new ArrayList<>();
    private int mDisplayedItemsHeight = 0;
    private int[] mLoc = new int[2];
    private int mHiddenItemCount;

    public TemplateView(Context context) {
        super(context);
        mRecyclerView = new RecyclerView(getContext());
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mAdapter = new SliceAdapter(context);
        mRecyclerView.setAdapter(mAdapter);
        addView(mRecyclerView);

        mForeground = new View(getContext());
        mForeground.setBackground(SliceViewUtil.getDrawable(getContext(),
                android.R.attr.selectableItemBackground));
        addView(mForeground);

        FrameLayout.LayoutParams lp = (LayoutParams) mForeground.getLayoutParams();
        lp.width = LayoutParams.MATCH_PARENT;
        lp.height = LayoutParams.MATCH_PARENT;
        mForeground.setLayoutParams(lp);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        mParent = (SliceView) getParent();
        mAdapter.setParents(mParent, this);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        if (!mViewPolicy.isScrollable() && mDisplayedItems.size() > 0
                && mDisplayedItemsHeight != height) {
            updateDisplayedItems(height);
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public void setInsets(int l, int t, int r, int b) {
        super.setInsets(l, t, r, b);
        mAdapter.setInsets(l, t, r, b);
    }

    /**
     * Called when the foreground view handling touch feedback should be activated.
     * @param event the event to handle.
     */
    public void onForegroundActivated(MotionEvent event) {
        if (mParent != null && !mParent.isSliceViewClickable()) {
            // Only show highlight if clickable
            mForeground.setPressed(false);
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mForeground.getLocationOnScreen(mLoc);
            final int x = (int) (event.getRawX() - mLoc[0]);
            final int y = (int) (event.getRawY() - mLoc[1]);
            mForeground.getBackground().setHotspot(x, y);
        }
        int action = event.getActionMasked();
        if (action == MotionEvent.ACTION_DOWN) {
            mForeground.setPressed(true);
        } else if (action == MotionEvent.ACTION_CANCEL
                || action == MotionEvent.ACTION_UP
                || action == MotionEvent.ACTION_MOVE) {
            mForeground.setPressed(false);
        }
    }

    @Override
    public void setPolicy(SliceViewPolicy policy) {
        super.setPolicy(policy);
        mAdapter.setPolicy(policy);
        policy.setListener(this);
    }

    @Override
    public void setActionLoading(SliceItem item) {
        mAdapter.onSliceActionLoading(item, 0 /* header position */);
    }

    @Override
    public void setLoadingActions(Set<SliceItem> loadingActions) {
        mAdapter.setLoadingActions(loadingActions);
    }

    @Override
    public Set<SliceItem> getLoadingActions() {
        return mAdapter.getLoadingActions();
    }

    @Override
    public void setTint(int tint) {
        super.setTint(tint);
        updateDisplayedItems(getMeasuredHeight());
    }

    @Override
    public void setSliceActionListener(SliceView.OnSliceActionListener observer) {
        mObserver = observer;
        if (mAdapter != null) {
            mAdapter.setSliceObserver(mObserver);
        }
    }

    @Override
    public void setSliceActions(List<SliceAction> actions) {
        mAdapter.setSliceActions(actions);
    }

    @Override
    public void setSliceContent(ListContent sliceContent) {
        mListContent = sliceContent;
        int sliceHeight = mListContent.getHeight(mSliceStyle, mViewPolicy);
        updateDisplayedItems(sliceHeight);
    }

    @Override
    public void setStyle(SliceStyle style, @NonNull RowStyle rowStyle) {
        super.setStyle(style, rowStyle);
        mAdapter.setStyle(style);
        applyRowStyle(rowStyle);
    }

    private void applyRowStyle(RowStyle rowStyle) {
        if (rowStyle.getDisableRecyclerViewItemAnimator()) {
            mRecyclerView.setItemAnimator(null);
        }
    }

    @Override
    public void setShowLastUpdated(boolean showLastUpdated) {
        super.setShowLastUpdated(showLastUpdated);
        mAdapter.setShowLastUpdated(showLastUpdated);
    }

    @Override
    public void setLastUpdated(long lastUpdated) {
        super.setLastUpdated(lastUpdated);
        mAdapter.setLastUpdated(lastUpdated);
    }

    @Override
    public void setAllowTwoLines(boolean allowTwoLines) {
        mAdapter.setAllowTwoLines(allowTwoLines);
    }

    private void updateDisplayedItems(int height) {
        if (mListContent == null || !mListContent.isValid()) {
            resetView();
            return;
        }
        DisplayedListItems response = mListContent.getRowItems(
                height, mSliceStyle, mViewPolicy);
        mDisplayedItems = response.getDisplayedItems();
        mHiddenItemCount = response.getHiddenItemCount();
        mDisplayedItemsHeight = mListContent.getListHeight(mDisplayedItems, mSliceStyle,
                mViewPolicy);
        mAdapter.setSliceItems(mDisplayedItems, mTintColor, mViewPolicy.getMode());
        updateOverscroll();
    }

    private void updateOverscroll() {
        boolean scrollable = mDisplayedItemsHeight > getMeasuredHeight();
        mRecyclerView.setOverScrollMode(mViewPolicy.isScrollable() && scrollable
                ? View.OVER_SCROLL_IF_CONTENT_SCROLLS
                : View.OVER_SCROLL_NEVER);
    }

    @Override
    public void resetView() {
        mDisplayedItemsHeight = 0;
        mDisplayedItems.clear();
        mAdapter.setSliceItems(null, -1, getMode());
        mListContent = null;
    }

    @Override
    public void onScrollingChanged(boolean newScrolling) {
        // Disable nested scrolling if the slice isn't scrollable. This allows inertial
        // scrolling if the slice is inside a ScrollView.
        mRecyclerView.setNestedScrollingEnabled(newScrolling);

        if (mListContent != null) {
            updateDisplayedItems(mListContent.getHeight(mSliceStyle, mViewPolicy));
        }
    }

    @Override
    public void onMaxHeightChanged(int newNewHeight) {
        if (mListContent != null) {
            updateDisplayedItems(mListContent.getHeight(mSliceStyle, mViewPolicy));
        }
    }

    @Override
    public void onMaxSmallChanged(int newMaxSmallHeight) {
        if (mAdapter != null) {
            mAdapter.notifyHeaderChanged();
        }
    }

    @Override
    public void onModeChanged(int newMode) {
        if (mListContent != null) {
            updateDisplayedItems(mListContent.getHeight(mSliceStyle, mViewPolicy));
        }
    }

    @Override
    public int getHiddenItemCount() {
        return mHiddenItemCount;
    }
}