FileDocCategorySizeDatePackage
RecentsVerticalScrollView.javaAPI DocAndroid 5.1 API14633Thu Mar 12 22:22:42 GMT 2015com.android.systemui.recent

RecentsVerticalScrollView

public class RecentsVerticalScrollView extends android.widget.ScrollView implements RecentsPanelView.RecentsScrollView, SwipeHelper.Callback

Fields Summary
private static final String
TAG
private static final boolean
DEBUG
private android.widget.LinearLayout
mLinearLayout
private com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter
mAdapter
private RecentsCallback
mCallback
protected int
mLastScrollPosition
private com.android.systemui.SwipeHelper
mSwipeHelper
private FadedEdgeDrawHelper
mFadedEdgeDrawHelper
private HashSet
mRecycledViews
private int
mNumItemsInOneScreenful
private Runnable
mOnScrollListener
Constructors Summary
public RecentsVerticalScrollView(android.content.Context context, android.util.AttributeSet attrs)


         
        super(context, attrs, 0);
        mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, context);

        mFadedEdgeDrawHelper = FadedEdgeDrawHelper.create(context, attrs, this, true);
        mRecycledViews = new HashSet<View>();
    
Methods Summary
private voidaddToRecycledViews(android.view.View v)

        if (mRecycledViews.size() < mNumItemsInOneScreenful) {
            mRecycledViews.add(v);
        }
    
public booleancanChildBeDismissed(android.view.View v)

        return true;
    
public voiddismissChild(android.view.View v)

        mSwipeHelper.dismissChild(v, 0);
    
public voiddrawFadedEdges(android.graphics.Canvas canvas, int left, int right, int top, int bottom)

        if (mFadedEdgeDrawHelper != null) {
            final boolean offsetRequired = isPaddingOffsetRequired();
            mFadedEdgeDrawHelper.drawCallback(canvas,
                    left, right, top + getFadeTop(offsetRequired), bottom, getScrollX(), getScrollY(),
                    getTopFadingEdgeStrength(), getBottomFadingEdgeStrength(),
                    0, 0, getPaddingTop());
        }
    
public android.view.ViewfindViewForTask(int persistentTaskId)

        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
            View v = mLinearLayout.getChildAt(i);
            RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) v.getTag();
            if (holder.taskDescription.persistentTaskId == persistentTaskId) {
                return v;
            }
        }
        return null;
    
public android.view.ViewgetChildAtPosition(android.view.MotionEvent ev)

        final float x = ev.getX() + getScrollX();
        final float y = ev.getY() + getScrollY();
        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
            View item = mLinearLayout.getChildAt(i);
            if (item.getVisibility() == View.VISIBLE
                    && x >= item.getLeft() && x < item.getRight()
                    && y >= item.getTop() && y < item.getBottom()) {
                return item;
            }
        }
        return null;
    
public android.view.ViewgetChildContentView(android.view.View v)

        return v.findViewById(R.id.recent_item);
    
public floatgetFalsingThresholdFactor()

        return 1.0f;
    
public intgetHorizontalFadingEdgeLength()

        if (mFadedEdgeDrawHelper != null) {
            return mFadedEdgeDrawHelper.getHorizontalFadingEdgeLength();
        } else {
            return super.getHorizontalFadingEdgeLength();
        }
    
public intgetVerticalFadingEdgeLength()

        if (mFadedEdgeDrawHelper != null) {
            return mFadedEdgeDrawHelper.getVerticalFadingEdgeLength();
        } else {
            return super.getVerticalFadingEdgeLength();
        }
    
public booleanisAntiFalsingNeeded()

        return false;
    
public intnumItemsInOneScreenful()

        return mNumItemsInOneScreenful;
    
public voidonAttachedToWindow()

        if (mFadedEdgeDrawHelper != null) {
            mFadedEdgeDrawHelper.onAttachedToWindowCallback(mLinearLayout, isHardwareAccelerated());
        }
    
