I'm following this tutorial to implement multi select in my RecyclerView but I have been getting the following runtime exception when I perform a long click:
java.lang.ClassCastException: com.abdralabs.talksee.MyApplication cannot be cast to android.support.v7.app.AppCompatActivity
at com.abdralabs.talksee.IMListAdapter$IMListViewHolder.onLongClick(IMListAdapter.java:116)
at android.view.View.performLongClick(View.java:5308)
at android.view.View$CheckForLongPress.run(View.java:21522)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5740)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:766)
Activity code:
public class IMListActivity extends AppCompatActivity implements Sertivity{
private RecyclerView recyclerView;
private IMListAdapter imListAdapter;
private List<Chat> chatList = new ArrayList<>();
List<String> stringList;
ActiveChatsDB activeChatsDB;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imlist);
Toolbar toolbar = (Toolbar)findViewById(R.id.imlist_toolbar);
setSupportActionBar(toolbar);
setBackButtonOnToolbar();
recyclerView = (RecyclerView)findViewById(R.id.rv_im_list);
imListAdapter = new IMListAdapter(chatList, getApplicationContext());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setAdapter(imListAdapter);
prepareChatListData();
}
private void prepareChatListData() {
String friend;
String latestMessage;
activeChatsDB = new ActiveChatsDB(IMListActivity.this);
stringList = activeChatsDB.getChatList();
activeChatsDB.close();
for (int i=0; i<stringList.size(); i++) {
friend = stringList.get(i);
DBAct dbAct = new DBAct(IMListActivity.this,friend);
latestMessage = dbAct.getLatestMessage();
dbAct.close();
Chat chat = new Chat(friend, latestMessage);
chatList.add(chat);
}
imListAdapter.notifyDataSetChanged();
}
private void setBackButtonOnToolbar(){
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
public RecyclerView getRecyclerView() {
return recyclerView;
}
}
Adapter code:
public class IMListAdapter extends RecyclerView.Adapter <com.abdralabs.talksee.IMListAdapter.IMListViewHolder> {
private List<Chat> chatList = new ArrayList<Chat>() ;
private Context ctx;
private MultiSelector multiSelector = new MultiSelector();
private ModalMultiSelectorCallback modalMultiSelectorCallback =
new ModalMultiSelectorCallback(multiSelector) {
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.item_delete) {
mode.finish();
for (int i = chatList.size(); i >= 0; i--) {
if (multiSelector.isSelected(i, 0)) { // (1)
// remove item from list
((IMListActivity)ctx).getRecyclerView().getAdapter().notifyItemRemoved(i);
}
}
multiSelector.clearSelections(); // (2)
return true;
}
return false;
}
@Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
super.onCreateActionMode(actionMode, menu);
((AppCompatActivity)ctx).getMenuInflater().inflate(R.menu.contextual_menu_friends, menu);
return true;
}
};
public IMListAdapter(List<Chat> chatList, Context ctx){
this.chatList = chatList;
this.ctx = ctx;
}
@Override
public com.abdralabs.talksee.IMListAdapter.IMListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.chat_list_row,parent,false);
return new com.abdralabs.talksee.IMListAdapter.IMListViewHolder(itemView, chatList, ctx); }
@Override
public void onBindViewHolder(com.abdralabs.talksee.IMListAdapter.IMListViewHolder holder, int position) {
Chat chat = chatList.get(position);
holder.name.setText(chat.getName());
holder.recentMsg.setText(chat.getRecentMessage());
}
@Override
public int getItemCount() {
return chatList.size();
}
public class IMListViewHolder extends SwappingHolder implements View.OnClickListener, View.OnLongClickListener{
public TextView name;
public TextView recentMsg;
List<Chat> chatList = new ArrayList<Chat>();
Context ctx;
public IMListViewHolder(View itemView, List<Chat> chatList, Context ctx) {
super(itemView, multiSelector);
this.chatList = chatList;
this.ctx = ctx;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
itemView.setLongClickable(true);
name = (TextView) itemView.findViewById(R.id.name_chat);
recentMsg = (TextView)itemView.findViewById(R.id.tv_recent_msg_im_list);
}
@Override
public void onClick(View v) {
int position = getAdapterPosition();
Chat chat = this.chatList.get(position);
Intent intent = new Intent(this.ctx, IMActivity.class);
intent.putExtra("otherUserName",chat.getName());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.ctx.startActivity(intent);
}
@Override
public boolean onLongClick(View v) {
if (!multiSelector.isSelectable()) { // (3)
((AppCompatActivity)ctx).startSupportActionMode(modalMultiSelectorCallback);
multiSelector.setSelectable(true); // (4)
multiSelector.setSelected(com.abdralabs.talksee.IMListAdapter.IMListViewHolder.this, true); // (5)
return true;
}
return false;
}
}
}
I don't know how I'm supposed to peform the right type casting. Please help.
EDIT 1:
I tried replacing the onLongClick code to
public boolean onLongClick(View v) {
if (!multiSelector.isSelectable()) { // (3)
((IMListActivity)ctx).startSupportActionMode(modalMultiSelectorCallback);
multiSelector.setSelectable(true); // (4)
multiSelector.setSelected(IMListViewHolder.this, true); // (5)
return true;
}
return false;
}
as Sachin Bahukhandi suggested, but I'm getting the same error
java.lang.ClassCastException: com.abdralabs.talksee.MyApplication cannot be cast to com.abdralabs.talksee.IMListActivity
at com.abdralabs.talksee.IMListAdapter$IMListViewHolder.onLongClick(IMListAdapter.java:116)
at android.view.View.performLongClick(View.java:5308)
at android.view.View$CheckForLongPress.run(View.java:21522)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5740)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:766)
In the tutorial that I'm following the code is as such:
@Override
public boolean onLongClick(View view) {
if (!mMultiSelector.isSelectable()) {
((AppCompatActivity) getActivity()).startSupportActionMode(mActionModeCallback); // (2)
mMultiSelector.setSelectable(true);
mMultiSelector.setSelected(MyViewHolder.this, true);
return true;
}
return false;
}
In the above code getActivity is called somehow from the Viewholder and type casted to AppCompatActivity. I don't know how to call getActivity directly from the ViewHolder since I'm getting and error so I tried to type cast a context object (which was passed from my Activity through the adapter constructor) to AppCompatActivity. So I don't exactly know what I'm doing wrong here.
So I solved this by passing the activity reference to the constructor of the adapter and calling
imListActivity.startSupportActionMode(modalMultiSelectorCallback);
instead of doing this
((IMListActivity)ctx).startSupportActionMode(modalMultiSelectorCallback);