From 108fb88b9fca0a0948b61b17efb63e2a45fe5aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20Varga?= Date: Sun, 8 Oct 2017 20:48:00 +0200 Subject: [PATCH] Use hardware volume keys from anywhere inside Kore (#453) * Allow the RemoteActivity and BaseMediaActivity to show a volume controller dialog when hardware volume keys are pressed ** The dialog handles the key events and makes callbacks to the activities to handle showing the dialog itself * Minor improvements ** Make HighlightButton render in the IDE GUI Editor ** Minor code cleanup ** set currentActivePlayerId = -1; on playerOnStop in BaseMediaActivity to be more consistent resolves xbmc/Kore#235 --- .../java/org/xbmc/kore/ui/BaseActivity.java | 15 +- .../org/xbmc/kore/ui/BaseMediaActivity.java | 34 +++- .../ui/sections/remote/RemoteActivity.java | 93 ++++----- .../OnHardwareVolumeKeyPressedCallback.java | 5 + ...olumeControllerDialogFragmentListener.java | 183 ++++++++++++++++++ .../VolumeKeyActionHandler.java | 62 ++++++ .../xbmc/kore/ui/widgets/HighlightButton.java | 13 +- .../kore/ui/widgets/VolumeLevelIndicator.java | 21 +- .../res/layout/volume_controller_dialog.xml | 39 ++++ 9 files changed, 400 insertions(+), 65 deletions(-) create mode 100644 app/src/main/java/org/xbmc/kore/ui/volumecontrollers/OnHardwareVolumeKeyPressedCallback.java create mode 100644 app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeControllerDialogFragmentListener.java create mode 100644 app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeKeyActionHandler.java create mode 100644 app/src/main/res/layout/volume_controller_dialog.xml diff --git a/app/src/main/java/org/xbmc/kore/ui/BaseActivity.java b/app/src/main/java/org/xbmc/kore/ui/BaseActivity.java index b5d859d..9c3d42b 100644 --- a/app/src/main/java/org/xbmc/kore/ui/BaseActivity.java +++ b/app/src/main/java/org/xbmc/kore/ui/BaseActivity.java @@ -28,20 +28,15 @@ import org.xbmc.kore.utils.UIUtils; */ public abstract class BaseActivity extends AppCompatActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { + @Override + protected void onCreate(Bundle savedInstanceState) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); setTheme(UIUtils.getThemeResourceId( prefs.getString(Settings.KEY_PREF_THEME, Settings.DEFAULT_PREF_THEME))); super.onCreate(savedInstanceState); - } - - @Override - public void onPause() { - super.onPause(); } -// @Override + // @Override // public boolean onCreateOptionsMenu(Menu menu) { // getMenuInflater().inflate(R.menu.global, menu); // return super.onCreateOptionsMenu(menu); @@ -50,8 +45,8 @@ public abstract class BaseActivity extends AppCompatActivity { // @Override // public boolean onOptionsItemSelected(MenuItem item) { // switch (item.getItemId()) { -// case R.id.action_settings: -// return true; +// case R.id.action_settings: +// return true; // default: // break; // } diff --git a/app/src/main/java/org/xbmc/kore/ui/BaseMediaActivity.java b/app/src/main/java/org/xbmc/kore/ui/BaseMediaActivity.java index e21f7de..d849a82 100644 --- a/app/src/main/java/org/xbmc/kore/ui/BaseMediaActivity.java +++ b/app/src/main/java/org/xbmc/kore/ui/BaseMediaActivity.java @@ -28,6 +28,7 @@ import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.transition.TransitionInflater; +import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -48,6 +49,9 @@ import org.xbmc.kore.jsonrpc.type.ListType; import org.xbmc.kore.jsonrpc.type.PlayerType; import org.xbmc.kore.ui.generic.NavigationDrawerFragment; import org.xbmc.kore.ui.sections.remote.RemoteActivity; +import org.xbmc.kore.ui.volumecontrollers.OnHardwareVolumeKeyPressedCallback; +import org.xbmc.kore.ui.volumecontrollers.VolumeControllerDialogFragmentListener; +import org.xbmc.kore.ui.volumecontrollers.VolumeKeyActionHandler; import org.xbmc.kore.ui.widgets.MediaProgressIndicator; import org.xbmc.kore.ui.widgets.NowPlayingPanel; import org.xbmc.kore.ui.widgets.VolumeLevelIndicator; @@ -63,7 +67,8 @@ public abstract class BaseMediaActivity extends BaseActivity implements HostConnectionObserver.ApplicationEventsObserver, HostConnectionObserver.PlayerEventsObserver, NowPlayingPanel.OnPanelButtonsClickListener, - MediaProgressIndicator.OnProgressChangeListener { + MediaProgressIndicator.OnProgressChangeListener, + OnHardwareVolumeKeyPressedCallback { private static final String TAG = LogUtils.makeLogTag(BaseMediaActivity.class); private static final String NAVICON_ISARROW = "navstate"; @@ -79,6 +84,7 @@ public abstract class BaseMediaActivity extends BaseActivity private HostManager hostManager; private HostConnectionObserver hostConnectionObserver; + private VolumeKeyActionHandler volumeKeyActionHandler; private boolean showNowPlayingPanel; @@ -180,7 +186,6 @@ public abstract class BaseMediaActivity extends BaseActivity .getBoolean(Settings.KEY_PREF_SHOW_NOW_PLAYING_PANEL, Settings.DEFAULT_PREF_SHOW_NOW_PLAYING_PANEL); - if(showNowPlayingPanel) { setupNowPlayingPanel(); } else { @@ -205,6 +210,30 @@ public abstract class BaseMediaActivity extends BaseActivity hostConnectionObserver.unregisterPlayerObserver(this); } + /** + * Override hardware volume keys and send to Kodi + */ + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (volumeKeyActionHandler == null) { + volumeKeyActionHandler = new VolumeKeyActionHandler(hostManager, this, this); + } + return volumeKeyActionHandler.handleDispatchKeyEvent(event) || super.dispatchKeyEvent( + event); + } + + @Override + public void onHardwareVolumeKeyPressed() { + showVolumeChangeDialog(); + } + + private void showVolumeChangeDialog() { + VolumeControllerDialogFragmentListener volumeControllerDialogFragment = + new VolumeControllerDialogFragmentListener(); + volumeControllerDialogFragment.show(getSupportFragmentManager(), + VolumeControllerDialogFragmentListener.class.getName()); + } + public boolean getDrawerIndicatorIsArrow() { return drawerIndicatorIsArrow; } @@ -296,6 +325,7 @@ public abstract class BaseMediaActivity extends BaseActivity @Override public void playerOnStop() { + currentActivePlayerId = -1; //We delay hiding the panel to prevent hiding the panel when playing // the next item in a playlist callbackHandler.removeCallbacks(hidePanelRunnable); diff --git a/app/src/main/java/org/xbmc/kore/ui/sections/remote/RemoteActivity.java b/app/src/main/java/org/xbmc/kore/ui/sections/remote/RemoteActivity.java index df4b582..8934d6f 100644 --- a/app/src/main/java/org/xbmc/kore/ui/sections/remote/RemoteActivity.java +++ b/app/src/main/java/org/xbmc/kore/ui/sections/remote/RemoteActivity.java @@ -49,7 +49,6 @@ import org.xbmc.kore.jsonrpc.method.Player; import org.xbmc.kore.jsonrpc.method.Playlist; import org.xbmc.kore.jsonrpc.method.System; import org.xbmc.kore.jsonrpc.method.VideoLibrary; -import org.xbmc.kore.jsonrpc.type.GlobalType; import org.xbmc.kore.jsonrpc.type.ListType; import org.xbmc.kore.jsonrpc.type.PlayerType; import org.xbmc.kore.jsonrpc.type.PlaylistType; @@ -59,6 +58,9 @@ import org.xbmc.kore.ui.generic.NavigationDrawerFragment; import org.xbmc.kore.ui.generic.SendTextDialogFragment; import org.xbmc.kore.ui.sections.hosts.AddHostActivity; import org.xbmc.kore.ui.views.CirclePageIndicator; +import org.xbmc.kore.ui.volumecontrollers.OnHardwareVolumeKeyPressedCallback; +import org.xbmc.kore.ui.volumecontrollers.VolumeControllerDialogFragmentListener; +import org.xbmc.kore.ui.volumecontrollers.VolumeKeyActionHandler; import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.TabsAdapter; import org.xbmc.kore.utils.UIUtils; @@ -77,8 +79,8 @@ import butterknife.InjectView; public class RemoteActivity extends BaseActivity implements HostConnectionObserver.PlayerEventsObserver, NowPlayingFragment.NowPlayingListener, - SendTextDialogFragment.SendTextDialogListener { - private static final String TAG = LogUtils.makeLogTag(RemoteActivity.class); + SendTextDialogFragment.SendTextDialogListener, OnHardwareVolumeKeyPressedCallback { + private static final String TAG = LogUtils.makeLogTag(RemoteActivity.class); private static final int NOWPLAYING_FRAGMENT_ID = 1; @@ -97,6 +99,8 @@ public class RemoteActivity extends BaseActivity private NavigationDrawerFragment navigationDrawerFragment; + private VolumeKeyActionHandler volumeKeyActionHandler; + @InjectView(R.id.background_image) ImageView backgroundImage; @InjectView(R.id.pager_indicator) CirclePageIndicator pageIndicator; @InjectView(R.id.pager) ViewPager viewPager; @@ -201,54 +205,20 @@ public class RemoteActivity extends BaseActivity hostConnectionObserver = null; } - /** - * Override hardware volume keys and send to Kodi - */ - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - // Check whether we should intercept this - boolean useVolumeKeys = PreferenceManager - .getDefaultSharedPreferences(this) - .getBoolean(Settings.KEY_PREF_USE_HARDWARE_VOLUME_KEYS, - Settings.DEFAULT_PREF_USE_HARDWARE_VOLUME_KEYS); - if (useVolumeKeys) { - int action = event.getAction(); - int keyCode = event.getKeyCode(); - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - if (action == KeyEvent.ACTION_DOWN) { - new Application - .SetVolume(GlobalType.IncrementDecrement.INCREMENT) - .execute(hostManager.getConnection(), null, null); - } - return true; - case KeyEvent.KEYCODE_VOLUME_DOWN: - if (action == KeyEvent.ACTION_DOWN) { - new Application - .SetVolume(GlobalType.IncrementDecrement.DECREMENT) - .execute(hostManager.getConnection(), null, null); - } - return true; - } - } - - return super.dispatchKeyEvent(event); - } - @Override public boolean onCreateOptionsMenu(Menu menu) { - if (!navigationDrawerFragment.isDrawerOpen()) { - // Only show items in the action bar relevant to this screen if the drawer is not showing. - // Otherwise, let the drawer decide what to show in the action bar. + if (!navigationDrawerFragment.isDrawerOpen()) { + // Only show items in the action bar relevant to this screen if the drawer is not showing. + // Otherwise, let the drawer decide what to show in the action bar. getMenuInflater().inflate(R.menu.remote, menu); - } + } return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. - switch (item.getItemId()) { + switch (item.getItemId()) { case R.id.action_wake_up: UIUtils.sendWolAsync(this, hostManager.getHostInfo()); return true; @@ -298,11 +268,30 @@ public class RemoteActivity extends BaseActivity AudioLibrary.Scan actionScanAudio = new AudioLibrary.Scan(); actionScanAudio.execute(hostManager.getConnection(), null, null); return true; - default: - break; - } + default: + break; + } - return super.onOptionsItemSelected(item); + return super.onOptionsItemSelected(item); + } + + /** + * Override hardware volume keys and send to Kodi + */ + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (volumeKeyActionHandler == null) { + volumeKeyActionHandler = new VolumeKeyActionHandler(hostManager, this, this); + } + return volumeKeyActionHandler.handleDispatchKeyEvent(event) || super.dispatchKeyEvent( + event); + } + + private void showVolumeChangeDialog() { + VolumeControllerDialogFragmentListener volumeControllerDialogFragment = + new VolumeControllerDialogFragmentListener(); + volumeControllerDialogFragment.show(getSupportFragmentManager(), + VolumeControllerDialogFragmentListener.class.getName()); } /** @@ -704,4 +693,16 @@ public class RemoteActivity extends BaseActivity playlistFragment.forceRefreshPlaylist(); } } + + @Override + public void onHardwareVolumeKeyPressed() { + int currentPage = viewPager.getCurrentItem(); + if (!isPageWithVolumeController(currentPage)) { + showVolumeChangeDialog(); + } + } + + private boolean isPageWithVolumeController(int currentPage) { + return currentPage == 0; + } } diff --git a/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/OnHardwareVolumeKeyPressedCallback.java b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/OnHardwareVolumeKeyPressedCallback.java new file mode 100644 index 0000000..bc95bde --- /dev/null +++ b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/OnHardwareVolumeKeyPressedCallback.java @@ -0,0 +1,5 @@ +package org.xbmc.kore.ui.volumecontrollers; + +public interface OnHardwareVolumeKeyPressedCallback { + void onHardwareVolumeKeyPressed(); +} diff --git a/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeControllerDialogFragmentListener.java b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeControllerDialogFragmentListener.java new file mode 100644 index 0000000..bfc6c8b --- /dev/null +++ b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeControllerDialogFragmentListener.java @@ -0,0 +1,183 @@ +package org.xbmc.kore.ui.volumecontrollers; + +import android.app.Dialog; +import android.content.DialogInterface; +import android.os.Bundle; +import android.os.Handler; +import android.support.annotation.Nullable; +import android.support.v4.app.FragmentManager; +import android.support.v7.app.AppCompatDialogFragment; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.xbmc.kore.R; +import org.xbmc.kore.host.HostConnectionObserver; +import org.xbmc.kore.host.HostManager; +import org.xbmc.kore.jsonrpc.ApiCallback; +import org.xbmc.kore.jsonrpc.ApiMethod; +import org.xbmc.kore.jsonrpc.method.Application; +import org.xbmc.kore.ui.widgets.HighlightButton; +import org.xbmc.kore.ui.widgets.VolumeLevelIndicator; +import org.xbmc.kore.utils.LogUtils; + +import butterknife.ButterKnife; +import butterknife.InjectView; + +public class VolumeControllerDialogFragmentListener extends AppCompatDialogFragment + implements HostConnectionObserver.ApplicationEventsObserver, + OnHardwareVolumeKeyPressedCallback, VolumeLevelIndicator.VolumeBarTouchTrackerListener { + + private static final String TAG = LogUtils.makeLogTag(VolumeControllerDialogFragmentListener.class); + private static final int AUTO_DISMISS_DELAY = 2000; + + @InjectView(R.id.npp_volume_mute) + HighlightButton volumeMuteButton; + @InjectView(R.id.npp_volume_muted_indicator) + HighlightButton volumeMutedIndicatorButton; + @InjectView(R.id.npp_volume_level_indicator) + VolumeLevelIndicator volumeLevelIndicator; + + private Handler callbackHandler = new Handler(); + private VolumeKeyActionHandler volumeKeyActionHandler; + private HostManager hostManager = null; + private ApiCallback defaultIntActionCallback = ApiMethod.getDefaultActionCallback(); + private View.OnClickListener onMuteToggleOnClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + cancelDismissDialog(); + Application.SetMute action = new Application.SetMute(); + action.execute(hostManager.getConnection(), new ApiCallback() { + @Override + public void onSuccess(Boolean result) { + //We depend on the listener to correct the mute button state + } + + @Override + public void onError(int errorCode, String description) { + LogUtils.LOGE(TAG, + "Got an error calling Application.SetMute. Error code: " + errorCode + + ", description: " + description); + } + }, callbackHandler); + } + }; + private long lastVolumeChangeInteractionEvent; + private Runnable dismissDialog = new Runnable() { + @Override + public void run() { + long timeSinceLastEvent = System.currentTimeMillis() - lastVolumeChangeInteractionEvent; + if (timeSinceLastEvent >= AUTO_DISMISS_DELAY) { + Dialog dialog = getDialog(); + if (dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + } + } + }; + + @Override + public void onResume() { + super.onResume(); + if (volumeKeyActionHandler == null) { + volumeKeyActionHandler = new VolumeKeyActionHandler(hostManager, getContext(), this); + } + getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() { + @Override + public boolean onKey(android.content.DialogInterface dialog, int keyCode, + android.view.KeyEvent event) { + + return volumeKeyActionHandler.handleDispatchKeyEvent(event); + } + }); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.volume_controller_dialog, container, false); + ButterKnife.inject(this, rootView); + + return rootView; + } + + @Override + public void show(FragmentManager manager, String tag) { + super.show(manager, tag); + delayedDismissDialog(); + } + + @Override + public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + hostManager = HostManager.getInstance(getContext()); + + setListeners(); + + registerObserver(); + // for orientation change + delayedDismissDialog(); + } + + private void registerObserver() { + HostConnectionObserver hostConnectionObserver = hostManager.getHostConnectionObserver(); + if (hostConnectionObserver == null) { + return; + } + + hostConnectionObserver.registerApplicationObserver(this, true); + hostConnectionObserver.forceRefreshResults(); + } + + private void setListeners() { + volumeMuteButton.setOnClickListener(onMuteToggleOnClickListener); + volumeMutedIndicatorButton.setOnClickListener(onMuteToggleOnClickListener); + + volumeLevelIndicator.setOnVolumeChangeListener( + new VolumeLevelIndicator.OnVolumeChangeListener() { + @Override + public void onVolumeChanged(int volume) { + cancelDismissDialog(); + new Application.SetVolume(volume).execute(hostManager.getConnection(), + defaultIntActionCallback, callbackHandler); + } + }); + volumeLevelIndicator.setVolumeBarTouchTrackerListener(this); + } + + @Override + public void applicationOnVolumeChanged(int volume, boolean muted) { + volumeLevelIndicator.setVolume(muted, volume); + + volumeMutedIndicatorButton.setVisibility(muted ? View.VISIBLE : View.GONE); + volumeMutedIndicatorButton.setHighlight(muted); + + volumeMuteButton.setHighlight(muted); + } + + @Override + public void onHardwareVolumeKeyPressed() { + delayedDismissDialog(); + } + + private void delayedDismissDialog() { + cancelDismissDialog(); + callbackHandler.postDelayed(dismissDialog, AUTO_DISMISS_DELAY); + } + + private void cancelDismissDialog() { + lastVolumeChangeInteractionEvent = System.currentTimeMillis(); + callbackHandler.removeCallbacks(dismissDialog); + } + + @Override + public void onStartTrackingTouch() { + cancelDismissDialog(); + } + + @Override + public void onStopTrackingTouch() { + delayedDismissDialog(); + } +} diff --git a/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeKeyActionHandler.java b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeKeyActionHandler.java new file mode 100644 index 0000000..ccf7435 --- /dev/null +++ b/app/src/main/java/org/xbmc/kore/ui/volumecontrollers/VolumeKeyActionHandler.java @@ -0,0 +1,62 @@ +package org.xbmc.kore.ui.volumecontrollers; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.view.KeyEvent; + +import org.xbmc.kore.Settings; +import org.xbmc.kore.host.HostManager; +import org.xbmc.kore.jsonrpc.method.Application; +import org.xbmc.kore.jsonrpc.type.GlobalType; + +public class VolumeKeyActionHandler { + + private final HostManager hostManager; + private final Context context; + private final OnHardwareVolumeKeyPressedCallback onHardwareVolumeKeyPressedCallback; + + public VolumeKeyActionHandler(HostManager hostManager, Context context, + @Nullable OnHardwareVolumeKeyPressedCallback onHardwareVolumeKeyPressedCallback) { + this.hostManager = hostManager; + this.context = context; + this.onHardwareVolumeKeyPressedCallback = onHardwareVolumeKeyPressedCallback; + } + + public boolean handleDispatchKeyEvent(KeyEvent event) { + if (shouldInterceptKey()) { + int action = event.getAction(); + int keyCode = event.getKeyCode(); + if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { + if (action == KeyEvent.ACTION_DOWN) { + notifyCallback(); + setVolume(GlobalType.IncrementDecrement.INCREMENT); + } + return true; + } + else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { + if (action == KeyEvent.ACTION_DOWN) { + notifyCallback(); + setVolume(GlobalType.IncrementDecrement.DECREMENT); + } + return true; + } + } + return false; + } + + private void setVolume(String volume) { + new Application.SetVolume(volume).execute(hostManager.getConnection(), null, null); + } + + private boolean shouldInterceptKey() { + return android.support.v7.preference.PreferenceManager.getDefaultSharedPreferences(context) + .getBoolean(Settings.KEY_PREF_USE_HARDWARE_VOLUME_KEYS, + Settings.DEFAULT_PREF_USE_HARDWARE_VOLUME_KEYS); + } + + private void notifyCallback() { + if (onHardwareVolumeKeyPressedCallback != null) { + onHardwareVolumeKeyPressedCallback.onHardwareVolumeKeyPressed(); + } + } +} diff --git a/app/src/main/java/org/xbmc/kore/ui/widgets/HighlightButton.java b/app/src/main/java/org/xbmc/kore/ui/widgets/HighlightButton.java index f253daf..cff7678 100644 --- a/app/src/main/java/org/xbmc/kore/ui/widgets/HighlightButton.java +++ b/app/src/main/java/org/xbmc/kore/ui/widgets/HighlightButton.java @@ -23,6 +23,7 @@ import android.util.AttributeSet; import org.xbmc.kore.R; public class HighlightButton extends AppCompatImageButton { + private int colorFilter; private boolean highlight; @@ -56,10 +57,12 @@ public class HighlightButton extends AppCompatImageButton { } private void setStyle(Context context) { - TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(new int[]{ - R.attr.colorAccent}); - colorFilter = styledAttributes.getColor(styledAttributes.getIndex(0), - context.getResources().getColor(R.color.accent_default)); - styledAttributes.recycle(); + if (!this.isInEditMode()) { + TypedArray styledAttributes = context.getTheme().obtainStyledAttributes( + new int[]{R.attr.colorAccent}); + colorFilter = styledAttributes.getColor(styledAttributes.getIndex(0), + context.getResources().getColor(R.color.accent_default)); + styledAttributes.recycle(); + } } } diff --git a/app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java b/app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java index 61b2630..c4c1769 100644 --- a/app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java +++ b/app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java @@ -33,11 +33,17 @@ public class VolumeLevelIndicator extends LinearLayout { @InjectView(R.id.vli_volume_text) TextView volumeTextView; private OnVolumeChangeListener onVolumeChangeListener; + private VolumeBarTouchTrackerListener volumeBarTouchTrackerListener; public interface OnVolumeChangeListener { void onVolumeChanged(int volume); } + public interface VolumeBarTouchTrackerListener { + void onStartTrackingTouch(); + void onStopTrackingTouch(); + } + public VolumeLevelIndicator(Context context) { super(context); initializeView(context); @@ -67,13 +73,19 @@ public class VolumeLevelIndicator extends LinearLayout { @Override public void onStartTrackingTouch(SeekBar seekBar) { - + if (volumeBarTouchTrackerListener != null) { + volumeBarTouchTrackerListener.onStartTrackingTouch(); + } } @Override public void onStopTrackingTouch(SeekBar seekBar) { - if (onVolumeChangeListener != null) + if (onVolumeChangeListener != null) { onVolumeChangeListener.onVolumeChanged(seekBar.getProgress()); + if (volumeBarTouchTrackerListener != null) { + volumeBarTouchTrackerListener.onStopTrackingTouch(); + } + } } }); } @@ -82,6 +94,11 @@ public class VolumeLevelIndicator extends LinearLayout { this.onVolumeChangeListener = onVolumeChangeListener; } + public void setVolumeBarTouchTrackerListener( + VolumeBarTouchTrackerListener volumeBarTouchTrackerListener) { + this.volumeBarTouchTrackerListener = volumeBarTouchTrackerListener; + } + /** * Sets UI volume state * @param muted diff --git a/app/src/main/res/layout/volume_controller_dialog.xml b/app/src/main/res/layout/volume_controller_dialog.xml new file mode 100644 index 0000000..7ff8e1a --- /dev/null +++ b/app/src/main/res/layout/volume_controller_dialog.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + \ No newline at end of file