Onbackpressed with dialog and check box don't show again - checkbox

When the user first opens the application and then presses the back button to exit the application, an alertdialog will appear to exit and provide a rating.
I want to add a checkbox so that when the user has ticked then the alertdialog doesn't reappear when pressing the back button.
I've tried it with this code no luck. Users cannot exit the application when they have checked the checkbox.
#Override
public void onBackPressed() {
LayoutInflater inflater = getLayoutInflater();
View alertLayout = inflater.inflate(R.layout.dailog_review, null);
AlertDialog.Builder alert = new AlertDialog.Builder(this);
CheckBox mCheckBox = alertLayout.findViewById(R.id.checkBox);
// this is set the view from XML inside AlertDialog
alert.setView(alertLayout);
alert.setNeutralButton("Exit", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//System.exit(1);
HomeActivity.super.onBackPressed();
}
});
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + getPackageName())));
} catch (android.content.ActivityNotFoundException anfe) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + getPackageName())));
}
}
});
AlertDialog mDialog = alert.create();
mDialog.show();
mCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(compoundButton.isChecked()){
storeDialogStatus(true);
}else{
storeDialogStatus(false);
}
}
});
if(getDialogStatus()){
mDialog.hide();
}else{
mDialog.show();
}
}
private void storeDialogStatus(boolean isChecked){
SharedPreferences mSharedPreferences = getSharedPreferences("CheckItem", MODE_PRIVATE);
SharedPreferences.Editor mEditor = mSharedPreferences.edit();
mEditor.putBoolean("item", isChecked);
mEditor.apply();
}
private boolean getDialogStatus(){
SharedPreferences mSharedPreferences = getSharedPreferences("CheckItem", MODE_PRIVATE);
return mSharedPreferences.getBoolean("item", false);
}

Based on the code provided,
if the user selected do not show again
your condition is handling this as hiding the dialog, which is not showing, so you need to trigger super backpress instead
if(getDialogStatus()){
HomeActivity.super.onBackPressed();
}else{
mDialog.show();
}

Related

RecyclerView: how to start Contextual Action Bar CAB with a Checkbox?

I have a RecyclerView list of CardViews and am using AppCompatActivity. Each CardView has a checkbox. When I click on the checkbox I would like to start a Contextual Action Bar. I would like to use an OnCheckedChangeListener and am having no luck. The checkmark correctly becomes visible when the "chkSelected" Checkbox is clicked on and it becomes invisible when the "chkSelected is clicked on again. What am I missing here?
public class MyRecylerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
...
private static ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
}
#Override
public void onDestroyActionMode(ActionMode mode) {
}
};
...
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_contact_item, parent, false);
final ItemHolder itemHolder = new ItemHolder(view);
return itemHolder;
}
private static class ItemHolder extends RecyclerView.ViewHolder {
private CheckBox chkSelected;
private ItemHolder(View itemView) {
super(itemView);
chkSelected = (CheckBox) itemView.findViewById(R.id.chkSelected);
chkSelected.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked)
mActionMode = ((AppCompatActivity) buttonView.getContext()).startSupportActionMode(actionModeCallback);
}
});
}
I also tried an OnClickListener() in the ItemHolder() with no luck. Code is below. The Toast in the onClick() is showing properly so there must be something wrong with the startSupportActionMode().
chkSelected.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(),"Checkbox was clicked",Toast.LENGTH_LONG).show();
if(mActionMode == null) {
// Start the Contextual Action Bar (CAB) using the ActionMode.Callback defined above
mActionMode = ((AppCompatActivity) view.getContext()).startSupportActionMode(mActionModeCallback);
}
}
});
Solution was to set up a method in onBindViewHolder() that would update the item views for the OnClickListeners in Itemholder().

Codename One Back Command on left and Menu on Right

