TimelineHorizontalScrollView.java revision 97c784156f2df509683c59c6ce0e23ef5126a4b3
1ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/* 2ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Copyright (C) 2010 The Android Open Source Project 3ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 4ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Licensed under the Apache License, Version 2.0 (the "License"); 5ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * you may not use this file except in compliance with the License. 6ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * You may obtain a copy of the License at 7ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 8ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * http://www.apache.org/licenses/LICENSE-2.0 9ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 10ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Unless required by applicable law or agreed to in writing, software 11ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * distributed under the License is distributed on an "AS IS" BASIS, 12ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * See the License for the specific language governing permissions and 14ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * limitations under the License. 15ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 16ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 17ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschipackage com.google.videoeditor.widgets; 18ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 19ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.util.ArrayList; 20ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport java.util.List; 21ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 2297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport com.google.videoeditor.R; 2397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 2497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport android.app.Activity; 25ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.content.Context; 2697c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport android.content.res.Resources; 2797c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport android.graphics.Canvas; 2897c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport android.graphics.drawable.Drawable; 29ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.os.Handler; 30ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.util.AttributeSet; 3197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschiimport android.view.Display; 32ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.MotionEvent; 33ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.view.ScaleGestureDetector; 34ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschiimport android.widget.HorizontalScrollView; 35ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 36ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi/** 37ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * The timeline scroll view 38ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 39ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschipublic class TimelineHorizontalScrollView extends HorizontalScrollView { 40ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Instance variables 41ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private final List<ScrollViewListener> mScrollListenerList; 42ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private final Handler mHandler; 4397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi private final int mPlayheadMarginTop, mPlayheadMarginBottom; 4497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi private final Drawable mPlayheadDrawable; 4597c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi private final int mHalfParentWidth; 46ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private ScaleGestureDetector mScaleDetector; 47ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private int mLastScrollX; 48ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mIsScrolling; 49ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mAppScroll; 50ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private boolean mEnableUserScrolling; 51ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 52ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // The runnable which executes when the scrolling ends 53ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi private Runnable mScrollEndedRunnable = new Runnable() { 54ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 55ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 56ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 57ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void run() { 58ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mIsScrolling = false; 59ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 60ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi for (ScrollViewListener listener : mScrollListenerList) { 61ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi listener.onScrollEnd(TimelineHorizontalScrollView.this, getScrollX(), 62ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi getScrollY(), mAppScroll); 63ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 64ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 65ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mAppScroll = false; 66ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 67ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi }; 68ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 69ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 70ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 71ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 72ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public TimelineHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) { 73ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi super(context, attrs, defStyle); 74ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 75ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mEnableUserScrolling = true; 76ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScrollListenerList = new ArrayList<ScrollViewListener>(); 77ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mHandler = new Handler(); 7897c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 7997c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Compute half the width of the screen (and therefore the parent view) 8097c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi final Display display = ((Activity)context).getWindowManager().getDefaultDisplay(); 8197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mHalfParentWidth = display.getWidth() / 2; 8297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 8397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // This value is shared by all children. It represents the width of 8497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // the left empty view. 8597c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi setTag(R.id.left_view_width, mHalfParentWidth); 8697c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi setTag(R.id.playhead_offset, -1); 8797c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 8897c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi final Resources resources = context.getResources(); 8997c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 9097c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Get the playhead margins 9197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mPlayheadMarginTop = (int)resources.getDimension(R.dimen.playhead_margin_top); 9297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mPlayheadMarginBottom = (int)resources.getDimension(R.dimen.playhead_margin_bottom); 9397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 9497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Prepare the playhead drawable 9597c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mPlayheadDrawable = resources.getDrawable(R.drawable.playhead); 96ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 97ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 98ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 99ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 100ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 101ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public TimelineHorizontalScrollView(Context context, AttributeSet attrs) { 102ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi this(context, attrs, 0); 103ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 104ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 105ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 106ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 107ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 108ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public TimelineHorizontalScrollView(Context context) { 109ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi this(context, null, 0); 110ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 111ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 112ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 113ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * Invoked to enable/disable user scrolling (as opposed to programmatic scrolling) 114ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param enable true to enable user scrolling 115ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 116ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void enableUserScrolling(boolean enable) { 117ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mEnableUserScrolling = enable; 118ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 119ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 120ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 121ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 122ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 123ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 124ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public boolean onInterceptTouchEvent(MotionEvent ev) { 125ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScaleDetector.onTouchEvent(ev); 126ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return mScaleDetector.isInProgress() || super.onInterceptTouchEvent(ev); 127ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 128ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 129ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 130ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 131ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 132ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi @Override 133ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public boolean onTouchEvent(MotionEvent ev) { 134ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (mEnableUserScrolling) { 135ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScaleDetector.onTouchEvent(ev); 136ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 137ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (!mScaleDetector.isInProgress()) { 138ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return super.onTouchEvent(ev); 139ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 140ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return true; 141ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 142ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 143ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return true; 144ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 145ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 146ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 147ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 148ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param listener The scale listener 149ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 150ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void setScaleListener(ScaleGestureDetector.SimpleOnScaleGestureListener listener) { 151ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScaleDetector = new ScaleGestureDetector(getContext(), listener); 152ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 153ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 154ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 155ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param listener The listener 156ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 157ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void addScrollListener(ScrollViewListener listener) { 158ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScrollListenerList.add(listener); 159ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 160ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 161ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 162ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param listener The listener 163ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 164ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void removeScrollListener(ScrollViewListener listener) { 165ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mScrollListenerList.remove(listener); 166ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 167ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 168ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 169ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @return true if scrolling is in progress 170ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 171ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public boolean isScrolling() { 172ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return mIsScrolling; 173ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 174ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 175ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 176ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * The app wants to scroll (as opposed to the user) 177ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 178ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param scrollX Horizontal scroll position 179ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param smooth true to scroll smoothly 180ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 181ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void appScrollTo(int scrollX, boolean smooth) { 182ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (getScrollX() == scrollX) { 183ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi return; 184ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 185ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 186ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mAppScroll = true; 187ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 188ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (smooth) { 189ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi smoothScrollTo(scrollX, 0); 190ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 191ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi scrollTo(scrollX, 0); 192ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 193ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 194ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 195ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /** 196ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * The app wants to scroll (as opposed to the user) 197ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * 198ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param scrollX Horizontal scroll offset 199ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * @param smooth true to scroll smoothly 200ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 201ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void appScrollBy(int scrollX, boolean smooth) { 202ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mAppScroll = true; 203ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 204ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (smooth) { 205ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi smoothScrollBy(scrollX, 0); 206ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 207ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi scrollBy(scrollX, 0); 208ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 209ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 210ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 211ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi /* 212ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi * {@inheritDoc} 213ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi */ 214ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi public void computeScroll() { 215ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi super.computeScroll(); 216ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 217ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final int scrollX = getScrollX(); 218ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (mLastScrollX != scrollX) { 219ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mLastScrollX = scrollX; 220ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 221ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Cancel the previous event 222ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mHandler.removeCallbacks(mScrollEndedRunnable); 223ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 224ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi // Post a new event 225ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mHandler.postDelayed(mScrollEndedRunnable, 300); 226ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 227ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi final int scrollY = getScrollY(); 228ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi if (mIsScrolling) { 229ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi for (ScrollViewListener listener : mScrollListenerList) { 230ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi listener.onScrollProgress(this, scrollX, scrollY, mAppScroll); 231ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 232ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } else { 233ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi mIsScrolling = true; 234ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi 235ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi for (ScrollViewListener listener : mScrollListenerList) { 236ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi listener.onScrollBegin(this, scrollX, scrollY, mAppScroll); 237ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 238ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 239ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 240ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi } 24197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 24297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi /* 24397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi * {@inheritDoc} 24497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi */ 24597c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi @Override 24697c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi protected void dispatchDraw(Canvas canvas) { 24797c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi super.dispatchDraw(canvas); 24897c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 24997c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi final int playheadOffset = (Integer)getTag(R.id.playhead_offset); 25097c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi final int startX; 25197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi if (playheadOffset < 0) { 25297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Draw the playhead in the middle of the screen 25397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi startX = mHalfParentWidth + getScrollX(); 25497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi } else { 25597c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Draw the playhead at the specified position (during trimming) 25697c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi startX = playheadOffset; 25797c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi } 25897c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi 25997c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi // Draw the playhead 26097c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi final int halfPlayheadWidth = mPlayheadDrawable.getIntrinsicWidth() / 2; 26197c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mPlayheadDrawable.setBounds(startX - halfPlayheadWidth, mPlayheadMarginTop, 26297c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi startX + halfPlayheadWidth, getHeight() - mPlayheadMarginBottom); 26397c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi mPlayheadDrawable.draw(canvas); 26497c784156f2df509683c59c6ce0e23ef5126a4b3Gil Dobjanschi } 265ace3cdb462fef9563a0470223c62a7e80e6d587aGil Dobjanschi} 266