public voidonBeginDrag(android.view.View v)

        // We do this so the underlying ScrollView knows that it won't get
        // the chance to intercept events anymore
        requestDisallowInterceptTouchEvent(true);
    
public voidonChildDismissed(android.view.View v)

        addToRecycledViews(v);
        mLinearLayout.removeView(v);
        mCallback.handleSwipe(v);
        // Restore the alpha/translation parameters to what they were before swiping
        // (for when these items are recycled)
        View contentView = getChildContentView(v);
        contentView.setAlpha(1f);
        contentView.setTranslationX(0);
    
public voidonChildSnappedBack(android.view.View animView)

    
protected voidonConfigurationChanged(android.content.res.Configuration newConfig)

        super.onConfigurationChanged(newConfig);
        float densityScale = getResources().getDisplayMetrics().density;
        mSwipeHelper.setDensityScale(densityScale);
        float pagingTouchSlop = ViewConfiguration.get(getContext()).getScaledPagingTouchSlop();
        mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
    
public voidonDragCancelled(android.view.View v)

    
protected voidonFinishInflate()

        super.onFinishInflate();
        setScrollbarFadingEnabled(true);
        mLinearLayout = (LinearLayout) findViewById(R.id.recents_linear_layout);
        final int leftPadding = getContext().getResources()
            .getDimensionPixelOffset(R.dimen.status_bar_recents_thumbnail_left_margin);
        setOverScrollEffectPadding(leftPadding, 0);
    
public booleanonInterceptTouchEvent(android.view.MotionEvent ev)

        if (DEBUG) Log.v(TAG, "onInterceptTouchEvent()");
        return mSwipeHelper.onInterceptTouchEvent(ev) ||
            super.onInterceptTouchEvent(ev);
    
protected voidonScrollChanged(int l, int t, int oldl, int oldt)

       super.onScrollChanged(l, t, oldl, oldt);
       if (mOnScrollListener != null) {
           mOnScrollListener.run();
       }
    
protected voidonSizeChanged(int w, int h, int oldw, int oldh)

        super.onSizeChanged(w, h, oldw, oldh);

        // Skip this work if a transition is running; it sets the scroll values independently
        // and should not have those animated values clobbered by this logic
        LayoutTransition transition = mLinearLayout.getLayoutTransition();
        if (transition != null && transition.isRunning()) {
            return;
        }
        // Keep track of the last visible item in the list so we can restore it
        // to the bottom when the orientation changes.
        mLastScrollPosition = scrollPositionOfMostRecent();

        // This has to happen post-layout, so run it "in the future"
        post(new Runnable() {
            public void run() {
                // Make sure we're still not clobbering the transition-set values, since this
                // runnable launches asynchronously
                LayoutTransition transition = mLinearLayout.getLayoutTransition();
                if (transition == null || !transition.isRunning()) {
                    scrollTo(0, mLastScrollPosition);
                }
            }
        });
    
public booleanonTouchEvent(android.view.MotionEvent ev)

        return mSwipeHelper.onTouchEvent(ev) ||
            super.onTouchEvent(ev);
    
public voidremoveViewInLayout(android.view.View view)

        dismissChild(view);
    
private intscrollPositionOfMostRecent()

        return mLinearLayout.getHeight() - getHeight() + getPaddingTop();
    
public voidsetAdapter(com.android.systemui.recent.RecentsPanelView.TaskDescriptionAdapter adapter)

        mAdapter = adapter;
        mAdapter.registerDataSetObserver(new DataSetObserver() {
            public void onChanged() {
                update();
            }

            public void onInvalidated() {
                update();
            }
        });

        DisplayMetrics dm = getResources().getDisplayMetrics();
        int childWidthMeasureSpec =
                MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.AT_MOST);
        int childheightMeasureSpec =
                MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.AT_MOST);
        View child = mAdapter.createView(mLinearLayout);
        child.measure(childWidthMeasureSpec, childheightMeasureSpec);
        mNumItemsInOneScreenful =
                (int) FloatMath.ceil(dm.heightPixels / (float) child.getMeasuredHeight());
        addToRecycledViews(child);

        for (int i = 0; i < mNumItemsInOneScreenful - 1; i++) {
            addToRecycledViews(mAdapter.createView(mLinearLayout));
        }
    