i am trying to make an app in Codename one where i want to create a handburger menu on the right side at the top of the screen and a back button on the left side, but cannot get it to work I know it can be done where you have a handburger menu on the left side and a button on the right side. I made a picture of how I want it to look like. The back button is added in paint and not through the code.
Picture of app example
below is the code that I have used to get the menu on the right side.
public class MainForm {
public static Form mainForm;
Command cmd_back, cmd_AboutTheApp;
private enum SideMenuMode {
SIDE, RIGHT_SIDE {
public String getCommandHint() {
return SideMenuBar.COMMAND_PLACEMENT_VALUE_RIGHT;
}
};
public String getCommandHint() {
return null;
}
public void updateCommand(Command c) {
String h = getCommandHint();
if(h == null) {
return;
}
c.putClientProperty(SideMenuBar.COMMAND_PLACEMENT_KEY, h);
}
};
SideMenuMode mode = SideMenuMode.RIGHT_SIDE;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
UIManager.getInstance().setThemeProps(theme.getTheme theme.getThemeResourceNames()[0]));
UIManager.getInstance().getLookAndFeel().setMenuBarClass(SideMenuBar.class);
Display.getInstance().setCommandBehavior(Display.COMMAND_BEHAVIOR_SIDE_NAVIGATION);
}
public void start() {
if(mainForm != null){
mainForm.show();
return;
}
mainForm = new Form();
mainForm.setTitleComponent(title);
mainForm.setLayout(new BorderLayout());
addCommands(mainForm);
}
private void addCommands(Form f){
cmd_Back = new Command("Back");
final Button btn_Back = new Button("Back");
cmd_Back.putClientProperty("TitleCommand", btn_Back);
btn_BackButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//do some thing
}
});
cmd_AboutTheApp = new Command("About the app");
final Button btn_AboutTheApp = new Button("About the app");
cmd_AboutTheApp.putClientProperty("SideComponent", btn_AboutTheApp);
btn_AboutTheApp.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//do some thing
}
});
mode.updateCommand(cmd_Back);
f.addCommand(cmd_Back);
mode.updateCommand(cmd_AboutTheApp);
f.addCommand(cmd_AboutTheApp);
}
}
if I move the back button so that it is added after AboutTheApp button then the back button is displayed on the right side of the screen but also to the right of the menu, which is also on the right side. I've tried a lot of different ways but none seems to be working
We supported a right side menu bar in the SideMenuBar but not in the Toolbar API. We support placing components/commands in the left/right side of the title area in the Toolbar API but not in the SideMenuBar.
I guess the solution is to add support for the right menu bar into the Toolbar API but I'm not sure what the complexities are for such a change.
I suggest filing an RFE in the issue tracker asking for this but it probably won't be soon as we are closing the features for 3.3 right now.
I have an app that does this. Search Google Play (or App Store) for "Torquepower Diesel Cummins Engine" app.
in the theme Constants I set my own rightSideMenuImage and rightSideMenuPressImage, but the default hamburger menu may be OK for you.
On the beforeXXXX of each form I do something like this:
super.beforePartNumberForm(f);
Toolbar tb = createToolbar(f);
createBackCommand(f, tb);
addHelpX(tb);
addViewCartX(tb);
addCallTorquepowerX(tb);
addReverseSwipe(f);
create the toolbar
Toolbar createToolbar(Form f) {
Toolbar tb = new Toolbar();
f.setToolBar(tb);
Label l = new Label();
l.setIcon(res.getImage("tpd_logoZZ.png"));
tb.setTitleComponent(l);
return tb;
}
create the back button
void createBackCommand(Form f, Toolbar tb) {
Command c = new Command("") {
#Override
public void actionPerformed(ActionEvent evt) {
back();
}
};
c.setIcon(res.getImage("black_left_arrow-512.png"));
c.setPressedIcon(res.getImage("grey_left_arrow-512.png"));
// MUST set this before adding to toolbar, else get null pointer
f.setBackCommand(c);
tb.addCommandToLeftBar(c);
}
add whatever commands are needed to the sidemenu
void addHelpX(Toolbar tb) {
Command c = new Command("Help") {
#Override
public void actionPerformed(ActionEvent evt) {
showForm("HelpForm", null);
}
};
c.putClientProperty(SideMenuBar.COMMAND_PLACEMENT_KEY, SideMenuBar.COMMAND_PLACEMENT_VALUE_RIGHT);
c.putClientProperty("SideComponent", new SideMenuItem(fetchResourceFile(), c.toString(), "very_basic_about.png"));
c.putClientProperty("Actionable", Boolean.TRUE);
tb.addCommandToSideMenu(c);
}
I use my own SideMenuItem which is:
public class SideMenuItem extends Button {
SideMenuItem() {
this("");
}
SideMenuItem(String s) {
super(s);
setUIID("SideMenuItem");
int h = Display.getInstance().convertToPixels(8, false);
setPreferredH(h);
}
SideMenuItem(Resources res, String s, String icon) {
super();
setIcon(res.getImage(icon));
setText(s);
setUIID("SideMenuItem");
int h = Display.getInstance().convertToPixels(8, false);
setPreferredH(h);
}
}

