Giter Club home page Giter Club logo

mapcompose's People

Contributors

cwsiteplan avatar nohus avatar p-lr avatar timpushkin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mapcompose's Issues

redrawTiles() sometimes clears the map and does not redraw tiles

I am currently investigating an issue where redrawTiles() sometimes does not trigger a redraw, only clears the map.

In a successful redraw, visibleTilesFlow gets set to null, that gets collected, then to the new VisibleTiles, which gets collected and redrawn.
Sometimes, visibleTilesFlow gets sets to null, and then VisibleTiles, as normal, but neither are collected. For some reason the visibleTilesFlow emissions are ignored by the collector. I am still investigating why, but maybe you have an idea.

This only seems to happen when redrawTiles() is called quickly after a previous call, maybe up to 2 seconds. It may just be that it can only happen when the tiles are still loading when another redrawTiles() call is made.

Lazy loading reuses marker composables with the same ID

When using RenderingStrategy.LazyLoading, if I add a marker, let it be displayed for a while, then remove it and add another marker with the same ID, the composable from the removed marker appears on the specified coordinates instead of the new one.

This doesn't happen in any of the following cases:

  1. If I use the default rendering strategy.
  2. If I add and remove the first marker immediately.
  3. If I add a delay between removing the old marker and adding the new one. The higher the delay, the less are the chances for this to happen, but it seems like it should be 10 ms at least.

I reproduced the bug in the demo app here -- on tap A should disappear and B should appear, but in reality, A appears again.

Access `minScale` property of `MapState`

MapState has public property maxScale but does not have minScale, even though ZoomPanRotateState has it (as a private property). It would be great to make it accesible for reading from MapState as it can be set to some non-trivial values by Fit or Fill MinimumScaleModes. Personally I need this for some scale-dependent animations to normalize the scale.

Markers are clipped to a circle

Composables added as markers are not displayed fully. Instead they are clipped to a circle shape.

With this composable:

Box(Modifier.size(20.dp).background(Color.Black))

The bottom shape is how it displays normally, and the upper shape is the same composable showing as a marker:

image

Marker and map blinks and shifts with BottomNavigationView

I am having a visual problem when I want to display a map while having a BottomNavigationView also displayed (see video). The points and map fragments seem to shift as if their position was recalculated.

22-02-15-16-04-12.2.mp4

The problem disappears if you change the visibility of the BottomNavigationView to GONE.

I specify that I work in a ComposeView in fragment xml because my application does not implement Compose. So I have :

Activity {
	FragmentContainer {
		MyFragment {
			ComposeView {
				MapCompose {}
			}
		}
	}
	BottomNavigationView {}
}

minSdkVersion

Is there a reason the minSdkVersion is set to 24? The library works fine at 21, and having it at 24 requires using an override for apps that have a lower minSdkVersion:

AndroidManifest.xml

<uses-sdk tools:overrideLibrary="ovh.plrapps.mapcompose" />

Zoom In at highest Zoomlvl.

Loving this library. Is there a way at the highest scale of the map to continue to zoom into the image or is this functionality not supported.

When I am getting to a zoom level of 4 in my application I can not go further zooming in on this level to inspect each tile in depth, would I need to somehow take my tiling library and have it supply a further zoom level to achieve this?

*Isn't really an issue more of a question.

Seamless tile loading

Currently tile loading is very visible for the user. When the map is scrolled to a new tile, it's always empty, has to load in, and them run the fade-in animation. I would expect to be able to scroll without ever seeing any loading (unless scrolling very fast), especially when tiles are locally-cached and don't need to load from the network.

The solution is to not only load visible tiles, but also have a margin of off-screen tiles loaded. This margin could be configurable (and default to 0, if you think the current behavior should stay the default). Also, when a tile is loaded off-screen, it should not run the fade-in animation.

I'd be happy to implement this myself, but there are significant changes happening on the layers branch, so there might be conflicts. What do you think?

Map is buggy when used in a dynamic size ComposeView

I have reproduced a bug on the branch bug_reproduction_composeview. I am not sure what exactly causes it, but it only happens when the ComposeView with the map in an XML layout has parent-dependent sizing (either match_parent, or 0dp with constraints in a ConstraintLayout). In the included XML file, if you either set the layout_width of the ComposeView to a constant value, the issue is gone. If you set the width of the parent FrameLayout to a constant value, the issue is also gone.

