Merge pull request #787 from mfietz/feature/queue-lock

Queue Lock: Swipe and drag can be disabled
This commit is contained in:
Tom Hennen 2015-05-03 14:49:03 -04:00
commit cd4bd0e37d
29 changed files with 109 additions and 5 deletions

View File

@ -14,9 +14,9 @@ import android.widget.TextView;
import com.squareup.picasso.Picasso; import com.squareup.picasso.Picasso;
import de.danoeh.antennapod.R; import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.feed.EventDistributor;
import de.danoeh.antennapod.core.feed.FeedItem; import de.danoeh.antennapod.core.feed.FeedItem;
import de.danoeh.antennapod.core.feed.FeedMedia; import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.storage.DownloadRequester; import de.danoeh.antennapod.core.storage.DownloadRequester;
import de.danoeh.antennapod.core.util.Converter; import de.danoeh.antennapod.core.util.Converter;
@ -31,6 +31,8 @@ public class QueueListAdapter extends BaseAdapter {
private final ActionButtonCallback actionButtonCallback; private final ActionButtonCallback actionButtonCallback;
private final ActionButtonUtils actionButtonUtils; private final ActionButtonUtils actionButtonUtils;
private boolean locked;
public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) { public QueueListAdapter(Context context, ItemAccess itemAccess, ActionButtonCallback actionButtonCallback) {
super(); super();
@ -38,6 +40,12 @@ public class QueueListAdapter extends BaseAdapter {
this.itemAccess = itemAccess; this.itemAccess = itemAccess;
this.actionButtonUtils = new ActionButtonUtils(context); this.actionButtonUtils = new ActionButtonUtils(context);
this.actionButtonCallback = actionButtonCallback; this.actionButtonCallback = actionButtonCallback;
locked = UserPreferences.isQueueLocked();
}
public void setLocked(boolean locked) {
this.locked = locked;
notifyDataSetChanged();
} }
@Override @Override
@ -67,6 +75,7 @@ public class QueueListAdapter extends BaseAdapter {
.getSystemService(Context.LAYOUT_INFLATER_SERVICE); .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.queue_listitem, convertView = inflater.inflate(R.layout.queue_listitem,
parent, false); parent, false);
holder.dragHandle = (ImageView) convertView.findViewById(R.id.drag_handle);
holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage); holder.imageView = (ImageView) convertView.findViewById(R.id.imgvImage);
holder.title = (TextView) convertView.findViewById(R.id.txtvTitle); holder.title = (TextView) convertView.findViewById(R.id.txtvTitle);
holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate); holder.pubDate = (TextView) convertView.findViewById(R.id.txtvPubDate);
@ -83,6 +92,12 @@ public class QueueListAdapter extends BaseAdapter {
holder = (Holder) convertView.getTag(); holder = (Holder) convertView.getTag();
} }
if(locked) {
holder.dragHandle.setVisibility(View.GONE);
} else {
holder.dragHandle.setVisibility(View.VISIBLE);
}
holder.title.setText(item.getTitle()); holder.title.setText(item.getTitle());
FeedMedia media = item.getMedia(); FeedMedia media = item.getMedia();
@ -143,6 +158,7 @@ public class QueueListAdapter extends BaseAdapter {
static class Holder { static class Holder {
ImageView dragHandle;
ImageView imageView; ImageView imageView;
TextView title; TextView title;
TextView pubDate; TextView pubDate;

View File

@ -48,7 +48,6 @@ import de.danoeh.antennapod.core.util.QueueSorter;
import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken; import de.danoeh.antennapod.core.util.gui.FeedItemUndoToken;
import de.danoeh.antennapod.core.util.gui.UndoBarController; import de.danoeh.antennapod.core.util.gui.UndoBarController;
import de.danoeh.antennapod.menuhandler.MenuItemUtils; import de.danoeh.antennapod.menuhandler.MenuItemUtils;
import de.danoeh.antennapod.menuhandler.NavDrawerActivity;
import de.greenrobot.event.EventBus; import de.greenrobot.event.EventBus;
/** /**
@ -67,6 +66,8 @@ public class QueueFragment extends Fragment {
private TextView txtvEmpty; private TextView txtvEmpty;
private ProgressBar progLoading; private ProgressBar progLoading;
private MenuItem queueLock;
private UndoBarController<FeedItemUndoToken> undoBarController; private UndoBarController<FeedItemUndoToken> undoBarController;
private List<FeedItem> queue; private List<FeedItem> queue;
@ -221,6 +222,9 @@ public class QueueFragment extends Fragment {
return false; return false;
} }
}); });
MenuItemUtils.refreshLockItem(getActivity(), menu, queueLock);
isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker); isUpdatingFeeds = MenuItemUtils.updateRefreshMenuItem(menu, R.id.refresh_item, updateRefreshMenuItemChecker);
} }
} }
@ -229,6 +233,17 @@ public class QueueFragment extends Fragment {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
if (!super.onOptionsItemSelected(item)) { if (!super.onOptionsItemSelected(item)) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.queue_lock:
boolean locked = !UserPreferences.isQueueLocked();
if(locked) {
listView.setDragEnabled(false);
} else {
listView.setDragEnabled(true);
}
UserPreferences.setQueueLocked(locked);
getActivity().supportInvalidateOptionsMenu();
listAdapter.setLocked(locked);
return true;
case R.id.refresh_item: case R.id.refresh_item:
List<Feed> feeds = ((MainActivity) getActivity()).getFeeds(); List<Feed> feeds = ((MainActivity) getActivity()).getFeeds();
if (feeds != null) { if (feeds != null) {
@ -330,6 +345,12 @@ public class QueueFragment extends Fragment {
progLoading = (ProgressBar) root.findViewById(R.id.progLoading); progLoading = (ProgressBar) root.findViewById(R.id.progLoading);
listView.setEmptyView(txtvEmpty); listView.setEmptyView(txtvEmpty);
if(UserPreferences.isQueueLocked()) {
listView.setDragEnabled(false);
} else {
listView.setDragEnabled(true);
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override @Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) { public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

View File

@ -1,11 +1,16 @@
package de.danoeh.antennapod.menuhandler; package de.danoeh.antennapod.menuhandler;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Build;
import android.support.v4.view.MenuItemCompat; import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.SearchView; import android.support.v7.widget.SearchView;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import de.danoeh.antennapod.core.R; import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.preferences.UserPreferences;
/** /**
* Utilities for menu items * Utilities for menu items
@ -14,9 +19,32 @@ public class MenuItemUtils extends de.danoeh.antennapod.core.menuhandler.MenuIte
public static MenuItem addSearchItem(Menu menu, SearchView searchView) { public static MenuItem addSearchItem(Menu menu, SearchView searchView) {
MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label); MenuItem item = menu.add(Menu.NONE, R.id.search_item, Menu.NONE, R.string.search_label);
MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_ALWAYS); MenuItemCompat.setShowAsAction(item, MenuItemCompat.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItemCompat.SHOW_AS_ACTION_IF_ROOM);
MenuItemCompat.setActionView(item, searchView); MenuItemCompat.setActionView(item, searchView);
if(Build.VERSION.SDK_INT < 14) {
SearchView.SearchAutoComplete textField = (SearchView.SearchAutoComplete) searchView.findViewById(de.danoeh.antennapod.R.id.search_src_text);
if(UserPreferences.getTheme() == de.danoeh.antennapod.R.style.Theme_AntennaPod_Dark) {
textField.setTextColor(Resources.getSystem().getColor(android.R.color.white));
} else {
textField.setTextColor(Resources.getSystem().getColor(android.R.color.black));
}
}
return item; return item;
} }
public static void refreshLockItem(Context context, Menu menu, MenuItem queueLock) {
queueLock = menu.findItem(de.danoeh.antennapod.R.id.queue_lock);
int[] lockIcons = new int[] { de.danoeh.antennapod.R.attr.ic_lock_open, de.danoeh.antennapod.R.attr.ic_lock_closed };
TypedArray ta = context.obtainStyledAttributes(lockIcons);
if (UserPreferences.isQueueLocked()) {
queueLock.setTitle(de.danoeh.antennapod.R.string.unlock_queue);
queueLock.setIcon(ta.getDrawable(1));
} else {
queueLock.setTitle(de.danoeh.antennapod.R.string.lock_queue);
queueLock.setIcon(ta.getDrawable(0));
}
}
} }

View File

@ -1,17 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="@dimen/listitem_threeline_height" android:layout_height="@dimen/listitem_threeline_height"
android:orientation="horizontal" android:orientation="horizontal"
android:paddingLeft="16dp"
tools:background="@android:color/darker_gray" > tools:background="@android:color/darker_gray" >
<ImageView <ImageView
android:id="@+id/drag_handle" android:id="@+id/drag_handle"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginLeft="8dp" android:layout_marginLeft="-8dp"
android:layout_marginRight="-64dp" android:layout_marginRight="-64dp"
android:contentDescription="@string/drag_handle_content_description" android:contentDescription="@string/drag_handle_content_description"
android:scaleType="fitXY" android:scaleType="fitXY"

View File

@ -3,6 +3,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android" <menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"> xmlns:custom="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/queue_lock"
android:title=""
android:menuCategory="container"
custom:showAsAction="always" />
<item <item
android:id="@+id/refresh_item" android:id="@+id/refresh_item"
android:title="@string/refresh_label" android:title="@string/refresh_label"

View File

@ -66,6 +66,7 @@ public class UserPreferences implements
private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify"; private static final String PREF_PERSISTENT_NOTIFICATION = "prefPersistNotify";
public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront"; public static final String PREF_QUEUE_ADD_TO_FRONT = "prefQueueAddToFront";
public static final String PREF_HIDDEN_DRAWER_ITEMS = "prefHiddenDrawerItems"; public static final String PREF_HIDDEN_DRAWER_ITEMS = "prefHiddenDrawerItems";
public static final String PREF_QUEUE_LOCKED = "prefQueueLocked";
// TODO: Make this value configurable // TODO: Make this value configurable
private static final float PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD_DEFAULT = 0.8f; private static final float PREF_AUTO_FLATTR_PLAYED_DURATION_THRESHOLD_DEFAULT = 0.8f;
@ -103,6 +104,7 @@ public class UserPreferences implements
private int notifyPriority; private int notifyPriority;
private boolean persistNotify; private boolean persistNotify;
private List<String> hiddenDrawerItems; private List<String> hiddenDrawerItems;
private boolean queueLocked;
private UserPreferences(Context context) { private UserPreferences(Context context) {
this.context = context; this.context = context;
@ -172,6 +174,7 @@ public class UserPreferences implements
} }
persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false); persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false);
hiddenDrawerItems = Arrays.asList(StringUtils.split(sp.getString(PREF_HIDDEN_DRAWER_ITEMS, ""), ',')); hiddenDrawerItems = Arrays.asList(StringUtils.split(sp.getString(PREF_HIDDEN_DRAWER_ITEMS, ""), ','));
queueLocked = sp.getBoolean(PREF_QUEUE_LOCKED, false);
} }
private int readThemeValue(String valueFromPrefs) { private int readThemeValue(String valueFromPrefs) {
@ -395,6 +398,11 @@ public class UserPreferences implements
return instance.isFreshInstall; return instance.isFreshInstall;
} }
public static boolean isQueueLocked() {
instanceAvailable();
return instance.queueLocked;
}
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sp, String key) { public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
Log.d(TAG, "Registered change of user preferences. Key: " + key); Log.d(TAG, "Registered change of user preferences. Key: " + key);
@ -468,6 +476,8 @@ public class UserPreferences implements
persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false); persistNotify = sp.getBoolean(PREF_PERSISTENT_NOTIFICATION, false);
} else if (key.equals(PREF_HIDDEN_DRAWER_ITEMS)) { } else if (key.equals(PREF_HIDDEN_DRAWER_ITEMS)) {
hiddenDrawerItems = Arrays.asList(StringUtils.split(sp.getString(PREF_HIDDEN_DRAWER_ITEMS, ""), ',')); hiddenDrawerItems = Arrays.asList(StringUtils.split(sp.getString(PREF_HIDDEN_DRAWER_ITEMS, ""), ','));
} else if(key.equals(PREF_QUEUE_LOCKED)) {
queueLocked = sp.getBoolean(PREF_QUEUE_LOCKED, false);
} }
} }
@ -554,6 +564,15 @@ public class UserPreferences implements
.commit(); .commit();
} }
public static void setQueueLocked(boolean locked) {
instanceAvailable();
instance.queueLocked = locked;
PreferenceManager.getDefaultSharedPreferences(instance.context)
.edit()
.putBoolean(PREF_QUEUE_LOCKED, locked)
.commit();
}
/** /**
* Return the folder where the app stores all of its data. This method will * Return the folder where the app stores all of its data. This method will

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 621 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 838 B

View File

@ -37,6 +37,8 @@
<attr name="av_ff_big" format="reference"/> <attr name="av_ff_big" format="reference"/>
<attr name="av_rew_big" format="reference"/> <attr name="av_rew_big" format="reference"/>
<attr name="ic_settings" format="reference"/> <attr name="ic_settings" format="reference"/>
<attr name="ic_lock_open" format="reference"/>
<attr name="ic_lock_closed" format="reference"/>
<!-- Used in itemdescription --> <!-- Used in itemdescription -->
<attr name="non_transparent_background" format="reference"/> <attr name="non_transparent_background" format="reference"/>

View File

@ -161,6 +161,8 @@
<string name="unknown_media_key">AntennaPod - Unknown media key: %1$d</string> <string name="unknown_media_key">AntennaPod - Unknown media key: %1$d</string>
<!-- Queue operations --> <!-- Queue operations -->
<string name="lock_queue">Lock queue</string>
<string name="unlock_queue">Unlock queue</string>
<string name="clear_queue_label">Clear queue</string> <string name="clear_queue_label">Clear queue</string>
<string name="undo">Undo</string> <string name="undo">Undo</string>
<string name="removed_from_queue">Item removed</string> <string name="removed_from_queue">Item removed</string>

View File

@ -42,6 +42,8 @@
<item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item> <item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item>
<item name="attr/av_rew_big">@drawable/ic_fast_rewind_grey600_36dp</item> <item name="attr/av_rew_big">@drawable/ic_fast_rewind_grey600_36dp</item>
<item name="attr/ic_settings">@drawable/ic_settings_grey600_24dp</item> <item name="attr/ic_settings">@drawable/ic_settings_grey600_24dp</item>
<item name="attr/ic_lock_open">@drawable/ic_lock_open_grey600_24dp</item>
<item name="attr/ic_lock_closed">@drawable/ic_lock_closed_grey600_24dp</item>
</style> </style>
<style name="Theme.AntennaPod.Dark" parent="@style/Theme.AppCompat"> <style name="Theme.AntennaPod.Dark" parent="@style/Theme.AppCompat">
@ -84,6 +86,8 @@
<item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item> <item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item>
<item name="attr/av_rew_big">@drawable/ic_fast_rewind_white_36dp</item> <item name="attr/av_rew_big">@drawable/ic_fast_rewind_white_36dp</item>
<item name="attr/ic_settings">@drawable/ic_settings_white_24dp</item> <item name="attr/ic_settings">@drawable/ic_settings_white_24dp</item>
<item name="attr/ic_lock_open">@drawable/ic_lock_open_white_24dp</item>
<item name="attr/ic_lock_closed">@drawable/ic_lock_closed_white_24dp</item>
</style> </style>
<style name="Theme.AntennaPod.Light.NoTitle" parent="@style/Theme.AppCompat.Light.NoActionBar"> <style name="Theme.AntennaPod.Light.NoTitle" parent="@style/Theme.AppCompat.Light.NoActionBar">
@ -129,6 +133,8 @@
<item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item> <item name="attr/av_ff_big">@drawable/ic_fast_forward_grey600_36dp</item>
<item name="attr/av_rew_big">@drawable/ic_fast_rewind_grey600_36dp</item> <item name="attr/av_rew_big">@drawable/ic_fast_rewind_grey600_36dp</item>
<item name="attr/ic_settings">@drawable/ic_settings_grey600_24dp</item> <item name="attr/ic_settings">@drawable/ic_settings_grey600_24dp</item>
<item name="attr/ic_lock_open">@drawable/ic_lock_open_grey600_24dp</item>
<item name="attr/ic_lock_closed">@drawable/ic_lock_closed_grey600_24dp</item>
</style> </style>
<style name="Theme.AntennaPod.Dark.NoTitle" parent="@style/Theme.AppCompat.NoActionBar"> <style name="Theme.AntennaPod.Dark.NoTitle" parent="@style/Theme.AppCompat.NoActionBar">
@ -173,6 +179,8 @@
<item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item> <item name="attr/av_ff_big">@drawable/ic_fast_forward_white_36dp</item>
<item name="attr/av_rew_big">@drawable/ic_fast_rewind_white_36dp</item> <item name="attr/av_rew_big">@drawable/ic_fast_rewind_white_36dp</item>
<item name="attr/ic_settings">@drawable/ic_settings_white_24dp</item> <item name="attr/ic_settings">@drawable/ic_settings_white_24dp</item>
<item name="attr/ic_lock_open">@drawable/ic_lock_open_white_24dp</item>
<item name="attr/ic_lock_closed">@drawable/ic_lock_closed_white_24dp</item>
</style> </style>
<style name="Theme.AntennaPod.VideoPlayer" parent="@style/Theme.AntennaPod.Dark"> <style name="Theme.AntennaPod.VideoPlayer" parent="@style/Theme.AntennaPod.Dark">