How to avoid closing popup menu on mouse clicking in javafx combobox?

I have combobox with custom ListCell:
private class SeverityCell extends ListCell<CustomItem> {
private final CustomBox custombox;
{
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
custombox = new CustomBox();
}
#Override
protected void updateItem(CustomItem item, boolean empty) {
super.updateItem(item, empty);
if (null != item) {
//...
}
setGraphic(custombox);
}
}
and
combobox.setCellFactory(new Callback<ListView<CustomItem>, ListCell<CustomItem>>() {
#Override public ListCell<CustomItem> call(ListView<CustomItem> p) {
return new SeverityCell();
}
});
When I click on mu custom component popup closes, but I want to avoid it. Which method/event I need to override?
ComboBox internally utilizes ListView for rendering its items. Also its skin class is ComboBoxListViewSkin. In a source code of this class there is boolean flag to control popup hiding behavior:
// Added to allow subclasses to prevent the popup from hiding when the
// ListView is clicked on (e.g when the list cells have checkboxes).
protected boolean isHideOnClickEnabled() {
return true;
}
which is used on listview:
_listView.addEventFilter(MouseEvent.MOUSE_RELEASED, t -> {
// RT-18672: Without checking if the user is clicking in the
// scrollbar area of the ListView, the comboBox will hide. Therefore,
// we add the check below to prevent this from happening.
EventTarget target = t.getTarget();
if (target instanceof Parent) {
List<String> s = ((Parent) target).getStyleClass();
if (s.contains("thumb")
|| s.contains("track")
|| s.contains("decrement-arrow")
|| s.contains("increment-arrow")) {
return;
}
}
if (isHideOnClickEnabled()) {
comboBox.hide();
}
});
So the behavior you want can be (and probably should be) implemented with custom skin. However, the workaround can be
combobox.setSkin( new ComboBoxListViewSkin<CustomItem>( combobox )
{
#Override
protected boolean isHideOnClickEnabled()
{
return false;
}
} );
and manually hide the popup, when the value is changed for instance:
combobox.valueProperty().addListener( new ChangeListener()
{
#Override
public void changed( ObservableValue observable, Object oldValue, Object newValue )
{
combobox.hide();
}
});
Note please, I didn't fully test this anonymous inner skin approach.

telerik Busy Indicator is not visible

Hi I am trying to use telerik Busy indicator with MVVM. I have the Busy indicator in Mainwindow. When there is an action(button click) on one of the user controls that is in the window, the user controls view model sends an message to the MinwindowviewModel. On the message the is busy indicator should show up. But this is not working. Why is this not working?
User controls view model
public class GetCustomerVM : ViewModelBase
{
private int _CustomerId;
public int CustomerId
{
get { return _CustomerId; }
set
{
if (value != _CustomerId)
{
_CustomerId = value;
RaisePropertyChanged("CustomerId");
}
}
}
public RelayCommand StartFetching { get; private set; }
public GetCustomerVM()
{
StartFetching = new RelayCommand(OnStart);
}
private void OnStart()
{
Messenger.Default.Send(new Start());
AccountDetails a = AccountRepository.GetAccountDetailsByID(CustomerId);
Messenger.Default.Send(new Complete());
}
}
The User Control View model is:
private bool _IsBusy;
public bool IsBusy
{
get { return _IsBusy; }
set
{
if (value != _IsBusy)
{
_IsBusy = value;
RaisePropertyChanged("IsBusy");
}
}
}
public WRunEngineVM()
{
RegisterForMessages();
}
private void RegisterForMessages()
{
Messenger.Default.Register<Start>(this, OnStart);
Messenger.Default.Register<Complete>(this, OnComplete);
}
private void OnComplete(Complete obj)
{
IsBusy = false;
}
private void OnStart(Start obj)
{
IsBusy = true;
}
In the Main window View, the root element is
<telerik:RadBusyIndicator IsBusy="{Binding IsBusy}" telerik:StyleManager.Theme="Windows7">
What does AccountDetails a = AccountRepository.GetAccountDetailsByID(CustomerId); do? My guess is that whatever is happeneing there is running on the UI thread. Because it is all happeneing on the UI thread, there is never a chance of the UI to refresh and show the RadBusyIndicator. Try moving all of the work on in OnStart to a BackgroundWorker, including sending the messages. You will run into issues here, because the messages will be updating the UI thread from a background thread, so you will need to use the Dispatcher to set IsBusy to true or false.

