I have an issue which I couldn't figure out for hours,
I have a fragments inside an activity, and sometimes I call the fragment with the codes below:
newsFeedFragment fragment = new newsFeedFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.hide(getSupportFragmentManager().findFragmentById(R.id.fragment_container));
fragmentTransaction.hide(getSupportFragmentManager().findFragmentByTag("notifications_fragment"));
fragmentTransaction.show(getSupportFragmentManager().findFragmentByTag("news_feed_fragment"));
fragmentTransaction.addToBackStack(null);
fragment.onResume();
fragmentTransaction.commit();
As the onResume is not called while showing the fragments I use "fragment.onResume();" in the code below. And when the fragment is shown, the onResume is called. However, I try to update a variable in the onResume method, but it is not updated with the code below. When ever the onResume is called, I see "1" as the result in the log, however I was expecting it to increase by 1 every time. Is there a way to make it work?
int refreshNotificationVar = 0; //in the main class
#Override
public void onResume(){
super.onResume();
refreshNotificationVar = refreshNotificationVar + 1;
System.out.println(refreshNotificationVar);
}
You cannot rely on instance variables in case of onPause and onResume; you can rely on static variables to some extent; you can use onSaveInstanceState; or use a Singleton class to store variable values; or store in shared preferences; or maybe store in a database depending on your needs. In your case, I would use a Singleton class to store the values and get/set them in onPause/onResume.
Related
I was documenting my code and I wanted to link another method in the same file
I want to refer to that method in a comment so anyone reading my comment can directly jump to that method where my comment refers
Method where I am documenting and I want to link to a method named toggleFavorite in the same file
// To avoid code duplication in [toggleFavorite] method
void _toogleFav(newStatus) {
isFavorite = newStatus;
notifyListeners();
}
This is what my toggleFavorite returns in case you need it
Future<void> toggleFavorite() async {
What I want
Exactly I want this word in my comment [toggleFavorite] to work as a link when I press this I get redirected to this method wherever it is created or used
Use triple /// and [] around the method
/// To avoid code duplication in [toggleFavorite] method
void _toogleFav(newStatus) {
isFavorite = newStatus;
notifyListeners();
}
I want to test a method that is responsible for a button tap (let's call it onButtonTap()), one of the first methods is a call to static method from utils file, that returns true of false, depending on set android/ios permissions (or allows user to change permissions by showing dialog that can open application settings). Let's call it checkOrRequestPermissions(). This makes everything behind that code untestable, as I don't know how to test it - I can't mock this class because:
It's not injected anywhere - it's inside utils file
It's static
So for better visualization lets go like this:
Code from file I want to test:
Future<void> onButtonTap(BuildContext context) async {
bool isGranted = await PermissionsUtil.checkOrRequestPermissions([some_args]);
// CODE_A - some code I want to test
}
Code inside PermissionsUtil:
class PermissionsUtil{
static Future<bool> checkOrRequestPermissions([some_args]){
// code for permissions
}
}
So my questions are:
Is there any way I could mock checkOrRequestPermissions() to simply return given value?
How could I make this code testable?
My problem is with how to stop firing unrelated event of event bus. as I got this solution for Dialog box.
but it does not work in case of where one instance already initialize and try to create new instance of same class.
Just example: A below scroll panel has handler initialized. it used for document preview.
class TestScroll extends ScrollPanel
{
public TestScroll(){
}
implemented onload()
{
// eventBus.addHandler code here.
//here some preview related code
}
unload() method
{
//eventBus remove handler code
}
}
This preview has some data which contains some links that open different preview but with same class and different data structure,
Now The problem is like onUnload ( which contains code of remove handler) event does not load , because other panel opened. that does not mean previous panel unload.
So in that case, twice event handler registered. when one event fired then other event also fired.
Due to that, Preview 1 data shows properly, but after that Preview2 opened and when I close it, I find Preview1=Preview2.
so how can I handle such situation?
As per no of instance created each event fired. but I have to check some unique document id with if condition in event itself.
is there any other ways to stop unrelated event firing?
Edit:
public class Gwteventbus implements EntryPoint {
int i=0;
#Override
public void onModuleLoad() {
TestApp panel=new TestApp();
Button button=new Button("Test Event");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
TestApp panel=new TestApp();
int j=i;
new AppUtils().EVENT_BUS.fireEventFromSource(new AuthenticationEvent(),""+(j));
i++;
}
});
panel.add(button);
RootPanel.get().add(panel);
}
}
public class AppUtils {
public static EventBus EVENT_BUS = GWT.create(SimpleEventBus.class);
}
public class TestApp extends VerticalPanel{
String testString="";
public TestApp( ) {
AppUtils.EVENT_BUS.addHandler(AuthenticationEvent.TYPE, new AuthenticationEventHandler() {
#Override
public void onAuthenticationChanged(AuthenticationEvent authenticationEvent) {
System.out.println("helloworld"+authenticationEvent.getSource());
}
});
}
}
These are wild guesses as it's difficult to really answer it without code and a clear description.
I'm guessing you have one eventbus for all the panels. So when you register a handler it is registered with that one eventbus. In case you fire an event from one of the panels to the eventbus all panels will receive the event.
To fix this you can either create a new eventbus per panel or check who fired the event with event.getSource().
If this doesn't make sense you probably are reusing a variable or use a static variable which actually should be a new instance or none static variable.
You can use the GwtEventService-Library to fire specific events over a unique domain and every receiver that is registered at this domain receives that events then. You can handle as many different events/domains as you want.
In order to remove a handler attached to the EventBus, you must first store a reference to the HandlerRegistration returned by the addHandler method:
HandlerRegistration hr = eventBus.addHandler(new ClickHandler(){...});
Then you can remove the handler with the removeHandler method:
hr.removeHandler();
A final note worth mentioning is that when using singleton views, like is typical with MVP and GWT Activities and Places, it is best practice to make use of a ResettableEventBus. The eventBus passed to an activity's start() is just such a bus. When the ActivityManager stops the activity, it automatically removes all handlers attached to the ResettableEventBus.
I would strongly recommend reading the GWT Project's documentation on:
Activities and Places
Large scale application development and MVP
I'm trying to use a custom widget: gwtupload with it's custom handlers. The handlers are defined as interfaces, as in, Interface.OnCustomEventHandler and the method, according to the API, that I want to use is like this code, but I'm not sure how to implement this with uiBinder.:
void onCustomEvent (Interface interface)
Normally for uiBinder I use this code for the regular gwt widgets:
#Widget widget;
#UiHandler("widget")
void onClick(ClickEvent event){
//Handle the event processing here.
}
Presently, when I try this,
#UiHandler("widget")
void onCustomEvent(ICustomInterface customInterface){
...
I get this null pointer exception:
[ERROR] Generator 'com.google.gwt.uibinder.rebind.UiBinderGenerator' threw an exception while rebinding '...ViewImpl.ViewImplUiBinder'
java.lang.NullPointerException
Here is the new code I tried:
public class MUpld extends Composite {
private static MUpldUiBinder uiBinder = GWT.create(MUpldUiBinder.class);
interface MUpldUiBinder extends UiBinder<Widget, MUpld> {
}
#UiField MultiUploader uploader;
public MUpld() {
final IUploader.OnFinishUploaderHandler onFinishUploaderHandler = new IUploader.OnFinishUploaderHandler() {
#Override
public void onFinish(IUploader iUploader) {
if (uploader.getStatus() == Status.SUCCESS){
System.out.println("In the onFinish method!");
}
}
};
initWidget(uiBinder.createAndBindUi(this));
uploader.addOnFinishUploadHandler(onFinishUploaderHandler);
}
}
In the debugger, I saw the handler get attached to the uploader widget I defined, but then the current uploader became a different one once the code moved out of this class. I tried using the final modifier, as that is the only way I know to get a variable into an inner class, but gwt would complain with:
[ERROR] com.cdg.complexityCalculator.client.view.MUpld has no default (zero args) constructor.
To fix this, you can define a #UiFactory method on the UiBinder's owner, or annotate a constructor of MUpld with #UiConstructor.
I wasn't able to get either of those options to work, but I realized I had the last two lines of code switched, so I changed it to what I have now and the handler loaded up with the correct object.
Any ideas as to how to get this to work? Everything else is in place, I just need a way to capture this event after my servlet has finished processing.
When I changed the last two lines of code, the handler got loaded properly. Now the objects are being created with the handler binding to the correct object.
initWidget(uiBinder.createAndBindUi(this));
uploader.addOnFinishUploadHandler(onFinishUploaderHandler);
I had to wait until the uiBinder created the instance of the uploader widget, then I was able to add the handler to it.
One of the tricks I've learned is to add a handler in the constructor for a composite widget you create, that way it's more of an encapsulated component. It handles it's own events.
I am building an image Editor as an Eclipse plugin.
I would like to use the Properties view to view & edit properties of the model underneath the image. Accordingly I am calling ..
getSite().setSelectionProvider( this );
.. within createPartControl, and implementing the ISelectionProvider interface in my EditorPart implementation, so that the model is returned as the selection (which must therefore implement the ISelection interface).
The next step is for the Editor to implement IAdaptable to supply an adapter for the selected object.
My problem however is that getAdapter is never called with IPropertySource.class, and therefore the Properties View never gets what it needs to make sense of the image model.
Your help is much appreciated.
M.
The answer in the end broke down into a few pieces ...
1.) When your selection does change (if a user has zoomed into the image, for example) be sure to tell Eclipse this. It won't happen otherwise.
2.) When sending your SelectionChangedEvent, wrap up your IAdaptable in a StructuredSelection object - otherwise the Properties view will ignore it.
This boiled down to the following method
public void fireSelectionChanged()
{
final SelectionChangedEvent event = new SelectionChangedEvent( this, new StructuredSelection( this ) );
Object[] listeners = selectionChangedListeners.getListeners();
for (int i = 0; i < listeners.length; ++i)
{
final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
SafeRunnable.run(new SafeRunnable() {
public void run() {
l.selectionChanged( event );
}
});
}
}
... on an class that implemented ISelectionProvider & IAdaptable.
M.