Comments (16)
Sure, it's just the scroll positions, so the native View methods of getScrollX
and getScrollY
would do it.
from tileview.
okay, thank you for your quick answer,
however this did only work for me when the view was not scaled.
I managed to set the scale of a TileView to the scale of another , but then the position was not correct anymore:
tileview2.moveTo(tileview1.getScrollX, tileview1.getScrollXY);
tileview2.setScale(tileview1.getScale());
Can you tell me whats wrong with this peace of code?
Thanks in advance.
from tileview.
Try this:
tileview2.scrollTo(tileview1.getScrollX(), tileview1.getScrollY());
tileview2.setScale(tileview1.getScale());
from tileview.
Thanks, now it works :)
from tileview.
With that working now, i ran into another minor issue:
When I manualy zoom in and scroll to another position in the second view and then change back to the first one (where I again getScroll and setScale to the new values from the second view) the image i get is not sharp.
Only when i move the map a little, then the tiles for the needed level of detail are being loaded.
hope my description is not to confusing ... any ideas what I could do to resolve this problem?
from tileview.
try calling requestRender
on the tileview that has not loaded the tiles.
from tileview.
unfortunately I get the same result with calling requestRender.
It is only sharp when i switch to a view I haven't loaded before, or one where the area i move the view to has been loaded before.
from tileview.
This actually comes up a lot - I strongly suspect it's a validation issue. First thing to do is try refresh
on the instance not loading tiles. Hopefully that works - if not, it's most definitely a validation issue, which is a bear with the Android framework - I've tried to catch any potential validation failure everywhere I can, but as I said it happens a lot. If refresh
doesn't work for you, try calling _both_ invalidate
and postInvalidate
(yes, they should be redundant, but they really aren't) on as many layers as your can when that happens (again, should not be necessary but sometimes is - both should cascade but don't always do so reliably) - maybe start on the tile view itself, but to be sure it's happening you may need to recurse down children as well...
Hopefully refresh
will do it and you won't have to get into the validation quagmire - post back and LMK how it goes.
from tileview.
refresh and also invalidating didn't work for me.
but maybe I'm doing it wrong:
I have a Fragment which returns different instances of a class Map that extends TileView.
I get those instances by calling getMap(x) where I first scrollTo and setScale to the position of the Map loaded before and then return it.
In this method(getMap) I tried calling requestRender() refresh() and both invalidate() and postInvalidate() on the Map instance before returning it but that didn't work.
Have i got something wrong("as many layers as your can" "recurse down children")? - because I don't know where else I should call this methods.
from tileview.
requestRender
and refresh
are TileView methods, and can only be called by TileView instances, so that's pretty straightforward. They should both be called only when the TileView instance is in a viewable state (added to the display list, etc). They should both be called only from the UI thread (if you're calling either method from an AsyncTask, for example, you'd want to post
a Runnable
to the UI thread to call either method).
Separate from that, the Android framework tries to save resources by only drawing if the last image on the screen is invalid. If there is no change, there's no sense wasting time and resources drawing the same thing again. In general, it does an OK job of determining what is valid and what is not, but can get confused when doing certain things programmatically, like scrolling - thus they (Android) offers two methods: invalidate
and postInvalidate
. They do the same thing - they mark the View as being _invalid_ and it should be drawn again the next time the UI does a drawing pass. The only difference between the two methods is that postInvalidate
automatically sends the invalidate invocation through the UI thread (otherwise you'd have to do it yourself, using the same post
and Runnable
technique I described earlier).
In theory, if you invalidate a parent, all it's children get redrawn as well, but in practice calling invalidate on a parent does not always work - sometimes you have to target the child that is responsible for the change in drawing state, and this isn't always obvious. These validation issues have come up a lot, and in general they're tough to track down.
If nothing I've suggested has worked, you can either post the relevant bits of your code, or I can take a look at your project if you have it available for download.
from tileview.
I'll post my code here. The interesting part is probably the MapManager.
I have a Fragment which returns the View instances:
public class MapFragment extends Fragment {
public static final String ARG_SERVICE_NUMBER = "service_number";
int i;
public MapFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
i = getArguments().getInt(ARG_SERVICE_NUMBER);
return MainActivity.maps.getMap(i);
}
@Override
public void onPause() {
super.onPause();
MainActivity.maps.clear(i);
}
@Override
public void onResume() {
super.onResume();
MainActivity.maps.resume(i);
}
@Override
public void onDestroy() {
super.onDestroy();
((ViewGroup) MainActivity.maps.getMap(i).getParent()).removeView(MainActivity.maps.getMap(i));
}
}
The variable maps in the Fragment above is an instance of my MapManager where the synchronisation of the view positions is done. This is also the class where i tried to apply your suggestions.
public class MapsManager {
private static Map[] map;
private static int currentFloor;
private static double[] position;
private static double scale;
private static MapsManager instance = new MapsManager();
public MapsManager() {
}
public static MapsManager getInstance(Activity activity) {
currentFloor = 0;
position = new double[2];
map = new Map[4];
map[0] = new MapLevel0(activity);
map[0].setPosition(700, 100);
map[0].setScale(0.3);
map[1] = new MapLevel1(activity);
map[2] = new MapLevel2(activity);
map[3] = new MapLevel3(activity);
return instance;
}
public TileView getMap(int i) {
position = map[currentFloor].getPosition();
map[i].setPosition((int) position[0], (int) position[1]);
scale = map[currentFloor].getScale();
map[i].setScale(scale);
currentFloor = i;
//at this point i tried requestRender() refresh() and both invalidate() and postInvalidate()
//map[i].refresh();
return map[i];
}
public void clear(int i) {
map[i].clear();
}
public void resume(int i) {
map[i].resume();
}
}
And here is the Map class:
public class Map extends TileView {
public Map(Context context) {
super(context);
this.setSize(6103, 3207);
defineRelativeBounds(42.379676, -71.094919, 42.346550, -71.040280);
setMarkerAnchorPoints(-0.5f, -1.0f);
setScaleLimits(0, 2);
setTransitionsEnabled(false);
}
public void frameTo(final double x, final double y) {
post(new Runnable() {
@Override
public void run() {
moveTo(x, y);
}
});
}
public double[] getPosition() {
double[] tmp = { getScrollX(), getScrollY() };
return tmp;
}
public void setPosition(int x, int y) {
scrollTo(x, y);
}
}
Any ideas what the problem could be?
Feel free to point out any potential issues.
from tileview.
The good news is that I think I see where the problem is. The bad news is that I'm not sure how to fix it.
So the TileView determins what tiles need to be rendered by examining a Rect that represents the viewport - it's basically the scroll position + the width or height of the TileView itself: https://github.com/moagrius/TileView/blob/master/src/com/qozix/tileview/TileView.java#L742
If the width and height are 0 (e.g., it's not in the display list), then no tiles will ever intersect.
A view will commonly not have width or height until it is has undergone a layout pass. You'll notice if you make a custom view and Log the width / height in the constructor, it will almost always be 0.
A couple things to try.
First, I'd try to post out of onCreateView:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
i = getArguments().getInt(ARG_SERVICE_NUMBER);
final TileView map = MainActivity.maps.getMap(i);
map.post(new Runnable(){
@Override
public void run(){
map.refresh();
}
});
return map;
}
If that doesn't work, you can try to de-optimize the onLayout requestRender... Either hack the core of TileView.onLayout and remove the conditional:
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout( changed, l, t, r, b );
if ( changed ) {
updateViewport();
requestRender();
}
}
becomes:
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout( changed, l, t, r, b );
updateViewport();
requestRender();
}
Or if you don't want to hack the core (e.g., if you're using the jar), do the same thing in your subclass
public class Map extends TileView {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout( changed, l, t, r, b );
requestRender();
}
// ...
from tileview.
Thank you very much for your detailed answers.
Even though i have no idea why your solutions did't do the trick, I now got it working by overriding the onLayout method in my Map class like this:
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(true, l, t, r, b);
}
from tileview.
Awesome, glad you got it working. FWIW, your version (with the changed
variable hardcoded to true) should be identical to the core-hack mentioned above.
As a result, I'm going to remove that conditional check entirely, since it's caused other issues before that I've had to tweak other spots to accommodate - #61
Thanks for your feedback, and your determination to get it working!
from tileview.
Nice, I haven't tried this particular solution of yours since I'm using the jar.
Thanks again for your help!
from tileview.
NP! And good job getting it to work!
from tileview.
Related Issues (20)
- Remote tile demo freezes and crashes HOT 2
- Combine smooth scroll and scale HOT 2
- Tiles not properly laid out when Scale < 1 with remote tiles HOT 15
- Open source but no license? HOT 2
- Markers disappear when zooming HOT 4
- Cannot add tile images on the fly HOT 1
- StreamProvider asked to provide data for rows and columns out of bounds with to small images HOT 5
- Tiles outside the image are created HOT 8
- White text on white background in Advanved Tile Demo HOT 1
- Get touched position when touch on the tileview (version 4.0.7)
- longtouch
- App killed in background crashes when returning to foreground HOT 1
- `android.os.BadParcelableException` regarding `com.moagrius.widget.ScrollView$SavedState.<init>` HOT 1
- Use in viewholder for recycler view. HOT 2
- build() method starts to return void instead of TileView HOT 1
- Mike passed away HOT 5
- Does this lib support SVG format
- JCenter -> MavenCenter
- implementation 'com.qozix:tileview:2.7.7' doesn't seem to work HOT 1
- Impossible import com.qozix.tileview HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from tileview.