Wait for pending operations to finish without blocking UI thread

I have a MVP like application, all expensive operations are using Async calls and display an Ajax like gif that indicates the user that something is happening without blocking the main thread.
Example:
Data entry form, user clicks Save, an async operation takes place and when it finishes restores the screen to an editable form without blocking the UI thread (in other terms, not blocking other visible windows in the application).
Everything works fine in here, but given the following scenario:
User tries to close the Form, and gets a confirmation message that asks the user if he is sure that he is going to close if he prefers to Save before closing.
When the users clicks 'Save' the same logic explained before takes place, but I'm forced to wait for this call to finish in the UI thread (in case there are any errors in the async call or whatever) and I can`t find any way of doing it other way without blocking the UI thread.
Any suggestions? Thanks!
--- Edit ----
What I'm doing right now is waiting on all my WaitHandles in the Presenter with this loop:
while (!WaitHandles.All(h => h.WaitOne(1)))
Application.DoEvents();
It feels a little dirty.. but at least it simulates non blocking the thread. Is this something that for some reason I should not be doing?
Here is an example of the "hide method". Granted, it's not MVP, it's just an example.
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
class Form1 : Form
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1()
{
Text = "First Form";
Button button;
Controls.Add(button = new Button { Text = "Launch 2nd Form", AutoSize = true, Location = new Point(10, 10) });
button.Click += (s, e) => new Form2 { StartPosition = FormStartPosition.Manual, Location = new Point(Right, Top) }.Show(this);
}
}
class Form2 : Form
{
public Form2()
{
Text = "Second Form";
dirty = true;
}
private bool dirty;
protected override void OnClosing(CancelEventArgs e)
{
DialogResult result;
if (dirty && (result = new ConfirmSaveForm().ShowDialog(this)) != DialogResult.No)
{
if (Owner != null)
Owner.Activate();
Hide();
e.Cancel = true;
SaveAsync(result == DialogResult.Cancel);
}
base.OnClosing(e);
}
protected override void OnClosed(EventArgs e)
{
Trace.WriteLine("Second Form Closed");
base.OnClosed(e);
}
private void SaveAsync(bool fail)
{
SaveAsyncBegin();
var sad = new Action<bool>(PerformAsyncSave);
sad.BeginInvoke(fail, (ar) =>
{
try { sad.EndInvoke(ar); }
catch (Exception ex) { Invoke(new Action<Exception>(SaveAsyncException), ex); return; }
Invoke(new Action(SaveAsyncEnd));
}, null);
}
private void SaveAsyncBegin()
{
// Update UI for save
}
private void PerformAsyncSave(bool fail)
{
Trace.WriteLine("Begin Saving");
Thread.Sleep(1000); // Do some work
if (fail)
{
Trace.WriteLine("Failing Save");
throw new Exception("Save Failed");
}
dirty = false;
}
private void SaveAsyncEnd()
{
Trace.WriteLine("Save Succeeded");
Close();
}
private void SaveAsyncException(Exception ex)
{
Trace.WriteLine("Save Failed");
Show();
MessageBox.Show(this, ex.Message, "Save Failed", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
class ConfirmSaveForm : Form
{
public ConfirmSaveForm()
{
Text = "Confirm Save";
FormBorderStyle = FormBorderStyle.FixedDialog;
ControlBox = false;
ClientSize = new Size(480, 50);
StartPosition = FormStartPosition.CenterParent;
Controls.Add(new Button { Text = "Yes, Fail", DialogResult = DialogResult.Cancel, Size = new Size(150, 30), Location = new Point(10, 10) });
Controls.Add(new Button { Text = "Yes, Succeed", DialogResult = DialogResult.Yes, Size = new Size(150, 30), Location = new Point(160, 10) });
Controls.Add(new Button { Text = "No", DialogResult = DialogResult.No, Size = new Size(150, 30), Location = new Point(320, 10) });
AcceptButton = Controls[0] as IButtonControl;
}
}

Resources