Prevent concurrent queue modifications from breaking the cast demo app UI
PiperOrigin-RevId: 233577854
This commit is contained in:
parent
3a5ed6b889
commit
55e6d1d708
@ -211,6 +211,7 @@ public class MainActivity extends AppCompatActivity
|
||||
private class QueueItemViewHolder extends RecyclerView.ViewHolder implements OnClickListener {
|
||||
|
||||
public final TextView textView;
|
||||
public MediaItem item;
|
||||
|
||||
public QueueItemViewHolder(TextView textView) {
|
||||
super(textView);
|
||||
@ -236,8 +237,9 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(QueueItemViewHolder holder, int position) {
|
||||
holder.item = playerManager.getItem(position);
|
||||
TextView view = holder.textView;
|
||||
view.setText(playerManager.getItem(position).title);
|
||||
view.setText(holder.item.title);
|
||||
// TODO: Solve coloring using the theme's ColorStateList.
|
||||
view.setTextColor(ColorUtils.setAlphaComponent(view.getCurrentTextColor(),
|
||||
position == playerManager.getCurrentItemIndex() ? 255 : 100));
|
||||
@ -278,7 +280,8 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
|
||||
int position = viewHolder.getAdapterPosition();
|
||||
if (playerManager.removeItem(position)) {
|
||||
QueueItemViewHolder queueItemHolder = (QueueItemViewHolder) viewHolder;
|
||||
if (playerManager.removeItem(queueItemHolder.item)) {
|
||||
mediaQueueListAdapter.notifyItemRemoved(position);
|
||||
// Update whichever item took its place, in case it became the new selected item.
|
||||
mediaQueueListAdapter.notifyItemChanged(position);
|
||||
@ -289,8 +292,9 @@ public class MainActivity extends AppCompatActivity
|
||||
public void clearView(RecyclerView recyclerView, ViewHolder viewHolder) {
|
||||
super.clearView(recyclerView, viewHolder);
|
||||
if (draggingFromPosition != C.INDEX_UNSET) {
|
||||
QueueItemViewHolder queueItemHolder = (QueueItemViewHolder) viewHolder;
|
||||
// A drag has ended. We reflect the media queue change in the player.
|
||||
if (!playerManager.moveItem(draggingFromPosition, draggingToPosition)) {
|
||||
if (!playerManager.moveItem(queueItemHolder.item, draggingToPosition)) {
|
||||
// The move failed. The entire sequence of onMove calls since the drag started needs to be
|
||||
// invalidated.
|
||||
mediaQueueListAdapter.notifyDataSetChanged();
|
||||
|
@ -168,10 +168,16 @@ import java.util.ArrayList;
|
||||
/**
|
||||
* Removes the item at the given index from the media queue.
|
||||
*
|
||||
* @param itemIndex The index of the item to remove.
|
||||
* @param item The item to remove.
|
||||
* @return Whether the removal was successful.
|
||||
*/
|
||||
public boolean removeItem(int itemIndex) {
|
||||
public boolean removeItem(MediaItem item) {
|
||||
int itemIndex = mediaQueue.indexOf(item);
|
||||
if (itemIndex == -1) {
|
||||
// This may happen if another sender app removes items while this sender app is in "swiping
|
||||
// an item" state.
|
||||
return false;
|
||||
}
|
||||
concatenatingMediaSource.removeMediaSource(itemIndex);
|
||||
mediaQueue.remove(itemIndex);
|
||||
if (currentPlayer == exoCastPlayer) {
|
||||
@ -188,20 +194,29 @@ import java.util.ArrayList;
|
||||
/**
|
||||
* Moves an item within the queue.
|
||||
*
|
||||
* @param fromIndex The index of the item to move.
|
||||
* @param toIndex The target index of the item in the queue.
|
||||
* @return Whether the item move was successful.
|
||||
* @param item The item to move. This method does nothing if {@code item} is not contained in the
|
||||
* queue.
|
||||
* @param toIndex The target index of the item in the queue. If {@code toIndex} exceeds the last
|
||||
* position in the queue, {@code toIndex} is clamped to match the largest possible value.
|
||||
* @return True if {@code item} was contained in the queue, and {@code toIndex} was a valid
|
||||
* position. False otherwise.
|
||||
*/
|
||||
public boolean moveItem(int fromIndex, int toIndex) {
|
||||
mediaQueue.add(toIndex, mediaQueue.remove(fromIndex));
|
||||
concatenatingMediaSource.moveMediaSource(fromIndex, toIndex);
|
||||
if (currentPlayer == exoCastPlayer) {
|
||||
exoCastPlayer.moveItemInQueue(fromIndex, toIndex);
|
||||
public boolean moveItem(MediaItem item, int toIndex) {
|
||||
int indexOfItem = mediaQueue.indexOf(item);
|
||||
if (indexOfItem == -1) {
|
||||
// This may happen if another sender app removes items while this sender app is in "dragging
|
||||
// an item" state.
|
||||
return false;
|
||||
}
|
||||
int clampedToIndex = Math.min(toIndex, mediaQueue.size() - 1);
|
||||
mediaQueue.add(clampedToIndex, mediaQueue.remove(indexOfItem));
|
||||
concatenatingMediaSource.moveMediaSource(indexOfItem, clampedToIndex);
|
||||
if (currentPlayer == exoCastPlayer) {
|
||||
exoCastPlayer.moveItemInQueue(indexOfItem, clampedToIndex);
|
||||
}
|
||||
|
||||
// Index update.
|
||||
maybeSetCurrentItemAndNotify(currentPlayer.getCurrentWindowIndex());
|
||||
return true;
|
||||
return clampedToIndex == toIndex;
|
||||
}
|
||||
|
||||
// Miscellaneous methods.
|
||||
|
Loading…
x
Reference in New Issue
Block a user