public voidsetCallback(RecentsCallback callback)

        mCallback = callback;
    
public voidsetLayoutTransition(android.animation.LayoutTransition transition)

        // The layout transition applies to our embedded LinearLayout
        mLinearLayout.setLayoutTransition(transition);
    
public voidsetMinSwipeAlpha(float minAlpha)

        mSwipeHelper.setMinSwipeProgress(minAlpha);
    
public voidsetOnScrollListener(java.lang.Runnable listener)

        mOnScrollListener = listener;
    
private voidsetOverScrollEffectPadding(int leftPadding, int i)

        // TODO Add to (Vertical)ScrollView
    
private voidupdate()

        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
            View v = mLinearLayout.getChildAt(i);
            addToRecycledViews(v);
            mAdapter.recycleView(v);
        }
        LayoutTransition transitioner = getLayoutTransition();
        setLayoutTransition(null);

        mLinearLayout.removeAllViews();

        // Once we can clear the data associated with individual item views,
        // we can get rid of the removeAllViews() and the code below will
        // recycle them.
        Iterator<View> recycledViews = mRecycledViews.iterator();
        for (int i = 0; i < mAdapter.getCount(); i++) {
            View old = null;
            if (recycledViews.hasNext()) {
                old = recycledViews.next();
                recycledViews.remove();
                old.setVisibility(VISIBLE);
            }
            final View view = mAdapter.getView(i, old, mLinearLayout);

            if (mFadedEdgeDrawHelper != null) {
                mFadedEdgeDrawHelper.addViewCallback(view);
            }

            OnTouchListener noOpListener = new OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    return true;
                }
            };

            view.setOnClickListener(new OnClickListener() {
                public void onClick(View v) {
                    mCallback.dismiss();
                }
            });
            // We don't want a click sound when we dimiss recents
            view.setSoundEffectsEnabled(false);

            OnClickListener launchAppListener = new OnClickListener() {
                public void onClick(View v) {
                    mCallback.handleOnClick(view);
                }
            };

            RecentsPanelView.ViewHolder holder = (RecentsPanelView.ViewHolder) view.getTag();
            final View thumbnailView = holder.thumbnailView;
            OnLongClickListener longClickListener = new OnLongClickListener() {
                public boolean onLongClick(View v) {
                    final View anchorView = view.findViewById(R.id.app_description);
                    mCallback.handleLongPress(view, anchorView, thumbnailView);
                    return true;
                }
            };
            thumbnailView.setClickable(true);
            thumbnailView.setOnClickListener(launchAppListener);
            thumbnailView.setOnLongClickListener(longClickListener);

            // We don't want to dismiss recents if a user clicks on the app title
            // (we also don't want to launch the app either, though, because the
            // app title is a small target and doesn't have great click feedback)
            final View appTitle = view.findViewById(R.id.app_label);
            appTitle.setContentDescription(" ");
            appTitle.setOnTouchListener(noOpListener);
            final View calloutLine = view.findViewById(R.id.recents_callout_line);
            if (calloutLine != null) {
                calloutLine.setOnTouchListener(noOpListener);
            }

            mLinearLayout.addView(view);
        }
        setLayoutTransition(transitioner);

        // Scroll to end after initial layout.
        final OnGlobalLayoutListener updateScroll = new OnGlobalLayoutListener() {
                public void onGlobalLayout() {
                    mLastScrollPosition = scrollPositionOfMostRecent();
                    scrollTo(0, mLastScrollPosition);
                    final ViewTreeObserver observer = getViewTreeObserver();
                    if (observer.isAlive()) {
                        observer.removeOnGlobalLayoutListener(this);
                    }
                }
            };
        getViewTreeObserver().addOnGlobalLayoutListener(updateScroll);
    
public booleanupdateSwipeProgress(android.view.View animView, boolean dismissable, float swipeProgress)

        return false;