SelectionMode without ActionMode added, use of previous ListSelectionHelper as new SelectableHelper, so ListViews still can be available.
This commit is contained in:
parent
e8f04f3d7c
commit
801a9a6708
6 changed files with 371 additions and 264 deletions
|
@ -26,14 +26,10 @@ import android.os.Bundle;
|
|||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.helper.ItemTouchHelper;
|
||||
import android.view.ActionMode;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
@ -47,10 +43,13 @@ import org.linphone.core.ChatRoom;
|
|||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.CoreListenerStub;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.fragments.FragmentsAvailable;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
import org.linphone.ui.SwipeController;
|
||||
import org.linphone.ui.SwipeControllerActions;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -61,12 +60,8 @@ import static org.linphone.fragments.FragmentsAvailable.CHAT_LIST;
|
|||
* Sources: Linphone + https://enoent.fr/blog/2015/01/18/recyclerview-basics/
|
||||
* */
|
||||
|
||||
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ChatRoomsAdapter.ChatRoomViewHolder.ClickListener {
|
||||
public class ChatListFragment extends Fragment implements ContactsUpdatedListener, ChatRoomsAdapter.ChatRoomViewHolder.ClickListener, SelectableHelper.DeleteListener {
|
||||
|
||||
private ActionModeCallback actionModeCallback = new ActionModeCallback();
|
||||
private ActionMode actionMode;
|
||||
private LinearLayout mEditTopBar, mTopBar;
|
||||
private ImageView mEditButton, mSelectAllButton, mDeselectAllButton,mDeleteButton, mCancelButton;
|
||||
private RecyclerView mChatRoomsList;
|
||||
private TextView mNoChatHistory;
|
||||
private ImageView mNewDiscussionButton, mBackToCallButton;
|
||||
|
@ -77,6 +72,7 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
private ChatRoomListenerStub mChatRoomListener;
|
||||
private Context mContext;
|
||||
public List<ChatRoom> mRooms;
|
||||
private SelectableHelper mSelectionHelper;
|
||||
|
||||
@Override
|
||||
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
@ -91,37 +87,36 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
//Views definition
|
||||
mChatRoomsList = view.findViewById(R.id.chatList);
|
||||
mWaitLayout = view.findViewById(R.id.waitScreen);
|
||||
mEditTopBar = view.findViewById(R.id.edit_list);
|
||||
mTopBar = view.findViewById(R.id.top_bar);
|
||||
mSelectAllButton = view.findViewById(R.id.select_all);
|
||||
mDeselectAllButton = view.findViewById(R.id.deselect_all);
|
||||
mDeleteButton= view.findViewById(R.id.delete);
|
||||
mEditButton = view.findViewById(R.id.edit);
|
||||
mCancelButton = view.findViewById(R.id.cancel);
|
||||
mNewDiscussionButton = view.findViewById(R.id.new_discussion);
|
||||
mBackToCallButton = view.findViewById(R.id.back_in_call);
|
||||
|
||||
//Creation and affectation of adapter to the RecyclerView
|
||||
mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms,this);
|
||||
mSelectionHelper = new SelectableHelper(view, this);
|
||||
|
||||
mChatRoomsAdapter = new ChatRoomsAdapter(mContext, R.layout.chatlist_cell, mRooms,this, mSelectionHelper);
|
||||
mChatRoomsList.setAdapter(mChatRoomsAdapter);
|
||||
|
||||
mSelectionHelper.setAdapter(mChatRoomsAdapter);
|
||||
mSelectionHelper.setDialogMessage(R.string.chat_room_delete_dialog);
|
||||
|
||||
//Initialize the LayoutManager
|
||||
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mContext);
|
||||
mChatRoomsList.setLayoutManager(layoutManager);
|
||||
|
||||
|
||||
|
||||
|
||||
mWaitLayout.setVisibility(View.GONE);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//All commentend code below, until line 145, have to be uncommented to allow swipe actions.
|
||||
|
||||
//Actions allowed by swipe buttons
|
||||
|
||||
final SwipeController swipeController = new SwipeController(new SwipeControllerActions() {
|
||||
@Override
|
||||
/*final SwipeController swipeController = new SwipeController(new SwipeControllerActions() {
|
||||
*//*@Override
|
||||
public void onLeftClicked(int position) {
|
||||
super.onLeftClicked(position);
|
||||
}
|
||||
}*//*
|
||||
|
||||
@Override
|
||||
public void onRightClicked(int position) {
|
||||
|
@ -131,8 +126,9 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
|
||||
//Initialize swipe detection
|
||||
|
||||
ItemTouchHelper itemTouchhelper = new ItemTouchHelper(swipeController);
|
||||
itemTouchhelper.attachToRecyclerView(mChatRoomsList);
|
||||
|
||||
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(swipeController);
|
||||
itemTouchHelper.attachToRecyclerView(mChatRoomsList);
|
||||
|
||||
//Add swipe buttons
|
||||
mChatRoomsList.addItemDecoration(new RecyclerView.ItemDecoration() {
|
||||
|
@ -141,17 +137,12 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
swipeController.onDraw(c);
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
// Buttons onClickListeners definitions
|
||||
|
||||
mEditButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
//Start selection mode
|
||||
actionMode = getActivity().startActionMode(actionModeCallback);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
mNewDiscussionButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
@ -207,8 +198,9 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
|
||||
@Override
|
||||
public void onItemClicked(int position) {
|
||||
if (actionMode != null) {
|
||||
toggleSelection(position);
|
||||
if (mChatRoomsAdapter.isEditionEnabled()) {
|
||||
mChatRoomsAdapter.toggleSelection(position);
|
||||
|
||||
}else{
|
||||
ChatRoom room = (ChatRoom) mChatRoomsAdapter.getItem(position);
|
||||
LinphoneActivity.instance().goToChat(room.getPeerAddress().asString(),null);
|
||||
|
@ -217,143 +209,15 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
|
||||
@Override
|
||||
public boolean onItemLongClicked(int position) {
|
||||
if (actionMode == null) {
|
||||
if (mChatRoomsAdapter.isEditionEnabled()!=true) {
|
||||
//Start selection mode
|
||||
actionMode = getActivity().startActionMode(actionModeCallback);
|
||||
|
||||
mSelectionHelper.enterEditionMode();
|
||||
}
|
||||
toggleSelection(position);
|
||||
mChatRoomsAdapter.toggleSelection(position);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*Switch selection state of an item and handle
|
||||
* selection buttons visibility
|
||||
*/
|
||||
private void toggleSelection(int position) {
|
||||
|
||||
mChatRoomsAdapter.toggleSelection(position);
|
||||
int count = mChatRoomsAdapter.getSelectedItemCount();
|
||||
if (count < mChatRoomsAdapter.getItemCount()) {
|
||||
mDeselectAllButton.setVisibility(View.GONE);
|
||||
mSelectAllButton.setVisibility(View.VISIBLE);
|
||||
|
||||
}else{
|
||||
mSelectAllButton.setVisibility(View.GONE);
|
||||
mDeselectAllButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mChatRoomsAdapter.notifyItemChanged(position);
|
||||
actionMode.invalidate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Selection mode (ActionMode)
|
||||
|
||||
private class ActionModeCallback implements ActionMode.Callback {
|
||||
@SuppressWarnings("unused")
|
||||
private final String TAG = ActionModeCallback.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
||||
actionMode=mode;
|
||||
mTopBar.setVisibility(View.GONE);
|
||||
mEditTopBar.setVisibility(View.VISIBLE);
|
||||
|
||||
//Transmits ActionMode current state to the adapter
|
||||
for (Integer i = 0; i <= mChatRoomsAdapter.getItemCount(); i++) {
|
||||
mChatRoomsAdapter.setEditionMode(mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* Inflate custom menu, example for future plans
|
||||
*mode.getMenuInflater().inflate (R.menu.edit_list_menu, menu);
|
||||
*/
|
||||
|
||||
|
||||
mCancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
actionMode.finish();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/*Way to disable the sliding menu (left)
|
||||
* mSideMenu=(DrawerLayout) getActivity().findViewById(R.id.side_menu);
|
||||
* mSideMenu.setDrawerLockMode(1);
|
||||
* */
|
||||
|
||||
|
||||
//Add all non-selected items to the selection
|
||||
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) {
|
||||
if (!mChatRoomsAdapter.isSelected(i)) {
|
||||
toggleSelection(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//Remove all selected items from the selection
|
||||
mDeselectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
for (Integer i = 0; i < mChatRoomsAdapter.getItemCount(); i++) {
|
||||
if (mChatRoomsAdapter.isSelected(i)) {
|
||||
toggleSelection(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mDeleteButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mChatRoomsAdapter.removeItems(mChatRoomsAdapter.getSelectedItems());
|
||||
actionMode.finish();
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
||||
/*
|
||||
Meant to execute actions as Contextual Action Bar item is clicked,
|
||||
unused in our case as the CAB isn't used.
|
||||
No need for clickListeners.
|
||||
Example below for future evolution.
|
||||
|
||||
case R.id.delete:
|
||||
return true
|
||||
*/
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyActionMode(ActionMode mode) {
|
||||
|
||||
mChatRoomsAdapter.clearSelection();
|
||||
mTopBar.setVisibility(View.VISIBLE);
|
||||
mEditTopBar.setVisibility(View.GONE);
|
||||
actionMode = null;
|
||||
mChatRoomsAdapter.setEditionMode(actionMode);
|
||||
}
|
||||
}
|
||||
|
||||
//ActionMode ending
|
||||
|
||||
//Existing functions before RecyclerView conversion
|
||||
|
||||
|
@ -408,6 +272,34 @@ public class ChatListFragment extends Fragment implements ContactsUpdatedListene
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleteSelection(Object[] objectsToDelete) {
|
||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
mChatRoomDeletionPendingCount = objectsToDelete.length;
|
||||
for (Object obj : objectsToDelete) {
|
||||
ChatRoom room = (ChatRoom)obj;
|
||||
|
||||
for (EventLog eventLog : room.getHistoryEvents(0)) {
|
||||
if (eventLog.getType() == EventLog.Type.ConferenceChatMessage) {
|
||||
ChatMessage message = eventLog.getChatMessage();
|
||||
if (message.getAppdata() != null && !message.isOutgoing()) {
|
||||
File file = new File(message.getAppdata());
|
||||
if (file.exists()) {
|
||||
file.delete(); // Delete downloaded file from incoming message that will be deleted
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
room.addListener(mChatRoomListener);
|
||||
lc.deleteChatRoom(room);
|
||||
}
|
||||
if (mChatRoomDeletionPendingCount > 0) {
|
||||
mWaitLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onContactsUpdated() {
|
||||
if (!LinphoneActivity.isInstanciated() || LinphoneActivity.instance().getCurrentFragment() != CHAT_LIST)
|
||||
|
|
|
@ -21,15 +21,12 @@ package org.linphone.chat;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.ActionMode;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.linphone.LinphoneManager;
|
||||
|
@ -40,11 +37,11 @@ import org.linphone.contacts.ContactsManager;
|
|||
import org.linphone.contacts.LinphoneContact;
|
||||
import org.linphone.core.ChatMessage;
|
||||
import org.linphone.core.ChatRoom;
|
||||
import org.linphone.core.ChatRoomListener;
|
||||
import org.linphone.core.ChatRoomListenerStub;
|
||||
import org.linphone.core.Core;
|
||||
import org.linphone.core.EventLog;
|
||||
import org.linphone.ui.SelectableAdapter;
|
||||
import org.linphone.ui.SelectableHelper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
@ -96,14 +93,14 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
}
|
||||
|
||||
//Handle the onClick/onLongClick event for the ViewHolder
|
||||
@Override
|
||||
// @Override
|
||||
public void onClick(View v) {
|
||||
if (listener != null) {
|
||||
listener.onItemClicked(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
// @Override
|
||||
public boolean onLongClick(View v) {
|
||||
if (listener != null) {
|
||||
return listener.onItemLongClicked(getAdapterPosition());
|
||||
|
@ -170,12 +167,10 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
private ChatRoomListenerStub mListener;
|
||||
private int itemResource;
|
||||
private ChatRoomViewHolder.ClickListener clickListener;
|
||||
private boolean editionMode;
|
||||
|
||||
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms, ChatRoomViewHolder.ClickListener clickListener) {
|
||||
public ChatRoomsAdapter(Context context, int itemResource, List<ChatRoom> mRooms, ChatRoomViewHolder.ClickListener clickListener, SelectableHelper helper) {
|
||||
|
||||
super();
|
||||
this.editionMode = false;
|
||||
super(helper);
|
||||
this.clickListener = clickListener;
|
||||
this.mRooms = mRooms;
|
||||
this.mContext = context;
|
||||
|
@ -204,25 +199,25 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
//Bind datas to the ViewHolder
|
||||
ChatRoom room = this.mRooms.get(position);
|
||||
//Shows checkboxes when ActionMode enabled
|
||||
holder.delete.setVisibility(this.editionMode == true ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.unreadMessages.setVisibility(this.editionMode == false ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.delete.setVisibility(this.isEditionEnabled() == true ? View.VISIBLE : View.INVISIBLE);
|
||||
holder.unreadMessages.setVisibility(this.isEditionEnabled() == false ? View.VISIBLE : View.INVISIBLE);
|
||||
//Set checkbox checked if item selected
|
||||
holder.delete.setChecked(isSelected(position) ? true : false);
|
||||
//Bind the chatroom object to the holder
|
||||
holder.bindChatRoom(room);
|
||||
}
|
||||
|
||||
//Let know the adapter if ActionMode is enabled
|
||||
public void setEditionMode(ActionMode actionMode) {
|
||||
if ( actionMode != null) {
|
||||
this.editionMode=true;
|
||||
this.notifyDataSetChanged(); //Needed to update the whole list checkboxes
|
||||
} else {
|
||||
this.editionMode=false;
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
}
|
||||
// Let know the adapter if ActionMode is enabled
|
||||
// public void setEditionMode(ActionMode actionMode) {
|
||||
// if ( isEditionEnabled() == true) {
|
||||
// this.editionMode=true;
|
||||
// this.notifyDataSetChanged(); //Needed to update the whole list checkboxes
|
||||
// } else {
|
||||
// this.editionMode=false;
|
||||
// this.notifyDataSetChanged();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
public void refresh() {
|
||||
mRooms = new ArrayList<>(Arrays.asList(LinphoneManager.getLc().getChatRooms()));
|
||||
|
@ -242,6 +237,7 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
room.removeListener(mListener);
|
||||
}
|
||||
mRooms.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
|
@ -253,52 +249,52 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
mRooms.remove(position);
|
||||
notifyItemRemoved(position);
|
||||
}
|
||||
|
||||
public void removeItems(List<Integer> positions) {
|
||||
// Reverse-sort the list
|
||||
Collections.sort(positions, new Comparator<Integer>() {
|
||||
@Override
|
||||
public int compare(Integer lhs, Integer rhs) {
|
||||
return rhs - lhs;
|
||||
}
|
||||
});
|
||||
|
||||
// Split the list in ranges
|
||||
while (!positions.isEmpty()) {
|
||||
if (positions.size() == 1) {
|
||||
removeItem(positions.get(0));
|
||||
positions.remove(0);
|
||||
|
||||
} else {
|
||||
int count = 1;
|
||||
while (positions.size() > count && positions.get(count).equals(positions.get(count - 1) - 1)) {
|
||||
++count;
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
removeItem(positions.get(0));
|
||||
} else {
|
||||
removeRange(positions.get(count - 1), count);
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
positions.remove(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void removeRange(int positionStart, int itemCount) {
|
||||
for (int i = 0; i < itemCount; ++i) {
|
||||
Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
cleanRoom(positionStart);
|
||||
lc.deleteChatRoom(mRooms.get(positionStart));
|
||||
mRooms.remove(positionStart);
|
||||
}
|
||||
notifyItemRangeRemoved(positionStart, itemCount);
|
||||
}
|
||||
|
||||
//Delete downloaded file from incoming message that will be deleted
|
||||
//
|
||||
// public void removeItems(List<Integer> positions) {
|
||||
// // Reverse-sort the list
|
||||
// Collections.sort(positions, new Comparator<Integer>() {
|
||||
// @Override
|
||||
// public int compare(Integer lhs, Integer rhs) {
|
||||
// return rhs - lhs;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // Split the list in ranges
|
||||
// while (!positions.isEmpty()) {
|
||||
// if (positions.size() == 1) {
|
||||
// removeItem(positions.get(0));
|
||||
// positions.remove(0);
|
||||
//
|
||||
// } else {
|
||||
// int count = 1;
|
||||
// while (positions.size() > count && positions.get(count).equals(positions.get(count - 1) - 1)) {
|
||||
// ++count;
|
||||
// }
|
||||
//
|
||||
// if (count == 1) {
|
||||
// removeItem(positions.get(0));
|
||||
// } else {
|
||||
// removeRange(positions.get(count - 1), count);
|
||||
// }
|
||||
//
|
||||
// for (int i = 0; i < count; ++i) {
|
||||
// positions.remove(0);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void removeRange(int positionStart, int itemCount) {
|
||||
// for (int i = 0; i < itemCount; ++i) {
|
||||
// Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
// cleanRoom(positionStart);
|
||||
// lc.deleteChatRoom(mRooms.get(positionStart));
|
||||
// mRooms.remove(positionStart);
|
||||
// }
|
||||
// notifyItemRangeRemoved(positionStart, itemCount);
|
||||
// }
|
||||
//
|
||||
// //Delete downloaded file from incoming message that will be deleted
|
||||
private void cleanRoom (int position) {
|
||||
|
||||
for (EventLog eventLog : mRooms.get(position).getHistoryEvents(0)) {
|
||||
|
@ -326,6 +322,7 @@ public class ChatRoomsAdapter extends SelectableAdapter<ChatRoomsAdapter.ChatRoo
|
|||
return this.mRooms.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItem(int position) {
|
||||
return mRooms.get(position);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.linphone.ui;
|
|||
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -9,13 +10,36 @@ import java.util.List;
|
|||
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = SelectableAdapter.class.getSimpleName();
|
||||
private SparseBooleanArray mSelectedItems;
|
||||
private boolean mIsEditionEnabled=false;
|
||||
private SelectableHelper mListHelper;
|
||||
|
||||
private SparseBooleanArray selectedItems;
|
||||
public SelectableAdapter(SelectableHelper helper) {
|
||||
mSelectedItems = new SparseBooleanArray();
|
||||
mListHelper = helper;
|
||||
|
||||
public SelectableAdapter() {
|
||||
selectedItems = new SparseBooleanArray();
|
||||
}
|
||||
private CompoundButton.OnCheckedChangeListener mDeleteCheckboxListener = new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
Integer position = (Integer)compoundButton.getTag();
|
||||
|
||||
mListHelper.updateSelectionButtons(mSelectedItems.size() == 0, mSelectedItems.size() == getItemCount());
|
||||
}
|
||||
};
|
||||
public CompoundButton.OnCheckedChangeListener getDeleteListener() {
|
||||
return mDeleteCheckboxListener;
|
||||
}
|
||||
public boolean isEditionEnabled() {
|
||||
return mIsEditionEnabled;
|
||||
}
|
||||
|
||||
public void enableEdition(boolean set) {
|
||||
mIsEditionEnabled = set;
|
||||
|
||||
mSelectedItems.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
/**
|
||||
* Indicates if the item at position position is selected
|
||||
* @param position Position of the item to check
|
||||
|
@ -30,31 +54,33 @@ public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> exte
|
|||
* @param position Position of the item to toggle the selection status for
|
||||
*/
|
||||
public void toggleSelection(int position) {
|
||||
if (selectedItems.get(position, false)) {
|
||||
selectedItems.delete(position);
|
||||
if (mSelectedItems.get(position, false)) {
|
||||
mSelectedItems.delete(position);
|
||||
} else {
|
||||
selectedItems.put(position, true);
|
||||
mSelectedItems.put(position, true);
|
||||
}
|
||||
mListHelper.updateSelectionButtons(getSelectedItemCount() == 0, getSelectedItemCount() == getItemCount());
|
||||
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the selection status for all items
|
||||
*/
|
||||
public void clearSelection() {
|
||||
List<Integer> selection = getSelectedItems();
|
||||
selectedItems.clear();
|
||||
for (Integer i : selection) {
|
||||
notifyItemChanged(i);
|
||||
}
|
||||
}
|
||||
// public void clearSelection() {
|
||||
// List<Integer> selection = getSelectedItems();
|
||||
// mSelectedItems.clear();
|
||||
// for (Integer i : selection) {
|
||||
// notifyItemChanged(i);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Count the selected items
|
||||
* @return Selected items count
|
||||
*/
|
||||
public int getSelectedItemCount() {
|
||||
return selectedItems.size();
|
||||
return mSelectedItems.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -62,10 +88,28 @@ public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder> exte
|
|||
* @return List of selected items ids
|
||||
*/
|
||||
public List<Integer> getSelectedItems() {
|
||||
List<Integer> items = new ArrayList<>(selectedItems.size());
|
||||
for (int i = 0; i < selectedItems.size(); ++i) {
|
||||
items.add(selectedItems.keyAt(i));
|
||||
List<Integer> items = new ArrayList<>(mSelectedItems.size());
|
||||
for (int i = 0; i < mSelectedItems.size(); ++i) {
|
||||
items.add(mSelectedItems.keyAt(i));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
for (Integer i = 0; i < getItemCount(); i++) {
|
||||
mSelectedItems.put(i, true);
|
||||
notifyItemChanged(i);
|
||||
}
|
||||
mListHelper.updateSelectionButtons(false, true);
|
||||
// notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void deselectAll() {
|
||||
mSelectedItems.clear();
|
||||
mListHelper.updateSelectionButtons(true, false);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
|
||||
public abstract Object getItem(int position);
|
||||
}
|
||||
|
|
174
src/android/org/linphone/ui/SelectableHelper.java
Normal file
174
src/android/org/linphone/ui/SelectableHelper.java
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
SelectableHelper.java
|
||||
Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.linphone.ui;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import org.linphone.R;
|
||||
import org.linphone.activities.LinphoneActivity;
|
||||
|
||||
|
||||
public class SelectableHelper {
|
||||
private ImageView mEditButton, mSelectAllButton, mDeselectAllButton, mDeleteSelectionButton, mCancelButton;
|
||||
private LinearLayout mEditTopBar, mTopBar;
|
||||
private SelectableAdapter<RecyclerView.ViewHolder> mAdapter;
|
||||
private DeleteListener mDeleteListener;
|
||||
private Context mContext;
|
||||
private int mDialogDeleteMessageResourceId;
|
||||
|
||||
public void setDialogMessage(int id) {
|
||||
mDialogDeleteMessageResourceId = id;
|
||||
}
|
||||
|
||||
public interface DeleteListener {
|
||||
void onDeleteSelection(Object[] objectsToDelete);
|
||||
}
|
||||
|
||||
public SelectableHelper(View view, DeleteListener listener) {
|
||||
mContext = view.getContext();
|
||||
mDeleteListener = listener;
|
||||
|
||||
mEditTopBar = view.findViewById(R.id.edit_list);
|
||||
mTopBar = view.findViewById(R.id.top_bar);
|
||||
|
||||
mCancelButton = view.findViewById(R.id.cancel);
|
||||
mCancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
|
||||
mEditButton = view.findViewById(R.id.edit);
|
||||
mEditButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mAdapter.getItemCount() > 0) {
|
||||
mAdapter.enableEdition(true);
|
||||
mTopBar.setVisibility(View.GONE);
|
||||
mEditTopBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
mSelectAllButton = view.findViewById(R.id.select_all);
|
||||
mSelectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mAdapter.selectAll();
|
||||
}
|
||||
});
|
||||
|
||||
mDeselectAllButton = view.findViewById(R.id.deselect_all);
|
||||
mDeselectAllButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mAdapter.deselectAll();
|
||||
}
|
||||
});
|
||||
|
||||
mDeleteSelectionButton = view.findViewById(R.id.delete);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
mDeleteSelectionButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final Dialog dialog = LinphoneActivity.instance().displayDialog(mContext.getString(mDialogDeleteMessageResourceId));
|
||||
Button delete = dialog.findViewById(R.id.delete_button);
|
||||
Button cancel = dialog.findViewById(R.id.cancel);
|
||||
|
||||
delete.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
mDeleteListener.onDeleteSelection(getSelectedObjects());
|
||||
dialog.dismiss();
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
dialog.dismiss();
|
||||
quitEditionMode();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
mDialogDeleteMessageResourceId = R.string.delete_text;
|
||||
}
|
||||
|
||||
public void setAdapter(SelectableAdapter adapter) {
|
||||
mAdapter=adapter;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void updateSelectionButtons(boolean isSelectionEmpty, boolean isSelectionFull) {
|
||||
if (isSelectionEmpty) {
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
} else {
|
||||
mDeleteSelectionButton.setEnabled(true);
|
||||
}
|
||||
|
||||
if (isSelectionFull) {
|
||||
mSelectAllButton.setVisibility(View.GONE);
|
||||
mDeselectAllButton.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mSelectAllButton.setVisibility(View.VISIBLE);
|
||||
mDeselectAllButton.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void quitEditionMode() {
|
||||
mAdapter.enableEdition(false);
|
||||
mTopBar.setVisibility(View.VISIBLE);
|
||||
mEditTopBar.setVisibility(View.GONE);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
mSelectAllButton.setVisibility(View.VISIBLE);
|
||||
mDeselectAllButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void enterEditionMode() {
|
||||
mAdapter.enableEdition(true);
|
||||
mTopBar.setVisibility(View.GONE);
|
||||
mEditTopBar.setVisibility(View.VISIBLE);
|
||||
mDeleteSelectionButton.setEnabled(false);
|
||||
mSelectAllButton.setVisibility(View.GONE);
|
||||
mDeselectAllButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private Object[] getSelectedObjects() {
|
||||
Object objects[] = new Object[mAdapter.getSelectedItemCount()];
|
||||
int index = 0;
|
||||
for (Integer i : mAdapter.getSelectedItems()) {
|
||||
objects[index] = mAdapter.getItem(i);
|
||||
index++;
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@ import static android.support.v7.widget.helper.ItemTouchHelper.LEFT;
|
|||
|
||||
enum ButtonsState {
|
||||
GONE,
|
||||
LEFT_VISIBLE,
|
||||
// LEFT_VISIBLE,
|
||||
RIGHT_VISIBLE
|
||||
}
|
||||
/*
|
||||
|
@ -70,7 +70,7 @@ public class SwipeController extends Callback {
|
|||
|
||||
if (actionState == ACTION_STATE_SWIPE) {
|
||||
if (buttonShowedState != ButtonsState.GONE) {
|
||||
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX, buttonWidth);
|
||||
// if (buttonShowedState == ButtonsState.LEFT_VISIBLE) dX = Math.max(dX, buttonWidth);
|
||||
if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) dX = Math.min(dX, -buttonWidth);
|
||||
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||
}else {
|
||||
|
@ -91,10 +91,10 @@ public class SwipeController extends Callback {
|
|||
View itemView = viewHolder.itemView;
|
||||
Paint p = new Paint();
|
||||
|
||||
RectF leftButton = new RectF(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + buttonWidthWithoutPadding, itemView.getBottom());
|
||||
p.setColor(Color.BLUE);
|
||||
c.drawRoundRect(leftButton, corners, corners, p);
|
||||
drawText("EDIT", c, leftButton, p);
|
||||
// RectF leftButton = new RectF(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + buttonWidthWithoutPadding, itemView.getBottom());
|
||||
// p.setColor(Color.BLUE);
|
||||
// c.drawRoundRect(leftButton, corners, corners, p);
|
||||
// drawText("EDIT", c, leftButton, p);
|
||||
|
||||
RectF rightButton = new RectF(itemView.getRight() - buttonWidthWithoutPadding, itemView.getTop(), itemView.getRight(), itemView.getBottom());
|
||||
p.setColor(Color.RED);
|
||||
|
@ -102,10 +102,10 @@ public class SwipeController extends Callback {
|
|||
drawText("DELETE", c, rightButton, p);
|
||||
|
||||
buttonInstance = null;
|
||||
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
|
||||
/* if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
|
||||
buttonInstance = leftButton;
|
||||
}
|
||||
else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
|
||||
else */if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
|
||||
buttonInstance = rightButton;
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ public class SwipeController extends Callback {
|
|||
swipeBack = event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP;
|
||||
if (swipeBack) {
|
||||
if (dX < -buttonWidth) buttonShowedState = ButtonsState.RIGHT_VISIBLE;
|
||||
else if (dX > buttonWidth) buttonShowedState = ButtonsState.LEFT_VISIBLE;
|
||||
// else if (dX > buttonWidth) buttonShowedState = ButtonsState.LEFT_VISIBLE;
|
||||
|
||||
if (buttonShowedState != ButtonsState.GONE) {
|
||||
setTouchDownListener(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
|
||||
|
@ -184,10 +184,10 @@ public class SwipeController extends Callback {
|
|||
setItemsClickable(recyclerView, true);
|
||||
swipeBack = false;
|
||||
if (buttonsActions != null && buttonInstance != null && buttonInstance.contains(event.getX(), event.getY())) {
|
||||
if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
|
||||
/*if (buttonShowedState == ButtonsState.LEFT_VISIBLE) {
|
||||
buttonsActions.onLeftClicked(viewHolder.getAdapterPosition());
|
||||
}
|
||||
else if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
|
||||
else */if (buttonShowedState == ButtonsState.RIGHT_VISIBLE) {
|
||||
buttonsActions.onRightClicked(viewHolder.getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package org.linphone.ui;
|
||||
|
||||
public abstract class SwipeControllerActions {
|
||||
public void onLeftClicked(int position) {}
|
||||
// public void onLeftClicked(int position) {}
|
||||
|
||||
public void onRightClicked(int position) {}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue