I'm building a mapping app using the OpenStreetMap API. When I add a Marker object myMarker (green dot in the picture) as an overlay to the map, in default an (empty) info-window pops up when you tap on the object. I don't want this to happen.
I tried de-activating this popping up by entering myMarker.setInfoWindow(null), but that didn't fix it. Please your advice.
I solved it using hideInfowindow() method and returning true.
For Google Maps:
public void onMapReady(#NonNull GoogleMap googleMap) {
map = googleMap;
map.setOnMarkerClickListener(marker -> {
marker.hideInfoWindow();
//return true instead of false
return true;
});
}
For OpenStreetMap when map is loaded:
mapObject.setOnMarkerClickListener(marker -> {
marker.hideInfoWindow();
//return true instead of false
return true;
});
Related
I'm using barteksc pdf viewer library to load pdf in my application.
pdfView = findViewById(R.id.pdfView);
pdfView.fromAsset(getResources().getString(R.string.pdfname))
.enableDoubletap(true)
.enableSwipe(true)
.defaultPage(pageNumber)
.onPageChange(mainreading.this)
.pageFitPolicy(FitPolicy.WIDTH)
.pageFling(true)
.linkHandler(null)
.enableAnnotationRendering(true)
.swipeHorizontal(true)
.scrollHandle(new DefaultScrollHandlenew(mainreading.this))
.enableAntialiasing(true)
.load();
}
I want pdf to start scroll automatically when user click the button of volume up and down buttons to start stop. I tried with below code while wrapping it in the handler with handler.performClick(); but it shows blank screen while scrolling up and down.
scrollbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pdfView.scrollTo(0, pdfView.getScrollY() + 24);
}
});
Example :
https://play.google.com/store/apps/details?id=com.emptysheet.pdfreader_autoscroll&hl=en&gl=US
I want to make as like this. Can anyone help please.
Also tried with this. But it shows blank page after some scrolls.
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_DOWN) {
pdfView.scrollTo(0, pdfView.getScrollY() -24);
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
pdfView.scrollTo(0, pdfView.getScrollY() + 24);
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
You can simply use this PDF viewer from github.
It's based on the same 'barsteksc' pdf viewer with the feature to jump to any pages.
It's MagicalPdfViewer and you can use 'jumpTo(pageNo)' method to simply jump to the specific page. It also gives you the option to animate to the specific page with the same method, just pass 'true' as the 2nd parameter.
Moreover, if you pass the values like '-1' and 'bigger than pageNo', It will automatically scroll to the 0 & last page respectively.
Give it a try & let me know if you got what you wanted.
I'm working on an app that uses a MapView instance called map. At a certain point I want to know if the map has been touched. To that purpose Android Studio generated this boolean return callback method (see below) for the OnTouchListener.
MapView map;
map = findViewById(R.id.view_map);
map.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch (View v) {
return false;
}
});
As you can see, unlike in a simple OnClickListener, you are apparently not free to write the method that should follow a touch event. That method appears to be fixed at return false. You cannot change it to e.g. a void method.
What is the purpose of that return? To where/what will false be returned? Is it perhaps stored in the object map, as a field of the MapView class? If I knew, I could initialize that field/variable to true, wait for the OnTouchListener to change it to false, and then use that information elsewhere in the app (e.g. to suspend the app's instruction to continuously center the map on the current GPS position).
Within the Acumatica 19.201.0070 framework I have created a custom processing page that utilizes PXFilteredProcessing with the old style processing UI public override bool IsProcessing => false; I have defined a cancel button (below) that will clear the graph and set some values of the processing filter.
public PXCancel<NPMasterSubGeneratorFilter> Cancel;
[PXCancelButton()]
protected virtual IEnumerable cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}
This works perfectly fine except for a single use case, after processing results are shown if the user then presses the cancel button the corresponding action is never hit. ( My fellow office devs state that core Acumatica processing pages seem to operate the same. )
Setting of the processing delegate is within the filter RowSelected event.
GeneratedSubs.SetProcessDelegate(list => CreateSubaccounts(list, row));
I have implemented a few iterations of my processing method but the current is below.
protected virtual void CreateSubaccounts(List<NPGeneratedSub> subs, NPMasterSubGeneratorFilter filter)
{
if (filter.NewSegment ?? false)
{
try
{
SegmentMaint segGraph = PXGraph.CreateInstance<SegmentMaint>();
segGraph.Segment.Update(segGraph.Segment.Search<Segment.dimensionID, Segment.segmentID>(AADimension.Subaccount, filter.SegmentID.Value));
SegmentValue value = segGraph.Values.Insert(new SegmentValue() { Value = filter.SegmentValue, Descr = filter.Description });
segGraph.Actions.PressSave();
}
catch
{
throw new PXOperationCompletedSingleErrorException(NonProfitPlusMessages.SegmentValueCannotCreate);
}
}
SubAccountMaint subGraph = PXGraph.CreateInstance<SubAccountMaint>();
NPSubAccountMaintExtension subGraphExt = subGraph.GetExtension<NPSubAccountMaintExtension>();
subGraphExt.save.ConfirmSaving = false;
Sub newSub;
bool errored = false;
foreach (NPGeneratedSub sub in subs)
{
PXProcessing<NPGeneratedSub>.SetCurrentItem(sub);
try
{
newSub = subGraph.SubRecords.Insert(new Sub() { SubCD = sub.SubCD, Description = sub.Description });
subGraph.Save.Press();
subGraph.Clear();
PXProcessing<NPGeneratedSub>.SetProcessed();
}
catch (Exception e)
{
PXProcessing<NPGeneratedSub>.SetError(e);
errored = true;
}
}
if (errored)
{
throw new PXOperationCompletedWithErrorException();
}
}
What needs to be adjusted to allow the buttons action to be triggered on press after processing results have been returned?
After stepping through the javascript I discovered that it wasn't sending a request to the server when you click the cancel button on this screen after processing. The reason is because SuppressActions is getting set to true on the Cancel PXToolBarButton. I compared what I was seeing on this screen to what was happening on screens that work correctly and realized that Acumatica is supposed to set SuppressActions to true on the Schedule drop down PXToolBarButton but for some reason, on this screen, it is incorrectly setting it to true on whatever button is after the Schedule drop down button.
I looked through the code in PX.Web.UI and it looks like they set SuppressActions to true when a drop down button is disabled and PXProcessing adds a FieldSelecting event to the Schedule button which disables the button after you click process. However, I didn't notice any obvious issues as to why the code would be setting it on the wrong PXToolBarButton so someone will likely need to debug the code and see what's going on (we are unable to debug code in PX.Web.UI.dll).
I tried commenting out the other grids in the aspx file that aren't related to the PXProcessing view and this resolved the issue. So my guess would be that having multiple grids on the PXProcessing screen somehow causes a bug where it sets SuppressActions on the wrong PXToolBarButton. However, since the multiple grids are a business requirement, removing them is not a solution. Instead, I would suggest moving all buttons that are after the schedule button to be before the schedule button. To do this, just declare the PXActions before the PXFilteredProcessing view in the graph.
Please try this
Override IsDirty property
Use PXAction instead of PXCancel
Add PXUIField attribute with enable rights
action name should start from lowercase letter
delegate name should start from uppercase letter
see code below
public override bool IsDirty => false;
public override bool IsProcessing
{
get { return false;}
set { }
}
public PXAction<NPMasterSubGeneratorFilter> cancel;
[PXUIField(MapEnableRights = PXCacheRights.Select)]
[PXCancelButton]
protected virtual IEnumerable Cancel(PXAdapter adapter)
{
NPMasterSubGeneratorFilter row = Filter.Current;
if (row != null)
{
this.Clear();
Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentID>(Filter.Current, row.SegmentID);
if (!(row.NewSegment ?? false)) Filter.SetValueExt<NPMasterSubGeneratorFilter.segmentValue>(Filter.Current, row.SegmentValue);
}
return adapter.Get();
}
I'm creating my own IntelliSense Presenter, since Visual Studio2012 support change theme, so I want my background color of the presenter can be auto-changed when the theme been changed. Is there a way to track the theme changes event, or get the current color theme of the Visual Studio?
Yes, this is possible. I had to solve a similiar issue with one of my extensions...
The current theme is stored in the Windows Registry; so I implemented the following utility class.
public enum VsTheme
{
Unknown = 0,
Light,
Dark,
Blue
}
public class ThemeUtil
{
private static readonly IDictionary<string, VsTheme> Themes = new Dictionary<string, VsTheme>()
{
{ "de3dbbcd-f642-433c-8353-8f1df4370aba", VsTheme.Light },
{ "1ded0138-47ce-435e-84ef-9ec1f439b749", VsTheme.Dark },
{ "a4d6a176-b948-4b29-8c66-53c97a1ed7d0", VsTheme.Blue }
};
public static VsTheme GetCurrentTheme()
{
string themeId = GetThemeId();
if (string.IsNullOrWhiteSpace(themeId) == false)
{
VsTheme theme;
if (Themes.TryGetValue(themeId, out theme))
{
return theme;
}
}
return VsTheme.Unknown;
}
public static string GetThemeId()
{
const string CategoryName = "General";
const string ThemePropertyName = "CurrentTheme";
string keyName = string.Format(#"Software\Microsoft\VisualStudio\11.0\{0}", CategoryName);
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName))
{
if (key != null)
{
return (string)key.GetValue(ThemePropertyName, string.Empty);
}
}
return null;
}
}
Okay; this just helps to figur out the current settings... listening for the theme changed notification is a bit trickier. After your package is loaded, you must obtain an IVsShell instance via the DTE; once you have this object you can utilize the AdviceBroadcastMessages method to subscribe for event notifications. You have to provide an object whose type implements the IVsBroadcastMessageEvents interface...
I don´t want to post the whole implementation, but the following lines might illustrate the key scenario...
class VsBroadcastMessageEvents : IVsBroadcastMessageEvent
{
int IVsBroadcastMessageEvent.OnBroadcastMessage(uint msg, IntPtr wParam, IntPtr lParam)
{
const uint WM_SYSCOLORCHANGE = 0x15;
if (msg == WM_SYSCOLORCHANGE)
{
// obtain current theme from the Registry and update any UI...
}
}
}
Consider implementing IDisposable on that type as well, in order to be able to unsubscribe from the event source, when the package gets unloaded.
This is how I subscribe for event notifications...
class ShellService
{
private readonly IVsShell shell;
private bool advised;
public ShellService(IVsShell shellInstance)
{
this.shell = shellInstance;
}
public void AdviseBroadcastMessages(IVsBroadcastMessageEvents broadcastMessageEvents, out uint cookie)
{
cookie = 0;
try
{
int r = this.shell.AdviseBroadcastMessages(broadcastMessageEvents, out cookie);
this.advised = (r == VSConstants.S_OK);
}
catch (COMException) { }
catch (InvalidComObjectException) { }
}
public void UnadviseBroadcastMessages(uint cookie)
{
...
}
}
Keep the value of the cookie parameter; you´ll need it to successfully unsubscribe.
Hope that helps (-:
Just wanted to put an update just in case anyone else comes along.. #Matze and #Frank are totally right.. However in VS 2015.. they added a easy way to detect the theme change. So you need to include PlatformUI an dyou get a super easy event
using Microsoft.VisualStudio.PlatformUI;
....
//Then you get an event
VSColorTheme.ThemeChanged += VSColorTheme_ThemeChanged;
You should make sure your control is disposable so you can unsubscribe from the event...
BONUS!
It also give you easy access to the colors.. even if the user has changed them from the default .. so you can do stuff like this in when set your colors
var defaultBackground = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowBackgroundColorKey);
var defaultForeground = VSColorTheme.GetThemedColor(EnvironmentColors.ToolWindowTextColorKey);
For VS 2015 this has changed, the solution #Matze has still works but you need to update the GetThemeId() function to check for the version and if it's 14.0 (VS2015) look in a different place in the registry. The way the value is stored has changed also, it's still a string but now contains other values seperated by a '*'. The theme guid is the last value in the list.
if (version == "14.0")
{
string keyName = string.Format(#"Software\Microsoft\VisualStudio\{0}\ApplicationPrivateSettings\Microsoft\VisualStudio", version);
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(keyName))
{
if (key != null)
{
var keyText = (string)key.GetValue("ColorTheme", string.Empty);
if (!string.IsNullOrEmpty(keyText))
{
var keyTextValues = keyText.Split('*');
if (keyTextValues.Length > 2)
{
return keyTextValues[2];
}
}
}
}
return null;
}
I have QLPreviewController up and running but I'm using PresentModalViewController() to show the QLPreviewController directly. For reasons beyond explanation, I would like to have my own UIViewController which will create its own view and within that view I would like to use the QLPreviewController. Should be easy I thought, but the code below just does nothing. The QLPreviewControllers ViewDidAppear never gets called. (In my example below, PreviewController inherits from QLPreviewController and encapsulates delegate, preview item and source).
Can somebody explain what is wrong with the code below (besides the fact that it is pointless :-))?
Oh, yeah: in my test scenario, I present the controller below modally. It shows up but witout the preview.
public class OuterPreviewController : UIViewController
{
public OuterPreviewController (QLPreviewControllerDataSource oDataSource) : base()
{
this.oDataSource = oDataSource;
}
private PreviewController oPreviewController;
private QLPreviewControllerDataSource oDataSource;
public override void LoadView ()
{
this.View = new UIView();
this.View.Frame = new RectangleF(0, 0, 500, 500);
this.View.BackgroundColor = UIColor.Red;
}
public override void ViewDidAppear (bool animated)
{
// Code execution comes her. No errors, no issues.
base.ViewDidAppear (animated);
this.oPreviewController = new PreviewController();
this.oPreviewController.DataSource = this.oDataSource;
// Preview controller's view is added but it never shows up.
this.View.AddSubview(this.oPreviewController.View);
this.oPreviewController.View.Frame = this.View.Frame;
this.oPreviewController.View.Center = this.View.Center;
}
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
return true;
}
}
Found a solution by coincidence today: all ReloadData() on the preview controller and magically it will show its contents.
This allows to add a QLPreviewController to an existing view as a subview and embed a preview. It also gets you rid of the toolbar which contains the open in menu.