Video below (I am attempting to scroll):

bug.mp4

[Feature Request] Suspending version of TileStreamProvider

Because getTileStream() in the TileStreamProvider is not suspending, I need to use runBlocking to use my suspending implementation, even though in the library, getTileStream() is called from a suspending context anyway:

tileStreamProvider = { y, x, zoom ->
    runBlocking {
        getMapTile(y, x, zoom)
    }
}

It would be nice to be able to provide a suspending implementation directly, without having to use runBlocking. This is very minor but would make the interface a bit nicer in my opinion.

Markers lazy loading

I am seeing performance issues when using markers:

I/Choreographer: Skipped 409 frames!  The application may be doing too much work on its main thread.

This is when adding markers.
Spent 1.64s inside MarkerComposer.kt, out of which 333ms in my marker composable.

I have 200 markers on the map, but I am doing marker generalization, so more markers appear when you zoom in, but because you are viewing a smaller area the total amount of markers on screen rarely exceeds 5. However it seems the library is always rendering all of them? The problem is much worse the more I zoom in.

Confusing map levels explanation image

The library assumes each level is twice as big as the previous one. After a 2 tiles wide level, the next level will be 4 tiles wide, and the next will be 8 tiles wide. However the explanation image in the documentation shows a 2 tiles wide level being followed with a 3 tiles wide level, and then 5 tiles wide level, which is not how the library works, and a source of confusion on how should I be generating my tiles.

Disabling user gestures

Is there an intended way of displaying a static map (with no user gestures / control)? I can of course prevent the user from interacting with the Composable in a number of less or more hacky ways, but I'm wondering if there is an intended solution. There is the disableRotation() method, so I was looking for something like disableScroll(), disableZoom(), and disableGestures().

Setting the initial map scroll position

Current code:

MapState(4, 4096, 4096).apply {
    viewModelScope.launch {
        snapScrollTo(0.5, 0.5, 1f)
    }
}

This is a bit verbose, and also requires launching a coroutine, which is not possible/convenient in all contexts.
Another issue is that such a created map requests tiles for the top-left map corner, which is extra HTTP requests that are useless. (And just extra work that isn't needed.)

Map padding

Currently the map cannot be scrolled any further when its end reaches the corresponding end of the screen. For example, if I zoom in I can scroll left only until the left end of the map reaches the left end of the display.

The problem is that it is not very convenient for a user to see some part of the map that is really close to the map's border, especially when there is some other UI on top of the map close to the corresponding end of the screen.

The solution might be to add an ability to control what portion of the screen can the map's border be additionally scrolled after its border reaches the corresponding end of the screen. For example, 0 would be the current behavior, 0.5 would let the border reach the center of the screen, and 1 would let it reach the opposite end of the screen.

The problem that I see with this solution is that it will allow the map to be scrolled even when it is fully zoomed out, so maybe some additional restrictions are required.

Layers support

I propose a layers feature that would allow to display multiple tile maps at the same time. Higher layers would use images with alpha so that the lower layers are still visible. Individual layer opacity would also be configurable.

Use cases

  • Normal tile layer for a world map + weather tile layer with clouds that renders on top
  • Ground level tile layer + layer for every architectural level on top
  • Server-side data overlays over the base map
  • Animated switching of map types/styles (add both maps as 2 layers, animate alpha, remove old layer)

Usage
From the API perspective, this could be a version/replacement of TileStreamProvider that returns multiple tiles (List<InputStream>). There would also need to be a way to control a layers' alpha; this could be either defining the layers and their alpha separately, or as part of the TileStreamProvider.

There is also a case to be made that this is something the client code could do, and not a library feature: blend the multiple tiles yourself and provide the composite tile to TileStreamProvider. The issue with that with the current API is that TileStreamProvider wants an InputStream, which is difficult to work with if the client code was to generate tiles dynamically. Presumably the tiles were already read from whatever InputStreams and blended into the final Bitmap, so TileStreamProvider would need to work with Bitmaps, not InputStreams.

It would definitely be nicer as a proper library feature though.

For reference, here is the feature in Google Maps SDK: https://developers.google.com/maps/documentation/android-sdk/tileoverlay
In OsmDroid: https://osmdroid.github.io/osmdroid/Map-Sources.html (Can I use more than one tile source at a time? section)

What do you think?

`setScrollOffsetRatio` not working properly

I want to achieve the following effects:

Here is a pin on the map, users can move the map to select any point in the map, including four corners of the map

So I tried adding this line in file SimpleDemoVM.kt of demo module, and I want to achieve the effect similar to setPanLimit(SubsamplingScaleImageView.PAN_LIMIT_CENTER) in SubsamplingScaleImageView:

image

When I run the code, I found that the effect is not like I imagined, especially after I scaled the map, the effect is more outrageous.

So I search for the code in the library to try to find the problem, and I found the following suspicious snippet:

image

But unfortunately, even if I have modified the above code, setScrolloffSetratio still not working properly.

Tile borders are visible

Here is a map displaying fully blue tiles:

image

The expected outcome would be just a blue image, but instead the tiles are clearly visible.

Click event is invoked on overlapped markers

When markers with the same zIndex overlap each other they do it according to the order in which they were added (the most recently added ones are on top). But when I click on a point in which several markers overlap each other the one at the bottom receives the click because it is the first one in the markers list.

I expect the click to be received by the marker on top because it is the one I see when I click on the point.

Remove all markers function

There is a MapState.removeAllLayers() extension function, it would be convinient to also have something like MapState.removeAllMarkers().

[Feature Request] Zooming by double tapping and sliding

Google Maps and other popular map apps have a feature like this (description from Google Maps SDK): "One finger zooming by double tapping but not releasing on the second tap, and then sliding the finger up to zoom out, or down to zoom in". It would be nice to have this gesture available in MapCompose too.

Two fingers tap should be easier to trigger

For now, the gesture has to be almost perfect. The two fingers should tap the screen at almost the same time, not move from even one pixel, and be released altogether.
The gesture detection should be move permissive.

How to use Latitude / Longitude to zoom on a location?

I've managed to display a world map from MapBox using Static Tiles and it's working well.
I would like to display a specific location when I open the map, but I don't get how I'm supposed to do it using Latitude and Longitude. Also I want to be able to zoom out to see the entire world map.
Thank you for your help

ConcurrentModificationException in TileCanvasState

I saw crash in TileCanvasState, in the evictAll() method:

private fun evictAll() {
    val iterator = tilesCollected.iterator()
    while (iterator.hasNext()) {
        val tile = iterator.next() // Here
        iterator.remove()
        tile.recycle()
    }
}

It's a ConcurrentModificationException while calling iterator.next(). It's a crash report from one user so far, but reporting for visibility.

Old tiles used after redrawTiles() is used

There is a bug reproduction demo on this branch.

The demo switches the TileStreamProvider implementation and then calls redrawTiles(). As the tiles are loading, it does so again. This results in the wrong tiles being displayed. I think this may be the cause for #26 too, although I am not sure.

Tilebug.mp4

The number of incorrect tiles is equal to workerCount.

Click listener on the map, e.g. to add marker

It would be a nice feature, to have a click/longclick listener on the map, like in OSMdroid and GMaps. It should be fired when clicking on an empty space in the map and allow access to the click position. A common usecase for this is adding a marker at an empty position.

scrollTo could use a simpler version

In other libraries there is usually a difference between scrollTo() and smoothScrollTo()/animateScrollTo(). In MapCompose there is only the animated version, which requires the use of a SnapSpec animation to achieve an instant move. I would propose to rename scrollTo() to animateScrollTo(), and create a new scrollTo() which is instant. A use case for a non-animated move for me is moving to an initial map position, or restoring the map position when changing the map type (which is a new MapState). Both should be instant, and using a 0-length animation feels like a hack.

The setScroll() method exists, but it has a less nice lower-level API not really suitable for user code.

I am proposing this before v2 comes out which is a breaking change anyway.

Alternatively, it would be nice if MapState accepted an initial scroll position as a constructor argument, but that's a different issue. (I still think this would be good even if MapState did.)

Scale-dependent bitmap filtering

I have added a configuration for bitmap filtering in #15, which makes pixel art style images look much better when scaled in a lot. However I found that it makes them look worse when scaled out a lot...
After some testing I can see that at least for my use case, it would be best to have bitmap filtering disabled for scale > 1, and enabled for scale < 1. I am wondering what is the API for enabling that you'd accept in a PR.

Currently we have this:

fun MapState.setBitmapFilteringEnabled(enabled: Boolean) {
    isBitmapFilteringEnabled = enabled
}

My current idea is to add another method like this, which enables to select the filtering state based on the current map scale:

fun MapState.setBitmapFilteringEnabled(predicate: (scale: Float) -> Boolean)

This would enable my client to do:

state.setBitmapFilteringEnabled { scale -> scale < 1 } 

What do you think?

Can I use it with OSM?

I was searching for a Google map SDK alternative and found this library but am confused as to how I can use it with an OSM.

can someone share any insight? I have read readme many times but cannot understand how I can make it work with OSM.

note I was finding something that works with Openstreet map and Compose

Map padding for camera moves

I need a padding feature where I could set the map's padding for the purpose of camera moves. I have a partially obscured map (by my own UI), and want to scroll the map to various locations, and have them end up centered in the actually visible portion of the map, not the actual center as they do now. This video illustrates the concept in the Google Maps SDK: https://www.youtube.com/watch?v=HSCsdiqNjGo
Of course in Google Maps there is additional UI that is affected, in this case I only mean affecting scrollTo methods.

Would you accept a PR implementing this? In short this would add a new setCameraPadding(...) method to the API, which then the scrollTo family of methods would take into account to offset the scroll.

Zoom fling when double tapping and sliding

Currently zoom fling only happens when zooming with two fingers and not when zooming by double tapping and sliding up or down, which feels inconsistent. For example, Google Maps have the fling animation in both cases.

Tile borders visible when scaled in

This is a separate issue from #5, which wasn't previously obvious because the other issue was showing up at the same time. But now that the other issue is fixed this one can be seen.

When the map is scaled in past 1f, the tiles become blurred – this is expected. However because the tiles are blurred individually and then drawn separately, the blur does not cross tile borders, which makes the tile borders visible:

image

The tiles probably need to be drawn without scaling to a buffer, and then the entire buffer drawn in scaled, or some similar approach.

Layers tiles visibility

No tiles are drawn when scale >= 1. If I initialize the map with scale < 1 it works from the start, but as soon as it is scaled in past 1 tiles disappear. They show up again when it's scaled back.

Cannot scrollTo fully zoomed out map

I would like to scroll the map to the center, zoomed out as far as possible. My minScaleMode is set Fill. I cannot do it, because minScale is not exposed publicly (contrary to maxScale) and so I cannot retrieve it to know what is the target scale I need.

I expected scrollTo(0.5, 0.5, 0f) to work, but it does not: the map correctly zooms out as far as possible, but does not move to the center. It seems the animation is stopped as soon as it hits minScale because it cannot animate the scale any further, even though it still hasn't scrolled to the target position.

Either making scrollTo clamp the provided scale or exposing minScale with a public getter would solve this issue.


Sorry for opening all the issues: The library is amazing and the only one that actually worked properly for my use case after trying a few others. And it using Compose is an additional bonus. Thank you!

When displaying a single level map, I am unable to pan

I'm loving this library :). Great work on it!

I am unable to pan to the bottom/top of the image when I'm zoomed in.
Another thing I noticed: When zoomed out, you'll see that the image isn't centered in the screen, it's shifted towards the bottom.
Annndd one more: Is there anyway I can remove the flicker when zooming in/out quickly?

Source code:

val width = 5000
val height = 3712
val state: MapState by remember { // TODO: Put this in a view model
mutableStateOf(
	MapState(1, width, height, width).apply {
		addLayer(tileStreamProvider = provider)
	}
  )
}
MapUI(state = state)

FileNotFound exception

Attached is the image I am using.

With libvps I ran the following to generate the deep zoom images:
vips dzsave floorplan.png output --layout=google --tile-size=256 --suffix .jpg --vips-progress

2021-11-17 18:43:18.070 11300-11329/com.achtien.mapcompose4 E/AndroidRuntime: FATAL EXCEPTION: pool-3-thread-3
    Process: com.achtien.mapcompose4, PID: 11300
    java.io.FileNotFoundException: output/4/6/0.jpg
        at android.content.res.AssetManager.nativeOpenAsset(Native Method)
        at android.content.res.AssetManager.open(AssetManager.java:881)
        at android.content.res.AssetManager.open(AssetManager.java:858)
        at com.achtien.mapcompose4.MainActivity$onCreate$tileStreamProvider$1.getTileStream(MainActivity.kt:26)
        at ovh.plrapps.mapcompose.core.TileCollector$worker$1.invokeSuspend(TileCollector.kt:93)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:920)

Android code:

class MainActivity : ComponentActivity() {
	override fun onCreate(savedInstanceState: Bundle?) {
		super.onCreate(savedInstanceState)
		val tileStreamProvider =
			TileStreamProvider { row, col, zoomLvl ->
				resources.assets.open("output/$zoomLvl/$row/$col.jpg")
			}
		val state: MapState by mutableStateOf(
			MapState(5, 4683, 2889, tileStreamProvider).apply {
				disableRotation()
			}
		)
		setContent {
			MapCompose4Theme {
				MapUI(state = state)
			}
		}
	}
}

floorplan

Creating a new MapState breaks gestures

If you try this in the demo app:

var state: MapState by mutableStateOf(createMapState())

init {
    viewModelScope.launch {
        delay(5000)
        state = createMapState()
    }
}

You can see that after the MapState is recreated the map no longer reacts to user interaction (scroll, zoom, etc.).
Recreating MapState is needed to switch between different maps (with different sizes, levels).

How do I update layers?

with(state) {
addLayer(tileStreamProvider)
}
I want to constantly update the layer, But there was a crash: java.lang.OutOfMemoryError: Failed to allocate a 17572876 byte allocation with 8388608 free bytes and 15MB until OOM
at :
val bitmapForLayer = layerIds.associateWith {
Bitmap.createBitmap(tileSize, tileSize, bitmapConfig)
}

