From 85bcd846f2ba9b24fb22f7f02c37158b749d8a3f Mon Sep 17 00:00:00 2001 From: Martijn Brekhof Date: Thu, 22 Jun 2017 19:37:00 +0200 Subject: [PATCH] Implemented VolumeLevelIndicator widget (#406) * Refactored NowPlayingFragment to use new widget * Refactored UIUtils.highlightImageView to reduce code duplication --- .../xbmc/kore/ui/AbstractInfoFragment.java | 14 +-- .../sections/remote/NowPlayingFragment.java | 82 +++------------- .../kore/ui/widgets/VolumeLevelIndicator.java | 97 +++++++++++++++++++ .../java/org/xbmc/kore/utils/UIUtils.java | 26 +++-- .../main/res/layout/fragment_now_playing.xml | 20 +--- .../res/layout/volume_level_indicator.xml | 16 +++ 6 files changed, 151 insertions(+), 104 deletions(-) create mode 100644 app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java create mode 100644 app/src/main/res/layout/volume_level_indicator.xml diff --git a/app/src/main/java/org/xbmc/kore/ui/AbstractInfoFragment.java b/app/src/main/java/org/xbmc/kore/ui/AbstractInfoFragment.java index 64bc686..28c08c8 100644 --- a/app/src/main/java/org/xbmc/kore/ui/AbstractInfoFragment.java +++ b/app/src/main/java/org/xbmc/kore/ui/AbstractInfoFragment.java @@ -464,7 +464,7 @@ abstract public class AbstractInfoFragment extends AbstractFragment if (checkStoragePermission()) { if (Settings.allowedDownloadNetworkTypes(getActivity()) != 0) { listener.onClick(view); - setButtonState(downloadButton, true); + UIUtils.highlightImageView(getActivity(), downloadButton, true); } else { Toast.makeText(getActivity(), R.string.no_connection_type_selected, Toast.LENGTH_SHORT).show(); } @@ -500,7 +500,7 @@ abstract public class AbstractInfoFragment extends AbstractFragment * @param state true if item has been watched/listened too, false otherwise */ protected void setDownloadButtonState(boolean state) { - setButtonState(downloadButton, state); + UIUtils.highlightImageView(getActivity(), downloadButton, state); } /** @@ -515,16 +515,8 @@ abstract public class AbstractInfoFragment extends AbstractFragment setToggleButtonState(pinUnpinButton, state); } - private void setButtonState(ImageButton button, boolean state) { - if (state) { - UIUtils.highlightImageView(getActivity(), button); - } else { - button.clearColorFilter(); - } - } - private void setToggleButtonState(ImageButton button, boolean state) { - setButtonState(button, state); + UIUtils.highlightImageView(getActivity(), button, state); button.setTag(state); } diff --git a/app/src/main/java/org/xbmc/kore/ui/sections/remote/NowPlayingFragment.java b/app/src/main/java/org/xbmc/kore/ui/sections/remote/NowPlayingFragment.java index 275010d..e871fce 100644 --- a/app/src/main/java/org/xbmc/kore/ui/sections/remote/NowPlayingFragment.java +++ b/app/src/main/java/org/xbmc/kore/ui/sections/remote/NowPlayingFragment.java @@ -34,7 +34,6 @@ import android.widget.ImageView; import android.widget.PopupMenu; import android.widget.RelativeLayout; import android.widget.ScrollView; -import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; @@ -57,6 +56,7 @@ import org.xbmc.kore.jsonrpc.type.VideoType; import org.xbmc.kore.ui.generic.GenericSelectDialog; import org.xbmc.kore.ui.sections.video.AllCastActivity; import org.xbmc.kore.ui.widgets.MediaProgressIndicator; +import org.xbmc.kore.ui.widgets.VolumeLevelIndicator; import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.Utils; @@ -153,8 +153,7 @@ public class NowPlayingFragment extends Fragment @InjectView(R.id.media_undertitle) TextView mediaUndertitle; @InjectView(R.id.progress_info) MediaProgressIndicator mediaProgressIndicator; - @InjectView(R.id.volume_bar) SeekBar volumeSeekBar; - @InjectView(R.id.volume_text) TextView volumeTextView; + @InjectView(R.id.volume_level_indicator) VolumeLevelIndicator volumeLevelIndicator; @InjectView(R.id.media_details) RelativeLayout mediaDetailsPanel; @InjectView(R.id.rating) TextView mediaRating; @@ -202,6 +201,14 @@ public class NowPlayingFragment extends Fragment } }); + volumeLevelIndicator.setOnVolumeChangeListener(new VolumeLevelIndicator.OnVolumeChangeListener() { + @Override + public void onVolumeChanged(int volume) { + new Application.SetVolume(volume).execute(hostManager.getConnection(), + defaultIntActionCallback, new Handler()); + } + }); + // // Pad main content view to overlap with bottom system bar // UIUtils.setPaddingForSystemBars(getActivity(), mediaPanel, false, false, true); // mediaPanel.setClipToPadding(false); @@ -300,18 +307,10 @@ public class NowPlayingFragment extends Fragment // the mute state on the host. We do this to make it clear to the user that the button // was pressed. HostConnectionObserver.HostState hostState = hostConnectionObserver.getHostState(); - setVolumeState(!hostState.isVolumeMuted(), hostState.getVolumeLevel()); + UIUtils.highlightImageView(getActivity(), volumeMuteButton, !hostState.isVolumeMuted()); 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) { } - }, callbackHandler); + action.execute(hostManager.getConnection(), defaultBooleanActionCallback, new Handler()); } @OnClick(R.id.shuffle) @@ -618,7 +617,8 @@ public class NowPlayingFragment extends Fragment @Override public void applicationOnVolumeChanged(int volume, boolean muted) { - setVolumeState(muted, volume); + volumeLevelIndicator.setVolume(muted, volume); + UIUtils.highlightImageView(getActivity(), volumeMuteButton, muted); } // Ignore this @@ -797,8 +797,6 @@ public class NowPlayingFragment extends Fragment } styledAttributes.recycle(); - volumeSeekBar.setOnSeekBarChangeListener(volumeSeekbarChangeListener); - Resources resources = getActivity().getResources(); DisplayMetrics displayMetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); @@ -916,56 +914,4 @@ public class NowPlayingFragment extends Fragment if (plot == null) return null; return plot.replaceAll("\\[.*\\]", ""); } - - private int mediaTotalTime = 0, - mediaCurrentTime = 0; // s - private static final int SEEK_BAR_UPDATE_INTERVAL = 1000; // ms - - /** - * Sets UI volume state - * @param muted whether volume is muted - * @param volume - */ - private void setVolumeState(Boolean muted, int volume) { - if (!isAdded()) return; - - if (muted) { - volumeSeekBar.setProgress(0); - volumeTextView.setText(R.string.muted); - - Resources.Theme theme = getActivity().getTheme(); - TypedArray styledAttributes = theme.obtainStyledAttributes(new int[] { - R.attr.colorAccent}); - volumeMuteButton.setColorFilter( - styledAttributes.getColor(0, - getActivity().getResources().getColor(R.color.accent_default))); - styledAttributes.recycle(); - - } else { - volumeSeekBar.setProgress(volume); - volumeTextView.setText(String.valueOf(volume)); - volumeMuteButton.clearColorFilter(); - } - } - - private SeekBar.OnSeekBarChangeListener volumeSeekbarChangeListener = new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) { - volumeTextView.setText(String.valueOf(progress)); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - new Application.SetVolume(seekBar.getProgress()) - .execute(hostManager.getConnection(), defaultIntActionCallback, callbackHandler); - - } - }; } 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 new file mode 100644 index 0000000..0a12553 --- /dev/null +++ b/app/src/main/java/org/xbmc/kore/ui/widgets/VolumeLevelIndicator.java @@ -0,0 +1,97 @@ +/* + * Copyright 2017 Martijn Brekhof. All rights reserved. + * + * 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 org.xbmc.kore.ui.widgets; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.SeekBar; +import android.widget.TextView; + +import org.xbmc.kore.R; + +public class VolumeLevelIndicator extends LinearLayout { + private SeekBar volumeSeekBar; + private TextView volumeTextView; + + private OnVolumeChangeListener onVolumeChangeListener; + + public interface OnVolumeChangeListener { + void onVolumeChanged(int volume); + } + + public VolumeLevelIndicator(Context context) { + super(context); + initializeView(context); + } + + public VolumeLevelIndicator(Context context, AttributeSet attributeSet) { + super(context, attributeSet); + initializeView(context); + } + + private void initializeView(Context context) { + LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + inflater.inflate(R.layout.volume_level_indicator, this); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + volumeSeekBar = (SeekBar) findViewById(R.id.vli_seek_bar); + volumeTextView = (TextView) findViewById(R.id.vli_volume_text); + + volumeSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) + volumeTextView.setText(String.valueOf(progress)); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + if (onVolumeChangeListener != null) + onVolumeChangeListener.onVolumeChanged(seekBar.getProgress()); + } + }); + } + + public void setOnVolumeChangeListener(OnVolumeChangeListener onVolumeChangeListener) { + this.onVolumeChangeListener = onVolumeChangeListener; + } + + /** + * Sets UI volume state + * @param muted + * @param volume + */ + public void setVolume(boolean muted, int volume) { + if (muted) { + volumeTextView.setText(R.string.muted); + volumeSeekBar.setProgress(0); + } else { + volumeTextView.setText(String.valueOf(volume)); + volumeSeekBar.setProgress(volume); + } + } +} diff --git a/app/src/main/java/org/xbmc/kore/utils/UIUtils.java b/app/src/main/java/org/xbmc/kore/utils/UIUtils.java index d83cdea..d009e14 100644 --- a/app/src/main/java/org/xbmc/kore/utils/UIUtils.java +++ b/app/src/main/java/org/xbmc/kore/utils/UIUtils.java @@ -561,13 +561,23 @@ public class UIUtils { } } - public static void highlightImageView(Context context, ImageView view) { - Resources.Theme theme = context.getTheme(); - TypedArray styledAttributes = theme.obtainStyledAttributes(new int[]{ - R.attr.colorAccent}); - view.setColorFilter( - styledAttributes.getColor(0, - context.getResources().getColor(R.color.accent_default))); - styledAttributes.recycle(); + /** + * Highlights an image view + * @param context + * @param view + * @param highlight true if the image view should be highlighted, false otherwise + */ + public static void highlightImageView(Context context, ImageView view, boolean highlight) { + if (highlight) { + Resources.Theme theme = context.getTheme(); + TypedArray styledAttributes = theme.obtainStyledAttributes(new int[]{ + R.attr.colorAccent}); + view.setColorFilter( + styledAttributes.getColor(styledAttributes.getIndex(0), + context.getResources().getColor(R.color.accent_default))); + styledAttributes.recycle(); + } else { + view.clearColorFilter(); + } } } diff --git a/app/src/main/res/layout/fragment_now_playing.xml b/app/src/main/res/layout/fragment_now_playing.xml index 7586ce3..73170d5 100644 --- a/app/src/main/res/layout/fragment_now_playing.xml +++ b/app/src/main/res/layout/fragment_now_playing.xml @@ -169,26 +169,12 @@ style="@style/Widget.Button.Borderless" android:src="?attr/iconVolumeMute" android:contentDescription="@string/volume_mute"/> - - - - - + android:orientation="vertical"/> + + + + \ No newline at end of file