I have a problem with the contextual menu, I have to control "MenuButton" without using of "Contextual Action bar menu (CAB)" when you make a long click and short click displays a context menu.I need to display the contextual menu with using of "Contextual Action bar menu (CAB)".when you make short click on "MenuButton" CAB menu also called on a short click, not a long click. I need to display the contextual menu with a short click. is this possible?
MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_internal);
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("");
title = (TextView) findViewById(R.id.txt_name_file);
past = (ImageView) findViewById(R.id.img_paste);
home = (ImageView) findViewById(R.id.img_home);
menu_item = (ImageView) findViewById(R.id.img_more);
list_in = (ListView) findViewById(R.id.list_in);
past.setVisibility(View.INVISIBLE);
fileManager = new FileManager();
arrayList = new ArrayList<>();
adapter = new InternalAdapter(getApplicationContext(), arrayList);
list_in.setAdapter(adapter);
list_in.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int i, long id) {
if (selectCount > 0) {
if (actionMode == null) {
actionMode = InternalActivity.this.startActionMode(callback);
Toast.makeText(getApplicationContext(), "S>0", Toast.LENGTH_SHORT).show();
}
toggleselection(i);
actionMode.setTitle(selectCount + " " + "Selected");
if (selectCount == 0) {
actionMode.finish();
}
} else if (selectCount == 0) {
Toast.makeText(getApplicationContext(), "2", Toast.LENGTH_SHORT).show();
String S = arrayList.get(i).getPathFile();
File file = new File(S);
if (arrayList.get(i).isFile() == false) {
pathItem = arrayList.get(i).getPathFile();
title.setText(pathItem.substring(pathItem.lastIndexOf("/") + 1));
readFile(pathItem);
} else if (file.canRead()) {
Intent intent = FileManager.createIntent(file);
if (getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "Error", Toast.LENGTH_SHORT).show();
}
}
}
}
});
list_in.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
if (actionMode == null) {
actionMode = InternalActivity.this.startActionMode(callback);
Toast.makeText(getApplicationContext(), "L", Toast.LENGTH_SHORT).show();
}
toggleselection(position);
actionMode.setTitle(selectCount + " " + "Selected");
if (selectCount == 0) {
actionMode.finish();
}
return true;
}
});
readFile(FileManager.PATH);
loadFileItem();
}
ArrayList<FileItem> selectedFile = new ArrayList<>();
private void toggleselection(int position) {
arrayList.get(position).isSelected = !arrayList.get(position).isSelected;
if (arrayList.get(position).isSelected) {
selectedFile.add(arrayList.get(position));
selectCount++;
} else {
selectedFile.add(arrayList.get(position));
selectCount--;
}
adapter.notifyDataSetChanged();
}
private ActionMode.Callback callback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater menuInflater = mode.getMenuInflater();
menuInflater.inflate(R.menu.internal_context_menu, menu);
MenuItem mi = menu.getItem(0);
mi.setTitle(mi.getTitle().toString());
actionMode = mode;
selectCount = 0;
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.i_de:
mode.finish();
break;
}
return true;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
if (selectCount > 0) {
deSelect();
}
actionMode = null;
}
};
private void deSelect() {
for (int i = 0; i < arrayList.size(); i++) {
arrayList.get(i).isSelected = false;
}
selectCount = 0;
adapter.notifyDataSetChanged();
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater menuInflater = getMenuInflater();
menuInflater.inflate(R.menu.select_file, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.copy:
copyFolder(pos);
break;
case R.id.delete:
deleteFolder(pos);
break;
case R.id.rename:
renameFile(pos);
break;
}
return super.onContextItemSelected(item);
}
public class InternalAdapter extends BaseAdapter {
ArrayList<FileItem> arrayList;
Context context;
ViewHolder viewHolder;
public InternalAdapter(Context context, ArrayList<FileItem> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public FileItem getItem(int position) {
return arrayList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
viewHolder = new ViewHolder();
view = LayoutInflater.from(context).inflate(R.layout.activity_internal_adapter, parent, false);
viewHolder.imgFolder = (ImageView) view.findViewById(R.id.img_folder);
viewHolder.txtNameFile = (TextView) view.findViewById(R.id.txt_name_folder);
viewHolder.txtDate = (TextView) view.findViewById(R.id.txt_date);
viewHolder.imgCreate = (ImageView) view.findViewById(R.id.img_create);
viewHolder.view = view.findViewById(R.id.view_internal);
viewHolder.linearLayout = (LinearLayout) view.findViewById(R.id.lv_image);
FileItem fileItem = getItem(position);
if (fileItem.isSelected) {
viewHolder.view.setAlpha(0.5f);
} else {
viewHolder.view.setAlpha(0.0f);
}
if (fileItem.isDirectory()) {
viewHolder.imgFolder.setImageResource(R.drawable.ic_folder_black_24dp);
} else if (fileItem.isFile()) {
viewHolder.imgFolder.setImageResource(R.drawable.ic_insert_drive_file_black_24dp);
}
viewHolder.txtNameFile.setText(fileItem.getName());
viewHolder.txtDate.setText(fileItem.getDate());
viewHolder.imgCreate.setLongClickable(false);
registerForContextMenu(viewHolder.imgCreate);
viewHolder.imgCreate.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
unregisterForContextMenu(v);
Toast.makeText(getApplicationContext(), "111", Toast.LENGTH_SHORT).show();
return false;
}
});
viewHolder.imgCreate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pos = position;
openContextMenu(v);
Toast.makeText(getApplicationContext(), "1", Toast.LENGTH_SHORT).show();
}
});
return view;
}
private class ViewHolder {
ImageView imgFolder;
TextView txtNameFile;
TextView txtDate;
ImageView imgCreate;
View view;
LinearLayout linearLayout;
}
}
}
Related
When I am typing text in searchView for search items, my app getting crashed. I have a fragment and adapter. What I do next? Someone help me.
This is the error I got-
Attempt to invoke virtual method 'void pdfreader.pdfconverter.pdfreaderapp.pdfAdapter.updatePdfFile(java.util.ArrayList)' on a null object reference
here is fragment code
public class Pdf_Reader_fragments extends Fragment implements SearchView.OnQueryTextListener {
public static ArrayList<File> pdffiles = new ArrayList<>();
RecyclerView recyclerView;
File folder;
String[] items;
static pdfAdapter adapter;
int number = 0;
private SwipeRefreshLayout mSwipeRefreshLayout;
public Pdf_Reader_fragments() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_pdf__reader, container, false);
recyclerView = (RecyclerView) view.findViewById(R.id.recylerView);
mSwipeRefreshLayout = view.findViewById(R.id.swip);
setHasOptionsMenu(true);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
try {
intiViews();
} catch (Exception e) {
}
Toast.makeText(getContext(), "Page Refresh", Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(false);
}
});
intiViews();
return view;
}
private void intiViews() {
folder = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
pdffiles = getPdfFiles(folder);
ArrayList<File> mypdf = getPdfFiles(Environment.getExternalStorageDirectory());
items = new String[mypdf.size()];
for (int i = 0; i < items.length; i++) {
items[i] = mypdf.get(i).getName().replace(".pdf", "");
}
pdfAdapter adapter = new pdfAdapter(getContext(), pdffiles, items);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity(), RecyclerView.VERTICAL, false));
}
private ArrayList<File> getPdfFiles(File folder) {
ArrayList<File> arrayList = new ArrayList<>();
File[] file = folder.listFiles();
if (file != null) {
for (File singleFile : file) {
if (singleFile.isDirectory() && !singleFile.isHidden()) {
arrayList.addAll(getPdfFiles(singleFile));
} else {
if (singleFile.getName().endsWith(".pdf")) {
arrayList.add(singleFile);
}
}
}
}
return arrayList;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search, menu);
MenuItem item = menu.findItem(R.id.search_button);
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW | MenuItem.SHOW_AS_ACTION_IF_ROOM);
SearchView searchView = (SearchView) item.getActionView();
searchView.setOnQueryTextListener(this);
}
#Override
public boolean onQueryTextSubmit(String query) {
if (adapter != null) {
query = String.valueOf(query.equals(""));
}
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
String userInput = newText.toLowerCase();
ArrayList<File> myfile = new ArrayList<>();
for (File pdf : pdffiles){
if (pdf.getName().toLowerCase().contains(userInput)){
myfile.add(pdf);
}
adapter.updatePdfFile(myfile);
}
return true;
}
}
pdfAdapter class
public class pdfAdapter extends RecyclerView.Adapter<pdfAdapter.MyViewHolder> {
private Context mContext;
private ArrayList<File> files;
String [] items;
public pdfAdapter(Context mContext, ArrayList<File> files, String[] items) {
this.mContext = mContext;
this.files = files;
this.items = items;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.pdf_items, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, final int position) {
holder.file_name.setText(items[position]);
holder.popUpMenu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
PopupMenu popupMenu = new PopupMenu(mContext, v);
popupMenu.getMenuInflater().inflate(R.menu.menu, popupMenu.getMenu());
popupMenu.show();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
// case R.id.edit:
// Toast.makeText(mContext, "Edit", Toast.LENGTH_SHORT).show();
// break;
case R.id.delete:
// Toast.makeText(mContext, "Delete", Toast.LENGTH_SHORT).show();
deleteFile(position, v);
}
return true;
}
public void deleteFile (final int position, View v) {
String uri = files.get(position).getAbsolutePath();
final File file = new File (uri);
boolean deleted = file.delete();
if (deleted) {
files.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, files.size());
Toast.makeText(mContext, "Delete sucessfully", Toast.LENGTH_SHORT).show();
}
}
});
}
});
holder.pdf_Layouts.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext, PdfViewActivity.class);
intent.putExtra("position", position);
mContext.startActivity(intent);
}});
}
#Override
public int getItemCount() {
return files.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView file_name;
ImageView file_icon,popUpMenu;
RelativeLayout pdf_Layouts;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
file_name = itemView.findViewById(R.id.pdf_item_name);
file_icon = itemView.findViewById(R.id.img_pdf);
pdf_Layouts = itemView.findViewById(R.id.pdf_items_h);
popUpMenu = itemView.findViewById(R.id.more);
}
}
void updatePdfFile(ArrayList<File> fileArrayList){
//
files.clear();
files.addAll(fileArrayList);
notifyDataSetChanged();
}
}
You are not assigning adapter to your class variable static pdfAdapter adapter;
In private void intiViews() function change:
pdfAdapter adapter = new pdfAdapter(getContext(), pdffiles, items); to
adapter = new pdfAdapter(getContext(), pdffiles, items);
I am using contextual action bar in my fragment("UnitsFragment.java") to delete and edit items of recyclerview. But when I come back from recyclerview adapter class("UnitsRv.java"). The context seems to be null. I tried returning context from adapter and it worked for function "prepareSelection". However for "onActionItemClicked" under ActionMode.callback, I need to get context so that I can use alertdialog for editing the items.
The "requireContext()" throws this error: Fragment UnitsFragment{e3a36c8 (b4957397-055a-4b1c-8af2-fee89a3e9b35)} not attached to a context.
Here are my codes.
UnitsFragment.java
public class UnitsFragment extends Fragment {
private static final String TAG = "UnitsFragment";
private RecyclerView recyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager layoutManager;
ArrayList<UnitsList> unitsLists = new ArrayList<>();
Activity mcontext = getActivity();
Context dcontext;
ActionMode actionMode;
public static ArrayList<UnitsList> selectionList = new ArrayList<>();
public static boolean isInActionMode = false;
List<String> list = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao().findUnitNameList();
public UnitsFragment() {
}
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.menu_item_action, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_edit:
if (selectionList.size() == 1) {
final EditText editText = new EditText(requireContext());
new AlertDialog.Builder(requireContext())
.setTitle("Rename unit name").setView(editText)
.setPositiveButton("Rename", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
UnitsList unitsList = selectionList.get(0);
unitsList.setUnit_name(editText.getText().toString().trim());
isInActionMode = false;
((UnitsRv) mAdapter).changeDataItem(getCheckedLastPosition(), unitsList);
actionMode.finish();
selectionList.clear();
}
})
.create()
.show();
Toast.makeText(getContext(), "Edit", Toast.LENGTH_SHORT).show();
mode.finish();
return true;
}
case R.id.menu_item_delete:
isInActionMode = false;
((UnitsRv) mAdapter).removeData(selectionList);
Toast.makeText(getContext(), "Delete", Toast.LENGTH_SHORT).show();
actionMode.finish();
selectionList.clear();
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
actionMode = null;
}
};
private int getCheckedLastPosition() {
ArrayList<UnitsList> dataSet = UnitsRv.getDataSet();
for (int i = 0; i < dataSet.size(); i++) {
if (dataSet.get(i).equals(selectionList.get(0))) {
return i;
}
}
return 0;
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);
dcontext = rootView.getContext();
Log.d(TAG, "onCreateView1: " + dcontext);
recyclerView = rootView.findViewById(R.id.rv_units);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.HORIZONTAL));
recyclerView.addItemDecoration(new DividerItemDecoration(getContext(),
DividerItemDecoration.VERTICAL));
layoutManager = new GridLayoutManager(getContext(), 2);
recyclerView.setLayoutManager(layoutManager);
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
Log.d(TAG, "onCreateView: " + getContext());
mAdapter = new UnitsRv(mcontext,unitsLists);
recyclerView.setAdapter(mAdapter);
return rootView;
}
#Override
public void onCreateOptionsMenu(#NonNull Menu menu, #NonNull MenuInflater inflater) {
inflater.inflate(R.menu.add, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_item_new:
final View customLayout = getLayoutInflater().inflate(R.layout.add_unit_dialog, null);
final EditText edt_unit_name = customLayout.findViewById(R.id.edt_new_unit_name);
final AlertDialog dialog = new AlertDialog.Builder(getContext())
.setView(customLayout)
.setTitle("Unit name")
.setPositiveButton(android.R.string.ok, null) //Set to null. We override the onclick
.setNegativeButton(android.R.string.cancel, null)
.create();
dialog.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialogInterface) {
Button ok_btn = dialog.getButton(AlertDialog.BUTTON_POSITIVE);
Button cancel_btn = dialog.getButton(AlertDialog.BUTTON_NEGATIVE);
ok_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String unit_name = edt_unit_name.getText().toString().trim();
if (!TextUtils.isEmpty(unit_name)) {
String old_unit_name = DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.findByUnitName(unit_name);
if (old_unit_name == null) {
DatabaseClient.getInstance(getContext())
.getUserDatabase()
.getUnitDao()
.insertUnits(new UnitsList(unit_name));
unitsLists.add(new UnitsList(unit_name));
dialog.dismiss();
} else {
edt_unit_name.setError("Unit already exists");
}
} else {
edt_unit_name.setError("Can't be empty");
}
}
});
cancel_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog.dismiss();
}
});
}
});
dialog.show();
return true;
}
return super.onOptionsItemSelected(item);
}
public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists);
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);
mAdapter.notifyDataSetChanged();
if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}
private void updateViewCounter() {
int counter = selectionList.size();
if (counter == 1) {
actionMode.setTitle(counter + "item selected");
} else {
actionMode.setTitle(counter + "items selected");
}
}
}
This is my Adapter class.
UnitsRv.java
public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";
private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment();
Context mcontext;
public UnitsRv(Context context,ArrayList<UnitsList> unitsLists) {
mcontext = context;
munitsLists = unitsLists;
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;
public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
unitsFragment.prepareSelection(mcontext,getAdapterPosition());
notifyItemChanged(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
unitsFragment.prepareSelection(view.getContext(),getAdapterPosition());
return true;
}
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.units_item, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
holder.unit_name.setText(munitsLists.get(position).getUnit_name());
if (UnitsFragment.isInActionMode){
if (UnitsFragment.selectionList.contains(munitsLists.get(position))){
holder.itemView.setBackgroundResource(R.color.colorSelected);
}
}
}
#Override
public int getItemCount() {
return munitsLists.size();
}
public static ArrayList<UnitsList> getDataSet() {
return munitsLists;
}
public void changeDataItem(int position, UnitsList unitsList) {
munitsLists.set(position, unitsList);
notifyDataSetChanged();
}
public void removeData(ArrayList<UnitsList> list) {
for (UnitsList unitsList : list) {
munitsLists.remove(unitsList);
}
notifyDataSetChanged();
}
}
First, you should not create instance of your UnitsFragment inside your adapter.
You can use EventBus to communicate between Activities, Fragments, Adapters, etc.
Or You can do your task using interface. like below.
Create an interface like this
public interface AdapterCallback {
void prepareSelection(Context context,int position);
}
In your UnitsFragment implement the above interface. like the following
public class UnitsFragment extends Fragment implements AdapterCallback{
// your other codes
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_units, container, false);
setHasOptionsMenu(true);
// .... your other codes
Log.d(TAG, "onCreateView: " + getContext());
// modify below line like this
mAdapter = new UnitsRv(mcontext, unitsLists, this); // here you have to pass an extra parameter that will implement your callback method from adapter.
recyclerView.setAdapter(mAdapter);
return rootView;
}
// ... you other codes
#Override
public void prepareSelection(Context context,int position) {
if(actionMode == null) {
isInActionMode = true;
for (String string : list) {
unitsLists.add(new UnitsList(string));
}
mAdapter = new UnitsRv(context, unitsLists,this); // add this as parameter.
Log.d(TAG, "prepareSelection: " + mAdapter);
Log.d(TAG, "prepareSelection1: " + dcontext);
mcontext = (Activity)context;
actionMode = mcontext.startActionMode(actionModeCallback);
mAdapter.notifyDataSetChanged();
if (!selectionList.contains(unitsLists.get(position))) {
selectionList.add(unitsLists.get(position));
}
updateViewCounter();
}
}
// other codes
}
Now, inside your Adapter you need to add an extra argument in constructor of UnitsRv and call your interface method from adapter ussing mAdapterCallback.
public class UnitsRv extends RecyclerView.Adapter<UnitsRv.ViewHolder> {
private static final String TAG = "UnitsRv";
private static ArrayList<UnitsList> munitsLists = new ArrayList<>();
UnitsFragment unitsFragment = new UnitsFragment(); // remove this line
private AdapterCallback mAdapterCallback; // add this line
Context mcontext;
public UnitsRv(Context context,ArrayList<UnitsList> unitsLists, AdapterCallback callback) {
mcontext = context;
munitsLists = unitsLists;
this.mAdapterCallback = callback; // add this line
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView unit_name;
public ViewHolder(View v) {
super(v);
unit_name = v.findViewById(R.id.unit_name);
v.setOnLongClickListener(this);
}
#Override
public void onClick(View view) {
if (UnitsFragment.isInActionMode){
mAdapterCallback.prepareSelection(mcontext,getAdapterPosition()); // modify this line
notifyItemChanged(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View view) {
Log.d(TAG, "onLongClick: " + getAdapterPosition());
mAdapterCallback.prepareSelection(view.getContext(),getAdapterPosition()); // modify this line
return true;
}
}
// your other codes....
}
You should check for your fragment is attached or not with isAdded()
place if(!isAdded()) return in your onActionItemClicked. and replace requireContext() with getContext() because requireContext() always throws IllegalStateException if fragment is not attached.
override onAttach method to save context in your fragment.
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context= context;
}
Hope this helps.
I want filter the recycleView by searchView.
I add xml file to menu.
When the app run she stop when the fragment open.
When I put break point I found the problem in line: SearchView searchView = (SearchView) searchItem.getActionView() - in method onCreateOptionsMenu.
why this happening? (the addapter create in fragment)
In xml menu I changed to
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
#SuppressLint("ValidFragment")
public class AvailableDrivesFragment extends Fragment {
public RecyclerView drivesRecyclerView;
public LinearLayout details;
public List<Drive> drives = new ArrayList<>();
public TextView textDetails;
public Button buttonChoose;
IDataBase fb = FactoryDataBase.getDataBase();
private DrivesRecycleViewAdapter adapter;
private Menu menu;
Driver driver;
#SuppressLint("ValidFragment")
AvailableDrivesFragment(Driver e) {
this.driver = e;
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_available_drives, container, false);
textDetails = v.findViewById(R.id.text_details);
details = v.findViewById(R.id.linear_details);
details.setVisibility(View.GONE);
getActivity().setTitle("Available Drives");
drivesRecyclerView = v.findViewById(R.id.my_list);
drivesRecyclerView.setHasFixedSize(true);
drivesRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapter = new DrivesRecycleViewAdapter();
drives = fb.getAvailableDrives();
drivesRecyclerView.setAdapter(adapter);
setHasOptionsMenu(true);
return v;
}
#Override
public void onDestroy() {
Firebase_DBManager.stopNotifyToDriveList();
super.onDestroy();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.search, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();//here stop working
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
try {
adapter.getFilter().filter(newText);
}
catch (Exception r) {
r.printStackTrace();
}
return false;
}
});
}
public class DrivesRecycleViewAdapter extends RecyclerView.Adapter<DrivesRecycleViewAdapter.DriveViewHolder> implements Filterable
{
public List<Drive> drivefull;
public DrivesRecycleViewAdapter() {
this.drivefull = new ArrayList<>(drives);
;
}
#Override
public DriveViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(getActivity()).inflate(R.layout.item_drive, parent, false);
return new DriveViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull DriveViewHolder holder, int position) {
Drive drive = drives.get(position);
holder.nameTextView.setText(drive.getName());
holder.nameTextView.setTextSize(20);
holder.phoneTextView.setText(drive.getStartAddress());
holder.phoneTextView.setTextSize(16);
}
#Override
public int getItemCount() {
return drives.size();
}
#Override
public Filter getFilter() {
return filter;
}
public Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
List<Drive> filteredList = new ArrayList<>();//new list that contained only filtered items
if (constraint == null || constraint.length() == 0)//we what to show all the results becuse we don't what filtering
{
filteredList.addAll(drivefull);
} else { //we what to filter the list
String filterPattern = constraint.toString().toLowerCase().trim(); // sting that takes the input
for (Drive item : drivefull) {
if (item.getName().toLowerCase().contains((filterPattern))) {
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
drives.clear();
drives.addAll((List) results.values);
notifyDataSetChanged();
}
};
class DriveViewHolder extends RecyclerView.ViewHolder {
TextView phoneTextView;
TextView nameTextView;
public DriveViewHolder(final View itemView) {
super(itemView);
phoneTextView = itemView.findViewById(R.id.phone_item_drive);
nameTextView = itemView.findViewById(R.id.name_item_drive);
itemView.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
menu.setHeaderTitle("Select Action");
MenuItem detailm = menu.add(Menu.NONE, 1, 1, "view details");
detailm.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
Drive drive = drives.get(getAdapterPosition());
textDetails.setText(drive.toString());
details.setVisibility(View.VISIBLE);
return true;
}
});
MenuItem addDrive = menu.add(Menu.NONE, 1, 1, "take drive");
addDrive.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
final Drive drive = drives.get(getAdapterPosition());
fb.changeStatus(drive.getId(), driver, DriveStatus.TREATMENT, new IDataBase.Action() {
#Override
public void onSuccess() {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage("The drive is in your care!")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
String mail = drive.getEmail();
String[] mails = mail.split(",");
Intent in = new Intent(Intent.ACTION_SEND);
in.putExtra(Intent.EXTRA_EMAIL, mails);
in.putExtra(Intent.EXTRA_SUBJECT, "get taxi");
in.putExtra(Intent.EXTRA_TEXT, "taxi will coming to you in few minutes");
in.setType("message/rfc822");
startActivity(Intent.createChooser(in, "choose email"));
}
});
AlertDialog alert = builder.create();
alert.show();
drives.remove(getAdapterPosition());
drivesRecyclerView.getAdapter().notifyDataSetChanged();
}
#Override
public void onFailure(Exception exception) {
Toast.makeText(getActivity(), "הלקיחה נכשלה", Toast.LENGTH_LONG).show();
}
#Override
public void onProgress(String status, double percent) {
;
}
});
return true;
}
});
}
});
}
}
}
}
So first I initialized my listview and added registerForContextMenu(my_list)
chatLists = (ListView)findViewById(R.id.chatlist);
chatLists.setAdapter(new ContactListAdapter(this));
registerForContextMenu(chatLists);
Then I added the OnCreateContextMenu
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId()==R.id.chatlist) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.list_context, menu);
}
}
But After running the app.. When I long press on any list items, it's not showing any context Menu..
here is some sample code u can use:
`
... onCreateView{
.....
notiList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
setListMultiSelectListener();
}
public void setListMultiSelectListener() {
notiList.setMultiChoiceModeListener(new MultiChoiceModeListener() {
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
// clear your list selection here
mAdapter.clearSelection();
}
#Override
public boolean onCreateActionMode(final ActionMode mode, Menu menu) {
// inflate your action menu here
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.delete_mode_menu, menu);
return true;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.action_select_all:
if (mAdapter.isAllSelected()) {
mAdapter.clearSelection();
for (int i = 0; i < notiList.getAdapter().getCount(); i++) {
notiList.setItemChecked(i, false);
}
} else {
mAdapter.selectAllItems();
for (int i = 0; i < notiList.getAdapter().getCount(); i++) {
notiList.setItemChecked(i, true);
}
}
break;
case R.id.action_delete:
mAdapter.deleteSelectedItems();
mode.finish();
break;
}
return true;
}
#Override
public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
deletionMode = mode;
if (checked) {
nr = nr + 1;
mAdapter.setNewSelection(position, checked);
} else {
nr = nr - 1;
mAdapter.removeSelection(position);
}
if (mAdapter.isAllSelected()) {
mode.getMenu().findItem(R.id.action_select_all).setIcon(R.drawable.check);
} else {
mode.getMenu().findItem(R.id.action_select_all).setIcon(R.drawable.uncheck);
}
}
});
}
`
here is adapter:
public class NotificationListAdapter extends BaseAdapter {
private MainActivity context;
private Vector<MessageInboxBean> messagesList;
private DisplayImageOptions /* options, */ options1;
private ImageLoader imageLoader;
private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();
private NotiItemHolder holder;
private boolean isHomeworkTab;
private LineColorPicker colorPicker;
private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>();
int msgTypeId;
public NotificationListAdapter(MainActivity context, int msgTypeId, Vector<MessageInboxBean> messagesList, DisplayImageOptions options, boolean isHomeworkTab) {
this.context = context;
this.messagesList = messagesList;
// this.options = options;
options1 = new DisplayImageOptions.Builder()//
.showImageOnLoading(R.drawable.default_teacher)//
.showImageForEmptyUri(R.drawable.default_teacher)//
.showImageOnFail(R.drawable.default_teacher)//
.cacheInMemory(true)//
.cacheOnDisk(true)//
.considerExifParams(true)//
.displayer(new RoundedBitmapDisplayer(0))//
.build();
this.isHomeworkTab = isHomeworkTab;
this.msgTypeId = msgTypeId;
imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
if (this.messagesList == null) {
messagesList = getMessagesList(this.msgTypeId);
}
// if (this.messagesList.size() == 0) {
// messagesList = getMessagesList(this.msgTypeId);
// }
}
public void setNewSelection(int position, boolean value) {
mSelection.put(position, value);
notifyDataSetChanged();
}
public boolean isPositionChecked(int position) {
Boolean result = mSelection.get(position);
return result == null ? false : result;
}
public Set<Integer> getCurrentCheckedPosition() {
return mSelection.keySet();
}
public void removeSelection(int position) {
mSelection.remove(position);
notifyDataSetChanged();
}
public void clearSelection() {
mSelection = new HashMap<Integer, Boolean>();
notifyDataSetChanged();
}
public void selectAllItems() {
mSelection = new HashMap<Integer, Boolean>();
for (int i = 0; i < messagesList.size(); i++) {
mSelection.put(i, true);
}
notifyDataSetChanged();
}
public boolean isAllSelected() {
if (mSelection.size() == messagesList.size()) {
return true;
} else {
return false;
}
}
public void deleteSelectedItems() {
ArrayList<Integer> notiIdAray = new ArrayList<Integer>();
for (int i = 0; i < messagesList.size(); i++) {
Boolean result = mSelection.get(i);
boolean result1 = result == null ? false : result;
if (result1) {
notiIdAray.add(messagesList.get(i).getNotificationId());
}
}
((MessageInboxTable) AppDb.getInstance(context).getTableObject(MessageInboxTable.TABLE_NAME)).deleteData(notiIdAray, context);
updateMessagesList(msgTypeId);
notifyDataSetChanged();
}
#Override
public int getCount() {
return messagesList.size();
}
#Override
public Object getItem(int position) {
return messagesList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#SuppressWarnings("deprecation")
#SuppressLint({ "NewApi", "InflateParams" })
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.notification_list_item, null);
holder = new NotiItemHolder();
holder.dueDate = (TextView) convertView.findViewById(R.id.dueDateTxt);
holder.date = (TextView) convertView.findViewById(R.id.date);
holder.day = (TextView) convertView.findViewById(R.id.day);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.message = (TextView) convertView.findViewById(R.id.message);
holder.subject = (TextView) convertView.findViewById(R.id.subject);
holder.doneStatus = (TextView) convertView.findViewById(R.id.doneStatus);
holder.sendersName = (TextView) convertView.findViewById(R.id.sendersName);
holder.notiDate = (TextView) convertView.findViewById(R.id.notiDate);
holder.sendersImg = (ImageView) convertView.findViewById(R.id.sendersImg);
holder.statusImg = (ImageView) convertView.findViewById(R.id.statusImg);
holder.star = (CheckBox) convertView.findViewById(R.id.star);
holder.doneLayout = (LinearLayout) convertView.findViewById(R.id.done_layout);
holder.endView = convertView.findViewById(R.id.endView);
convertView.setTag(holder);
} else {
holder = (NotiItemHolder) convertView.getTag();
}
MessageInboxBean bean = messagesList.get(position);
if (mSelection.get(position) != null) {
convertView.findViewById(R.id.cal_img_layout).setBackgroundResource(R.drawable.calender_check);
holder.dueDate.setVisibility(View.INVISIBLE);
holder.date.setVisibility(View.INVISIBLE);
holder.day.setVisibility(View.INVISIBLE);
} else {
if (bean.getDueDate().trim().length() > 0) {
convertView.findViewById(R.id.cal_img_layout).setBackgroundResource(R.drawable.calender);
holder.dueDate.setVisibility(View.VISIBLE);
holder.date.setVisibility(View.VISIBLE);
holder.day.setVisibility(View.VISIBLE);
holder.date.setText(getDueDate(bean.getDueDate()));
holder.day.setText(getDueDay(bean.getDueDate()));
} else {
convertView.findViewById(R.id.cal_img_layout).setBackgroundResource(R.drawable.calender_2);
holder.dueDate.setVisibility(View.INVISIBLE);
holder.date.setVisibility(View.INVISIBLE);
holder.day.setVisibility(View.INVISIBLE);
}
if (isHomeworkTab) {
holder.subject.setVisibility(View.VISIBLE);
holder.doneLayout.setVisibility(View.VISIBLE);
} else {
holder.subject.setVisibility(View.GONE);
holder.doneLayout.setVisibility(View.GONE);
}
}
holder.title.setText(bean.getTitle());
holder.message.setText(bean.getMessage());
if (isHomeworkTab) {
holder.subject.setText(getSubjectFromId(context, bean.getSubjectId()) == null ? "" : getSubjectFromId(context, bean.getSubjectId()));
String colr = getSubjectColorFromId(context, bean.getSubjectId());
if (colr != null) {
setColorToImage(holder.subject, 1, colr, false);
}
if (bean.getStatus().equals("0")) {
holder.doneStatus.setText("Not done");
holder.doneStatus.setTextColor(context.getResources().getColor(R.color.text_light_grey));
holder.statusImg.setImageResource(R.drawable.not_done);
} else {
holder.doneStatus.setText("Done");
holder.doneStatus.setTextColor(context.getResources().getColor(R.color.app_theme_color));
holder.statusImg.setImageResource(R.drawable.done);
}
}
holder.notiDate.setText(getMessageDate(bean.getMessageDate()));
if (bean.getStarred().equals("0")) {
holder.star.setChecked(false);
} else {
holder.star.setChecked(true);
}
holder.sendersName.setText("~" + bean.getSender());
// holder.notiDate
imageLoader.displayImage(bean.getSenderPicURL(), holder.sendersImg, options1, animateFirstListener);
holder.subject.setTag(position);
holder.star.setTag(position);
holder.doneLayout.setTag(position);
holder.subject.setOnClickListener(subjectClick);
holder.star.setOnCheckedChangeListener(starClick);
holder.doneLayout.setOnClickListener(doneClick);
if (position == getCount() - 1) {
holder.endView.setVisibility(View.VISIBLE);
} else {
holder.endView.setVisibility(View.GONE);
}
return convertView;
}
class NotiItemHolder {
TextView dueDate, date, day, title, message, subject, doneStatus, sendersName, notiDate;
ImageView sendersImg, statusImg;
CheckBox star;
LinearLayout doneLayout;
View endView;
}
}
I am trying to implement MultiChoiceModeListener for select multiple item from a ListView. My current progress is shown below. But it doesn't working. It has no action on even long press. is any thing missed in my code or anything wrong? Any help will be greatly appreciated.
public class FragmentFavorite extends Fragment {
ListView lvFavoriteItems;
Activity mActivity = null;
Context mContext;
ArrayList<String> names = new ArrayList<>(Arrays.asList("My name is a", "My name is b",
"My name is c", "My name is d", "My name is e", "My name is f"));
ArrayList<String> phone = new ArrayList<>(Arrays.asList("9895653263", "9895653264", "9895653265",
"9895653266", "9895653267", "9895653267"));
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(mActivity == null) {
this.mActivity = getActivity();
}
this.mContext = context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.favorite_list, container, false);
lvFavoriteItems = (ListView) root.findViewById(R.id.lv_item_list);
FavoriteAdapter fav = new FavoriteAdapter();
lvFavoriteItems.setAdapter(fav);
lvFavoriteItems.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
lvFavoriteItems.setMultiChoiceModeListener(new FavMultiChoiceModeListener());
return root;
}
private class FavoriteAdapter extends BaseAdapter {
#Override
public int getCount() {
return names.size();
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
View listItem;
LayoutInflater inflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
listItem = inflater.inflate(R.layout.contact_item_2_line, null);
} else {
listItem = convertView;
}
TextView tv1 = (TextView) listItem.findViewById(R.id.tv_item_name);
tv1.setText(names.get(position));
TextView tv2 = (TextView) listItem.findViewById(R.id.tv_phone);
tv2.setText(phone.get(position));
listItem.setId(position);
return listItem;
} }
private class FavMultiChoiceModeListener implements ListView.MultiChoiceModeListener {
#Override
public void onItemCheckedStateChanged(ActionMode mode, int i, long l, boolean b) {
final int checkedCount = lvFavoriteItems.getCheckedItemCount();
mode.setSubtitle("" + checkedCount + " items selected ");
}
#Override
public boolean onCreateActionMode(ActionMode actionMode, Menu menu) {
MenuInflater inflater = mActivity.getMenuInflater();
inflater.inflate(R.menu.selection_menu, menu);
actionMode.setTitle("Select Items");
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
return true;
}
#Override
public boolean onActionItemClicked(ActionMode actionMode, MenuItem menuItem) {
Toast.makeText(mActivity, "Clicked " + menuItem.getTitle(),
Toast.LENGTH_SHORT).show();
return true;
}
#Override
public void onDestroyActionMode(ActionMode actionMode) {
}
}
}
Since you're extending from BaseAdapter, you might need to call convertView.setLongClickable(true) in your getView method.