New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for displaying animated gif images on Image tag #1099
Comments
Actually, looks like on iOS at least (from this SO discussion), all the images need to be broken out into their frames. So the XML would probably need to look like this: <Image duration="1" repeatCount="0">
<Image.animationImages>
<AnimationImage src="..." />
<AnimationImage src="..." />
<AnimationImage src="..." />
<Image.animationImages>
</Image> I'm basing that off of how you would do it in iOS, however, I'm not sure how it would look like for Android? |
👍 |
I know @bradmartin is cooking something here! :) |
This works for Android, iOS will be available in the coming weeks. If anyone is interested I have a few cocoapods in mind, just PM me for info. |
Well done @bradmartin! |
Just published the plugin. https://www.npmjs.com/package/nativescript-gif Only limitation is Android supports local .gif files right now. The library should work with remote .gif urls but I haven't been able to figure it out quite yet. Anyone wanting to contribute, that would be awesome. This block here is where it needs to be implemented. |
Hey @bradmartin, Maybe you can use something like: var bytes = r.content.raw.toByteArray();
var buffer = java.nio.ByteBuffer.wrap(bytes); |
@enchev I tried that and various other approaches which none have worked as I thought they would, which could be a problem with the library itself but I'm not a Java expert by any means to go debugging and figure out those issues without wasting too much time 😄. The author of the Android library did give me a snippet to try out, I converted it to JS and it worked fine but I had to change the StrictPolicy to allow the network request to run on the main thread. Very bad, I know, but wanted to see if it worked and it did. Java SampleString url = "https://media4.giphy.com/media/BgBf6pW9qOgQU/200.gif";
URLConnection urlConnection = new URL(url).openConnection();
urlConnection.connect();
final int contentLength = urlConnection.getContentLength();
ByteBuffer buffer = ByteBuffer.allocateDirect(contentLength);
ReadableByteChannel channel = Channels.newChannel(urlConnection.getInputStream());
while (buffer.remaining() > 0)
channel.read(buffer);
channel.close();
GifDrawable drawable = new GifDrawable(buffer); Translated to JS var url = new java.net.URL(this.src);
var urlConnection = url.openConnection();
urlConnection.connect();
var contentLength = urlConnection.getContentLength();
console.log('contentLength: ' + contentLength);
var buffer = java.nio.ByteBuffer.allocateDirect(contentLength);
console.log('buffer: ' + buffer);
var channel = java.nio.channels.Channels.newChannel(urlConnection.getInputStream());
console.log('channel: ' + channel);
while (buffer.remaining() > 0) {
channel.read(buffer);
}
channel.close();
console.log('channel close');
this._drawable = new pl.droidsonroids.gif.GifDrawable(buffer); Which will of course fail because that would make the request on the main thread which is blocked, so to just test that it was working I added this prior to the js block to make the request. StrictMode change if (android.os.Build.VERSION.SDK_INT > 9) {
var policy = new android.os.StrictMode.ThreadPolicy.Builder().permitAll().build();
android.os.StrictMode.setThreadPolicy(policy);
} Once that change has been made the GifDrawable will be constructed using the buffer and it will work, but again, can't actual use this so I tried to do the same with the http module making the request and using the bytes returned but I can't get it to work. Http Request Attempt http.request({ url: this.src, method: "GET" }).then(function(r) {
/***** Enchev suggestion - didn't work :( *****/
// var bytes = r.content.raw.toByteArray();
// console.log('bytes: ' + bytes);
// var buffer = java.nio.ByteBuffer.wrap(bytes);
// console.log('buffer: ' + buffer);
/***** Attempt to use the Content-Length header, this part is okay *****/
var contentLength;
for (var header in r.headers) {
if (header === "Content-Length") {
contentLength = r.headers[header];
break;
}
};
console.log('contentLength: ' + contentLength);
/***** The buffer is created ******/
var buffer = java.nio.ByteBuffer.allocateDirect(contentLength);
console.log('buffer: ' + buffer);
// returns OutputStreamChannel --- PROBLEM HERE IS it returns an OutputStream
// the Java sample code passed in urlConnection.getInputStream() which returns an Input stream and it works
// Need to get an input stream as the channel and the while loop should work and then the buffer should also work
// when passed to the GifDrawable
var channel = java.nio.channels.Channels.newChannel(r.content.raw);
console.log('channel: ' + channel);
// NEED INPUT STREAM CHANNEL TO WORKING
while (buffer.remaining() > 0) {
channel.read(buffer);
}
channel.close();
this._drawable = new pl.droidsonroids.gif.GifDrawable(buffer);
console.log('this._drawable: ' + this._drawable);
}, function (err) {
console.log(err);
}); |
You were right @enchev that worked, I just screwed up the TS 💣 @NathanaelA fixed up the code and I just published the update so now the plugin supports local and remote .gifs for Android and iOS. |
Great! :D I'm closing this issue! |
Why is it bad? |
Been a long time since I worked on this. Trying to recall the android specifics but basically overriding that policy is a recipe for disaster and also running all network on main thread could lock up other running tasks if you had 10 gifs being pulled down. Or anything else really. Sorry I don't recall the specifics. Google for that policy and you'll find info from the android docs about it |
How can I use a variable with the src? like
|
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
On iOS at least, you have to do custom native stuff to get a GIF to actually animate, otherwise, it doesn't move.
Perhaps an attribute of
animated="true"
on the XML tag would be nice in addition with a programmatic option too.It would also be really cool if it was 2-way-bindable as well, for "play and stop" functionality.
The text was updated successfully, but these errors were encountered: