I want to add a Switch to a PopupMenu as an item, I also don't want to use any XML codes, Is there is any way to do this?
here is an example of my code :
options.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View _view) {
PopupMenu myPopupMenu = new PopupMenu(getApplicationContext(), options);
myPopupMenu.getMenu().add("Option 1");
myPopupMenu.getMenu().add("Option 2");
myPopupMenu.getMenu().add("Option 3");
//Here I want to add a Switch
myPopupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
switch(item.getTitle().toString()) {
case "Option 1": {
onFirstOptionClicked();
break;
}
case "Option 2": {
onSecondOptionClicked();
break;
}
case "Option 3": {
onThirdOptionClicked();
break;
}
case "The Title of The Switch": {
//here i want to get a boolean value
//that detects if the Switch is checked or not
break;
}
}
return true;
}
});
myPopupMenu.show();
}});
I tried using the setCheckable method but it made a CheckBox item, what I want is a Switch item :
myPopupMenu.getMenu().add("The Title of The Switch").setCheckable(true);
Related
I've read that you have to store the item's state and set it again because it gets cleared from the RAM. For me, If I keep scrolling up and down in a bit longer list (10-15 item) random checks will appear and disappear. Below is how I store it and set it. What should I set apart from these? I'm using this inside a fragment.
#Override
public void onBindViewHolder(#NonNull BettingViewHolder holder, int position) {
BettingItem item = items.get(position);
holder.homeTextView.setText(item.homeTeam);
holder.awayTextView.setText(item.awayTeam);
holder.dateTextView.setText(item.date);
holder.leagueTextView.setText(item.league);
holder.sportsTextView.setText(item.sport);
holder.homeOddsTextView.setText(Double.toString(item.homeOdds));
holder.drawOddsTextView.setText(Double.toString(item.drawOdds));
holder.awayOddsTextView.setText(Double.toString(item.awayOdds));
switch (item.outcome) {
case HOME:
holder.homeCheckBox.setChecked(true);
break;
case DRAW:
holder.drawCheckBox.setChecked(true);
break;
case AWAY:
holder.awayCheckBox.setChecked(true);
break;
default:
holder.homeCheckBox.setChecked(false);
holder.drawCheckBox.setChecked(false);
holder.awayCheckBox.setChecked(false);
break;
}
holder.item = item;
}
//its a part from ViewHolder's constructor
homeCheckBox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if (item != null) {
homeCheckBox.setChecked(isChecked);
if (isChecked) {
item.outcome = BettingItem.Outcome.valueOf("HOME");
drawCheckBox.setChecked(false);
awayCheckBox.setChecked(false);
} else {
if (item.outcome == BettingItem.Outcome.valueOf("HOME"))
item.outcome = BettingItem.Outcome.valueOf("NONE");
}
listener.onEventSelected(item);
}
}
});
drawCheckBox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if (item != null) {
drawCheckBox.setChecked(isChecked);
if (isChecked) {
item.outcome = BettingItem.Outcome.valueOf("DRAW");
homeCheckBox.setChecked(false);
awayCheckBox.setChecked(false);
} else {
if (item.outcome == BettingItem.Outcome.valueOf("DRAW"))
item.outcome = BettingItem.Outcome.valueOf("NONE");
}
listener.onEventSelected(item);
}
}
});
awayCheckBox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
if (item != null) {
awayCheckBox.setChecked(isChecked);
if (isChecked) {
item.outcome = BettingItem.Outcome.valueOf("AWAY");
drawCheckBox.setChecked(false);
homeCheckBox.setChecked(false);
} else {
if (item.outcome == BettingItem.Outcome.valueOf("AWAY"))
item.outcome = BettingItem.Outcome.valueOf("NONE");
}
listener.onEventSelected(item);
}
}
});
you need to uncheck the old checkboxes, because the viewHolders got recycled (if the old checkBoxes were selected, it'll remain selected).
switch (item.outcome) {
case HOME:
holder.homeCheckBox.setChecked(true);
holder.drawCheckBox.setChecked(false);
holder.awayCheckBox.setChecked(false);
break;
case DRAW:
holder.homeCheckBox.setChecked(false);
holder.drawCheckBox.setChecked(true);
holder.awayCheckBox.setChecked(false);
break;
case AWAY:
holder.homeCheckBox.setChecked(false);
holder.drawCheckBox.setChecked(false);
holder.awayCheckBox.setChecked(true);
break;
default:
holder.homeCheckBox.setChecked(false);
holder.drawCheckBox.setChecked(false);
holder.awayCheckBox.setChecked(false);
break;
}
I would only want this behaviour if the user taps on it. I don't know
yet how to seperate these.
in this case, do something like this in your onCheckedChangedListener
homeCheckBox.setOnCheckedChangedListener(buttonView, isChecked -> {
if(buttonView.isPressed()){
//user pressed the button. (handle user clicks)
} else {
//the program toggled the checkbox (do nothing)
}
});
You can basically create list of objects to store your checkbox status with default status (you can use Boolean) and you need to set your recycler view checkbox status from that list. By the way, your status list need to have same size as your total cell size to avoid index out of range error. Also, when your status change you need to change your list of object in your already created list.
I have 4 items in the menu and 1 button Rec / Stop. I want, when the Rec button is active and records, the other 4 items in the menu items are disabled. Please help me.
this is activity_main.xml
<ToggleButton
android:id="#+id/recStop"
android:layout_width="65dp"
android:layout_height="65dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="100dp"
android:background="#drawable/tbutton"
android:text=""
android:textOff=""
android:textOn="" />
this is tbutton.xml
<item android:drawable="#drawable/rec"
android:state_checked="false" />
<item android:drawable="#drawable/stop"
android:state_checked="true" />
this is MainActivity.java
private ToggleButton toggleButton;
toggleButton = (ToggleButton) findViewById(R.id.recStop);
// Button Rec / Stop
toggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
speech.setRecognitionListener(VoiceRecognitionActivity.this);
progressBar.setVisibility(View.VISIBLE);
progressBar.setIndeterminate(true);
speech.startListening(recognizerIntent);
} else {
progressBar.setIndeterminate(false);
progressBar.setVisibility(View.INVISIBLE);
speech.stopListening();
speech.destroy();
}
}
});
this is MainActivity.java
// Menu items
public boolean onOptionsItemSelected(MenuItem item){
switch (item.getItemId()) {
case R.id.copy:
break;
}
switch (item.getItemId()) {
case R.id.share:
break;
}
switch (item.getItemId()) {
case R.id.clear:
break;
}
switch (item.getItemId()) {
case R.id.about:
break;
}
return super.onOptionsItemSelected(item);
}
Inside each condition of your switch...case, check the status of togglebutton and if its checked avoid further actions in it. Also don't use multiple switch, you must define multiple cases inside it see the code below.
switch (item.getItemId()) {
case R.id.copy:
if(toggleButton.isChecked()) {
//display warning message
} else {
// your regular code here
}
break;
case R.id.share:
if(toggleButton.isChecked()) {
//display warning message
} else {
// your regular code here
}
break;
case R.id.clear:
if(toggleButton.isChecked()) {
//display warning message
} else {
// your regular code here
}
break;
case R.id.about:
if(toggleButton.isChecked()) {
//display warning message
} else {
// your regular code here
}
break;
}
You can achieve that with this code
switch (item.getItemId()) {
case R.id.copy:
if(toggleButton.isChecked()) {
menu.findItem(R.id.copy).setEnabled(false);
} else {
menu.findItem(R.id.copy).setEnabled(true);
}
break;
//you do the same for the rest of menu buttons
}
I have created a private member of the whole class called Member curMbr;
The activity (rather the fragment, since this is in a frament class) has a listview
with some contributions from members.
I also have a context menu on that list. When clicking on a contribution, I want a (customized) dialog box to show details about the member. (Member ID is part of the contribution objet. )
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
Log.d("FRGCOTIZ02", "create ctxt menu");
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
String[] menuItems = getResources().getStringArray(R.array.ar_menu_ctxt_participant);
// Get selected member
Contribution curCotis = (Contribution) (((ListView)v).getItemAtPosition(info.position));
Participant p = new Participant(helper.getDBItem(DBHelper.TABLE_PARTICIPANT,
DBHelper.COL_ID, curCotis.getParticipant()));
curMbr = new Member(helper.getDBItem(DBHelper.TABLE_MEMBER, DBHelper.COL_ID, p.getMember()));
for (int i = 0; i < menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
Log.d("FRGCOTIZ01", curMbr.getId_());
}
#Override
public boolean onContextItemSelected(MenuItem item) {
return ( applyContextMenuSelection(item) || super.onContextItemSelected(item) );
}
private boolean applyContextMenuSelection(MenuItem item) {
switch (item.getItemId()) {
case 0: // Summary
final Dialog dlg = new Dialog(this.getContext());
final String sessID;
try {
sessID = KUtil.DATE_FORMAT.format(curSess.getDate());
dlg.setContentView(R.layout.alert_show_charges);
Button btnOK = dlg.findViewById(R.id.btn_alertOK);
btnOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
setupAlertDialogCharges(dlg, sessID, curMbr.getId_());
}
});
Button btnCancel = dlg.findViewById(R.id.btn_alertCancel);
btnCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dlg.dismiss();
}
});
dlg.show();
} catch (Exception e){
Log.d("FRAGMENT Contribution", e.getMessage());
}
break;
case 1: // Collect
break;
case 2: // Cancel
break;
default:
break;
}
return true;
}
In method onCreateContextMenu, I can get the member and display his ID.
But in method applyContextMenuSelection, there is an exception, saying the meber is null!
Funny enough there is another variable that I am using in that method, and it works fine. Difference is, that variable has been set at creation of the fragment.
How do I solve this?
I have been studying the code for a while and the only thing I could figure was that the issue is somehow linked to the use of contextmenu. It seems to me that variables are set back to their original when the menu action is supposed to be executed. Again, I am not too sure about that.
So, the only solution I found so far was to keep that vale in a "higher" context:
When I can still read the value,
getActivity().getIntent().putExtra(HomeActivity.ID_ENTRY, curMbr.getId_());
When I want to use it,
final String mbrID = getActivity().getIntent().getStringExtra(HomeActivity.ID_ENTRY);
i'll create a custom Dropdown/popup and it's work perfect.
See below Custom dropdown/popup code:
case R.id.linerSort:
PopupMenu popup = new PopupMenu(activity, linerSort);
//Inflating the Popup using xml file
popup.getMenuInflater()
.inflate(R.menu.popup, popup.getMenu());
//registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(
activity,
"You Clicked : " + item.getTitle(),
Toast.LENGTH_SHORT
).show();
return true;
}
});
popup.show();
break;
Now i want to sorting a list which i select a item of Dropdown/popup.
Sorting is according to ArrayList<Object> So how to do that with my code.
if suppose i select a price then is shorting a acceding or descending order.
i follow this link: How to sort ArrayList<Object> in Ascending order android But how to i merge with my code i don't understand.
Try below code to sort in ascending or descending order:
case R.id.HighToLow:
Collections.sort(subCategoryViewDataBeanArrayList, new Comparator<SubCategoryViewDataBean>() {
#Override
public int compare(SubCategoryViewDataBean s1, SubCategoryViewDataBean s2) {
return Integer.parseInt(String.valueOf(s2.price)) - Integer.parseInt(String.valueOf(s1.price));
}
});
BindData(subCategoryViewDataBeanArrayList);
break;
case R.id.LowToHigh:
Collections.sort(subCategoryViewDataBeanArrayList, new Comparator<SubCategoryViewDataBean>() {
#Override
public int compare(SubCategoryViewDataBean s1, SubCategoryViewDataBean s2) {
return Integer.parseInt(String.valueOf(s1.price)) - Integer.parseInt(String.valueOf(s2.price));
}
});
BindData(subCategoryViewDataBeanArrayList);
I tried this solution, but it doesn't work as I expected. Here is my code, and this is what i have tried.
PopupMenu popup = new PopupMenu(TableActivity.this, view);
popup.setOnMenuItemClickListener(TableActivity.this);
menu = popup.getMenu();
popup.inflate(R.menu.popup_shift);
popup.show();
popup.setOnMenuItemClickListener(this);
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_merge:
if(tableDbList.get(positionShift).getMergeTableId()== 0) {
//this is the condition to show/hide popup menuitem
popup.getMenu().findItem(R.id.menu_merge).setVisible(false);
}else {
checkPinCode.checkPinCodemethod(TableActivity.this, "mergeCancel");
}
}
return true;
}
You are trying to change visibility on MenuItem click . It will work but popupMenu will dismiss just after click . So it does not make any sense.
If your requirement is to show items on some condition you should set visibility before show(). Below is a simple example .
private void showPopup() {
final PopupMenu popup = new PopupMenu(MainActivity.this, view);
popup.getMenuInflater().inflate(R.menu.popup_shift, popup.getMenu());
if(someCondition){
popup.getMenu().findItem(R.id.menu_merge).setVisible(false);
}
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Toast.makeText(MainActivity.this, "You Clicked : " + item.getTitle(), Toast.LENGTH_SHORT).show();
return true;
}
});
popup.show();
}