Default tile size

The default tile size is 256. Was there any research done in choosing it? What are the tradeoffs in making it smaller or bigger?

Performance of layers

Multiple layers are less performant. This is quite significant in my case where I have 8 layers shown and zoomed out to see many tiles, every tile becomes 8 tiles to draw. This makes sense, but I think there is room for optimization: instead of drawing each tile separately every time, tiles from layers could be drawn into a composite tile "virtual layer", and then the actual map would only draw the composite tiles. This would make it so that instead of drawing 8 tiles per tile coordinate every frame, we would draw 9 tiles on the first frame (8 for composite tile, then composite tile on the screen), and then just 1 on following frames, by drawing just the cached composite tiles.

All layers logic could be moved to a single place and produce a single composite TileStreamProvider, that in the background uses all the TileStreamProviders from all layers to produce composite tiles (with caching). The rest of the library could work as if there was only 1 layer.

I think the speed up would be significant. What do you think about this idea?

Rare crash during gestures

Sometimes when performing gestures (rotate / pinch zoom), the library crashes the app.

java.lang.IllegalStateException: Offset is unspecified
        at androidx.compose.ui.geometry.Offset.getX-impl(Offset.kt:67)
        at androidx.compose.ui.input.pointer.util.VelocityTracker.calculateVelocity-9UxMQ8M(VelocityTracker.kt:69)
        at ovh.plrapps.mapcompose.ui.gestures.GestureDetectorKt$detectGestures$2$1.invokeSuspend(GestureDetector.kt:89)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
        at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
        at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
        at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:432)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.dispatchPointerEvent(SuspendingPointerInputFilter.kt:330)
        at androidx.compose.ui.input.pointer.SuspendingPointerInputFilter.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:343)
        at androidx.compose.ui.input.pointer.Node.dispatchMainEventPass(HitPathTracker.kt:287)
        at androidx.compose.ui.input.pointer.NodeParent.dispatchMainEventPass(HitPathTracker.kt:151)
        at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:90)
        at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-gBdvCQM(PointerInputEventProcessor.kt:77)
        at androidx.compose.ui.platform.AndroidComposeView.dispatchTouchEvent(AndroidComposeView.android.kt:860)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3120)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2801)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:502)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1890)
        at android.app.Activity.dispatchTouchEvent(Activity.java:4196)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:460)
        at android.view.View.dispatchPointerEvent(View.java:14799)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6347)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:6148)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5626)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5814)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5871)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5683)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5649)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5657)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5630)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8562)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8513)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8482)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8685)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:259)
        at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method)
        at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:239)
        at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:8642)
        at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:8771)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
        at android.view.Choreographer.doFrame(Choreographer.java:772)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7839)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.