I'm having problems with what I thought was a simple use of SharedPreferences!
Aim: I've a ActionBar/Tab application with a MainActivity and 4 Tabs as swipe Fragments. I want the App to remember the last user selected Tab, so that on the next start of the App, it defaults to that Tab.
Code in each Fragment (in the onCreateView method):
SharedPreferences prefs = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit().putInt("tabPref", 0);
editor.apply();
where the "tabPref", 0 is the name of the pref and number of the Tab (0-3).
In the MainActivity, I'm using the following to read the preference and set the default tab on starting the App (in onCreate):
SharedPreferences prefs = getPreferences(Context.MODE_PRIVATE);
Integer tabPref = prefs.getInt("tabPref", 99);
mViewPager.setCurrentItem(tabPref, false);
However, I'm getting some really weird preferences being set, that don't conform to the selection of the tab (e.g. Tab 4 doesn't even set the preference, and Tabs 1-3 randomly set Integers 0, 1, 2 or 3 - I'm using System.Outs to see what's happening).
Am I missing something fundamental regarding the life cycle of the fragments that isn't properly setting the SharedPreference?
Thanks....
Solved: I needed to set the SharedPreferences in the OnPageChangeListener class within MainActivity, not in the Fragments (doh!).
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
SharedPreferences.Editor editor = prefs.edit().putInt("tabPref", position);
editor.apply();
}
});
Related
so I am using JavFX to create a form that stores all the answers in a csv file. I need to create a dropdown menu that allows the users to select an option, which is then recorded in the csv file. I have tried a lot of different options, however I think comboBox is the best option.
I have no problem creating the ComboBox, I only run into problems when it comes to the method to get the value of the box.
Can someone help me find a solution, or suggest what another JavaFX menu I can use?
This is the code I have right now:
public VBox setFamiliar(){
Button button = new Button();
button.setOnAction(e -> toString());
familiarComboBox = new ComboBox<>();
familiarVBox = new VBox();
familiarComboBox.getItems().addAll("Irmão", "Irmã", "Avó", "Avô", "Tio", "Tia", "Pai", "Mãe");
familiarVBox.getChildren().add(familiarComboBox);
familiarVBox.getChildren().add(button);
return familiarVBox;
}
Here I set the ComboBox, this part doesnt seem to have a problem because it appears and I can select an item. I created a separate void toString() method that sets the value of a variable to the current selected item
public void toString(ActionEvent e){
familiar = familiarComboBox.getSelectionModel().getSelectedItem().toString();
}
The problem is then in the get method to get the value that was selected.
public String getIrmao(){
if(familiar.equals("Irmão")){
return "2";
}
return "0";
I also tried to do familiarComboBox.getSelectionModel().getSelectedItem().equals(), and other variations of this combination.
If I understand your requirement -- that when a user makes a choice from the "Familiar" combo box, a value should be written immediately to a CSV file -- you don't need the getIrmao() method. You simply write the value out in the action which you are calling toString(...) (not a good choice of names), but which we will rename to handleFamiliarChange(...).
Now the method becomes
public void handleFamiliarChange(ActionEvent e){
final String familiar =
familiarComboBox.getSelectionModel().getSelectedItem().toString();
FileUtils.writeToCsvFile(familiar.equals("Irmão") ? 2 : 0);
}
where FileUtils.writeToCsvFile(...) is a method that does the file writing. Note that FileUtils is a class you have created to separate out file handling concerns -- your JavaFX view class should only concern itself with views.
I am attempting to create a calculator app with a custom keypad using the MVVM pattern. The calculator has four entry boxes and I am suppressing the phone's keyboard from showing by using a custom renderer. I have noticed that the entrees lose their cursor position when I type numbers in an entry, change the cursor position manually by tapping in another position, and start typing again. When I start typing again, the initial character goes into the correct position, but any characters after that goes at the beginning of the string which means the cursor position is zero.
I cannot figure out what is resetting the cursor position. I am keeping track of the cursor position through binding. Here is a small snippet from my code below. So if EntryOne is Selected(Has Focus) and you start typing, the GetText method is called and I am passing in the cursor position by reference. The text that already exists in the Entry is separated into two parts. All the characters in front of the cursor position are part one and all the characters after the cursor position is part two. The parameter is the number the user pressed. All three strings are concatenated together to display the new text in the Entry box. If I use the phone’s keyboard I do not have this issue. So I know it is possible.
Please see the app attached and let me know if more info is needed. Any help would be greatly appreciated.
Thank you in advance!!!
EntryOneText = GetText(EntryOneText, parameter, ref _entryOneCursorIndex);
private string GetText(string text, string parameter, ref int cursorPosition)
{
if (!string.IsNullOrEmpty(text))
{
string partOne = text.Substring(0, cursorPosition);
string partTwo = text.Substring(cursorPosition, (text.Length - cursorPosition));
cursorPosition++;
return string.Format("{0}{1}{2}", partOne, parameter, partTwo);
}
cursorPosition++;
return parameter;
}
EntryCursorPositionTest
Thanks to Alessandro Caliaro. He provided an answer for me on the Xamarin Forms Forum.
private void EntryOne_Focused(object sender, FocusEventArgs e)
{
_mainViewModel.SelectedEntry = 1;
_mainViewModel.EntryOneCursorIndex = ((Entry)sender).CursorPosition;
}
public ICommand NumericCommand
{
get
{
return new Command<string>((string parameter) =>
{
if (!string.IsNullOrEmpty(parameter))
{
switch (SelectedEntry)
{
case 1:
if (EntryOneText == null)
EntryOneText = "";
int save = EntryOneCursorIndex;
EntryOneText = EntryOneText.Insert(save, parameter);
EntryOneCursorIndex = save + 1;
//EntryOneText = GetText(EntryOneText, parameter, ref _entryOneCursorIndex);
break;
My Dialog is a simple Frame with an Image, a label to display a question and two more labels (Yes / No) with TapCommand.
I've set up the container with the DialogPage.xaml and DialogPageViewModel and injected in the ViewModel I want to open the dialog.
Here is the code I'm using to call the Dialog:
public void ShowDialog()
{
_dialogService.ShowDialog("DiscardPopup", CloseDialogCallback);
}
void CloseDialogCallback(IDialogResult dialogResult)
{
var goBack = dialogResult.Parameters.GetValue<bool>("GoBack");
if (goBack)
NavigationService.GoBackAsync();
}
If the user taps over the "Yes label", I execute this command:
YesCommand = new DelegateCommand(() => YesTapped());
private void YesTapped()
{
IDialogParameters pa = new DialogParameters();
pa.Add("GoBack", true);
RequestClose(pa);
}
If the user taps over the "No label", I simply call:
NoCommand = new DelegateCommand(() => RequestClose(null));
The "problem" is when the ShowDialog is fired, the DiscardPopup is taking up to 3 seconds to show up.
Is there a way to make it faster?
The same happens with the TapCommands, 2 - 3 seconds when the RequestClose is invoked.
Without actual code telling you exactly what the issue is, is going to be best guess. Based on your feedback to my comments above I would suggest the following:
Try displaying the dialog on a test page that doesn't have a complex layout. My guess is that you won't see such a long load time. If that's the case this would point to your layout being overly complex and that the lag time is due to the device struggling to re-render the View
Try using Prism.Plugin.Popups. You'll need to initialize Rg.Plugins.Popup and register the DialogService. You can see docs on that at http://popups.prismplugins.com
Redux seems to be a very nice architecture for mobile app development. However, mobile apps have some features that are not common for web apps.
In my case, I would like to start long polling /monitoring location/tracking file system (any action that watches some external state) after the start of some particular screen and stop when the screen is closed.
Let's say we have a function, that can emit multiple events over time.
Stream<Event>monitor();
I would like to listen to the function only when some particular screen is active.
What is the best way of doing that?
Suppose you have 3 pages: 'PageHome.dart', 'Page1.dart', 'Page2.dart'.
Create another dart file 'GlobalVariables.dart', create a class gv inside this file, create static redux 'stores' for the three pages.
create static var strCurPage in gv.
suppose each page has a variable that is to be changed by an external event, declare them in gv as static var also.
Codes in GlobalVariables.dart:
import 'package:redux/redux.dart';
enum Actions {
Increment
}
// The reducer, which takes the previous count and increments it in response to an Increment action.
int reducerRedux(int intSomeInteger, dynamic action) {
if (action == Actions.Increment) {
return intSomeInteger + 1;
}
return intSomeInteger;
}
class gv {
static Store<int> storePageHome =
new Store<int>(reducerRedux, initialState: 0);
static Store<int> storePage1 =
new Store<int>(reducerRedux, initialState: 0);
static Store<int> storePage2 =
new Store<int>(reducerRedux, initialState: 0);
static String strCurPage = 'PageHome';
static String strPageHomeVar = 'PageHomeInitialContent';
static String strPage1Var = 'Page1InitialContent';
static String strPage2Var = 'Page2InitialContent';
}
Import 'GlobalVariables.dart' in all other dart files.
Before navigate to a new page, e.g. from PageHome to Page1, set:
gv.strCurPage = 'Page1';
Inside your monitor function, if an external event happens, say, change the values of the variables in Page1 and Page2 (But user currently navigating in Page1):
void thisFunctionCalledByExternalEvent(strPage1NewContent, strPage2NewContent) {
gv.strPage1Var = strPage1NewContent;
gv.strPage2Var = strPage2NewContent;
if (gv.strCurPage == 'Page1') {
// Dispatch storePage1 to refresh Page 1
storePage1.dispatch(Actions.Increment);
} else if (gv.strCurPage == 'Page2') {
// Dispatch storePage2 to refresh Page 2
storePage2.dispatch(Actions.Increment);
} else {
// Do not need to refresh page if user currently navigating other pages.
// so do nothing here
}
}
I don't know whether this is the best way, but using redux and GlobalVariables.dart, I can:
know which page the user is currently navigating.
change the content of a page even when the user is not at that page when the event fires. (But the content will be shown when the user navigate to that page later)
force the user to go to a specific page no matter which page the user is navigating, when the event fires.
EDIT 4:
EDIT 3
EDIT 2
string currentWindow = driver.CurrentWindowHandle;
driver.SwitchTo().Window("");
string childTitle = driver.Title;
driver.SwitchTo().Window(currentWindow);
string parentTitle = driver.Title;
the above code gives me the same title for parent window or child window.
EDIT:
<a id="ctl00_ctl00_Features_ctl03_lnkPage" class="title" target="_blank" href="websiteaddress">Stay Around</a>
how to verify the title of a newly window open and once i verified then close the opened new window?
so in my page I have a link and click on the link and it opens a new window and now I am not sure how to verify the title of that window.
here is what i have done so far.
GoToMysiteUrl();
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
//it opens a new window
now i want to switch focus on the new window and verify the title and close the new window
back to the previous window.
The piece that most people miss when dealing with popup windows in IE is that a click on an element is asynchronous. That is to say, if you check the .WindowHandles property immediately after a click, you may lose the race condition, because you're checking for the existence of a new window before IE has had the chance to create it, and the driver has had a chance to register it exists.
Here's the C# code I would use to perform the same operation:
string foundHandle = null;
string originalWindowHandle = driver.CurrentWindowHandle;
// Get the list of existing window handles.
IList<string> existingHandles = driver.WindowHandles;
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
// Use a timeout. Alternatively, you could use a WebDriverWait
// for this operation.
DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(5));
while(DateTime.Now < timeout)
{
// This method uses LINQ, so it presupposes you are running on
// .NET 3.5 or above. Alternatively, it's possible to do this
// without LINQ, but the code is more verbose.
IList<string> currentHandles = driver.WindowHandles;
IList<string> differentHandles = currentHandles.Except(existingHandles).ToList();
if (differentHandles.Count > 0)
{
// There will ordinarily only be one handle in this list,
// so it should be safe to return the first one here.
foundHandle = differentHandles[0];
break;
}
// Sleep for a very short period of time to prevent starving the driver thread.
System.Threading.Thread.Sleep(250);
}
if (string.IsNullOrEmpty(foundHandle))
{
throw new Exception("didn't find popup window within timeout");
}
driver.SwitchToWindow(foundHandle);
// Do whatever verification on the popup window you need to, then...
driver.Close();
// And switch back to the original window handle.
driver.SwitchToWindow(originalWindowHandle);
Incidentally, if you're using the .NET bindings, you have access to a PopupWindowFinder class in the WebDriver.Support.dll assembly, which uses a very similar approach to the locating popup windows. You may find that class meets your needs exactly, and can use it without modification.
GoToMysiteUrl();
IWebElement addtoList = driver.FindElement(By.XPath(_pageName));
addtoList.Click();
// Post above operation a new window would open as described in problem
// Get hold of Main window's handle
string currentWindow = Driver.CurrentWindowHandle;
// Switch to the newly opened window
Driver.SwitchTo().Window("Your Window Name");
// Perform required Actions/Assertions here and close the window
// Switch to Main window
Driver.SwitchTo().Window(currentWindow);