android - sonido - programa para hacer gif con fotos
¿Cómo mostrar una imagen GIF animada en una aplicación de Android? (10)
Quiero mostrar una imagen GIF animada en una aplicación de Android como la imagen de abajo. He probado la webview pero no he tenido éxito. ¿Cómo mostrar el gif animado en la aplicación?
Después de una larga búsqueda en Google, supe que no hay soporte nativo para las imágenes GIF. No hay soluciones adecuadas para mostrar el gif animado en la aplicación. Puedes ver esta solución
Para hacer que el gif animado juegue en un diseño.
Intente de esta manera:
Movie movie,movie1;
InputStream is=null,is1=null;
long moviestart;
long moviestart1;
public GIFView(Context context) {
super(context);
is=context.getResources().openRawResource(R.drawable.hxps);
is1=context.getResources().openRawResource(R.drawable.cartoon);
movie=Movie.decodeStream(is);
movie1=Movie.decodeStream(is1);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFCCCCCC);
super.onDraw(canvas);
long now=android.os.SystemClock.uptimeMillis();
System.out.println("now="+now);
if (moviestart == 0) { // first time
moviestart = now;
}
if(moviestart1==0)
{
moviestart1=now;
}
System.out.println("/tmoviestart="+moviestart);
int relTime = (int)((now - moviestart) % movie.duration()) ;
int relTime1=(int)((now - moviestart1)% movie1.duration());
System.out.println("time="+relTime+"/treltime="+movie.duration());
movie.setTime(relTime);
movie1.setTime(relTime1);
movie.draw(canvas,0,0);
movie1.draw(canvas,10,300);
this.invalidate();
}
La mejor y más fácil solución para mostrar imágenes GIF en Android y funcionará perfectamente:
- Abrir build.gradle (Módulo: aplicación)
- poner en dependencias: compilar ''pl.droidsonroids.gif: android-gif-drawable: 1.1. +''
Abra la carpeta de diseño y coloque este código donde desee mostrar la imagen GIF: por ejemplo, activity_main.xml
<pl.droidsonroids.gif.GifImageView android:layout_width="150dp" android:layout_height="wrap_content" android:src="@drawable/your_gif_file_name"/>
android: src = "@ drawable / your_gif_file_name", reemplaza ''your_gif_file_name'' con el archivo de imagen gif que desees
No necesitas ninguna biblioteca, simplemente usa este código:
Paso 1: Crea un archivo llamado GIFView.java
package com.thigale.testproject;
/**
* Created by Thigale Sameer on 11-12-16.
*/
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Movie;
import android.util.AttributeSet;
import android.view.View;
import java.io.InputStream;
public class GifView extends View {
public Movie mMovie;
public long movieStart;
private int gifId;
public GifView(Context context) {
super(context);
}
public GifView(Context context, AttributeSet attrs) {
super(context, attrs);
initializeView(attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "src", 0));
}
public GifView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initializeView(attrs.getAttributeResourceValue("http://schemas.android.com/apk/res-auto", "src", 0));
}
private void initializeView(final int id) {
InputStream is = getContext().getResources().openRawResource(id);
mMovie = Movie.decodeStream(is);
this.gifId = id;
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
super.onDraw(canvas);
long now = android.os.SystemClock.uptimeMillis();
if (movieStart == 0) {
movieStart = now;
}
if (mMovie != null) {
int relTime = (int) ((now - movieStart) % mMovie.duration());
mMovie.setTime(relTime);
mMovie.draw(canvas, getWidth() - mMovie.width(), getHeight() - mMovie.height());
this.invalidate();
}
}
public void setGIFResource(int resId) {
this.gifId = resId;
initializeView(this.gifId);
}
public int getGIFResource() {
return this.gifId;
}
}
Paso 2: Agregue las siguientes líneas en res / attrs.xml
<declare-styleable name="GIFView">
<attr name="src" format="reference" />
</declare-styleable>
Paso 3: agrega esta línea a tu AndroidManifest.xml en una actividad específica
android:hardwareAccelerated="false"
Paso 4: Crea esta vista en tu XML:
<com.thigale.testproject.GifView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
components:src="@drawable/loading" />
Paso 5 En la actividad principal donde creó la vista, agregue las siguientes líneas:
xmlns:components="http://schemas.android.com/apk/res-auto"
Puedes simplemente agregar una vista web y mostrar una imagen GIF en eso, como:
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient());
webView.loadUrl("https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Rotating_earth_(large).gif/200px-Rotating_earth_(large).gif");
Esto mostrará la imagen gif en tu aplicación.
¡Espero eso ayude! ¡Buena suerte!
Puedes usar Glide :
ImageView imageView = (ImageView) findViewById(R.id.imageView);
GlideDrawableImageViewTarget imageViewTarget = new GlideDrawableImageViewTarget(imageView);
Glide.with(this).load(R.raw.sample_gif).into(imageViewTarget);
También intenté hacer lo mismo, pero Android no muestra imágenes gif con animación. Si desea lograr lo mismo, entonces tome algunos fotogramas de su imagen animada y luego use fotograma a fotograma.
Puedes tener referencia en el siguiente enlace. http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html
También puedes usar esta biblioteca para admitir fácilmente un gifDrawable .
Solo usa GifImageView en lugar de ImageView normal:
<pl.droidsonroids.gif.GifImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/your_anim"/>
y ubique su archivo gif bajo la fuente src. ¡Eso es todo!
Usted puede tener una oportunidad en este lib GifImageView . Es muy simple y fácil de usar. El siguiente código de ejemplo es de README de este proyecto.
@Override protected void onCreate (final Bundle savedInstanceState) {super.onCreate (savedInstanceState);
gifView = new GifImageView(context); gifView.setBytes(bitmapData); setContentView(gifView);
}
@Override protected void onStart () {super.onStart (); gifView.startAnimation (); }
@Override protected void onStop () {super.onStop (); gifView.stopAnimation (); }
actualizar:
Hay una versión actualizada en el arsenal de Android y en la página de GitHub de GIFView .
Esto es algo pequeño que hice cuando alguien me pidió que lo ayudara a mostrar gifs. La mayoría de las cosas que encontré en línea eran bibliotecas y soluciones de terceros que utilizaban el subproceso de la interfaz de usuario para procesar el gif que no funcionaba tan bien en mi teléfono, así que decidí hacerlo yo mismo con la ayuda de la API de películas de Android. Lo hice deliberadamente extendiendo ImageView para que podamos usar atributos como scaleType. Esto permite recuperar gif de url o del directorio de activos. Lo documenté todo.
Cómo usarlo:
Ejemplo simple de usarlo en un archivo de diseño xml:
<[package].GIFView xmlns:gif_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/gif_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
gif_view:gif_src="asset:gif1" />
El código:
GIF.java:
/**
* Class that represents a gif instance.
*/
public class GIF {
private static final Bitmap.Config DEF_VAL_CONFIG = Bitmap.Config.RGB_565;
private static final int DEF_VAL_DELAY_IN_MILLIS = 33;
// the gif''s frames are stored in a movie instance
private Movie movie;
// the canvas of this gif
private Canvas canvas;
// the bitmap of this gif
private Bitmap bitmap;
// the start time of the gif
private long gifStartTime;
// the executor of the gif''s thread
private ScheduledExecutorService executor;
// the main runnable of the gif
private Runnable mainRunnable;
// delay in millis between frames
private int delayInMillis;
private OnFrameReadyListener onFrameReadyListener;
private Handler listenerHandler;
private Runnable listenerRunnable;
/**
* Creates Gif instance based on the passed InputStream.
*
* @param in the InputStream
* @throws InputStreamIsNull if in is null
* @throws InputStreamIsEmptyOrUnavailableException if in is empty or unavailable
*/
public GIF(InputStream in) {
this(in, DEF_VAL_CONFIG);
}
/**
* Creates Gif instance based on the passed InputStream and the config.
*
* @param in the InputStream
* @param config the Config
* @throws NullPointerException if config is null
* @throws InputStreamIsNull if in is null
* @throws InputStreamIsEmptyOrUnavailableException if in is empty or unavailable
*/
public GIF(InputStream in, Bitmap.Config config) {
if (in == null)
throw new InputStreamIsNull("the input stream is null");
this.movie = Movie.decodeStream(in);
if (movie == null)
throw new InputStreamIsEmptyOrUnavailableException("the input steam is empty or unavailable");
this.bitmap = Bitmap.createBitmap(movie.width(), movie.height(), config);
// associates the canvas with the bitmap
this.canvas = new Canvas(bitmap);
this.mainRunnable = new Runnable() {
@Override
public void run() {
draw();
invokeListener();
}
};
setDelayInMillis(DEF_VAL_DELAY_IN_MILLIS);
}
/**
* Register a callback to be invoked when the gif changed a frame.
* Invokes methods from a special thread.
*
* @param onFrameReadyListener the listener to attach
*/
public void setOnFrameReadyListener(OnFrameReadyListener onFrameReadyListener) {
setOnFrameReadyListener(onFrameReadyListener, null);
}
/**
* Register a callback to be invoked when the gif changed a frame.
* Invokes methods from the specified handler.
*
* @param onFrameReadyListener the listener to attach
* @param handler the handler
*/
public void setOnFrameReadyListener(OnFrameReadyListener onFrameReadyListener, Handler handler) {
this.onFrameReadyListener = onFrameReadyListener;
listenerHandler = handler;
if (listenerHandler != null)
listenerRunnable = new Runnable() {
@Override
public void run() {
GIF.this.onFrameReadyListener.onFrameReady(bitmap);
}
};
else
listenerRunnable = null;
}
/**
* Sets the delay in millis between every calculation of the next frame to be set.
*
* @param delayInMillis the delay in millis
* @throws IllegalArgumentException if delayInMillis is non-positive
*/
public void setDelayInMillis(int delayInMillis) {
if (delayInMillis <= 0)
throw new IllegalArgumentException("delayInMillis must be positive");
this.delayInMillis = delayInMillis;
}
/**
* Starts the gif.
* If the gif is already running does nothing.
*/
public void startGif() {
if (executor != null)
return;
executor = Executors.newSingleThreadScheduledExecutor();
final int INITIAL_DELAY = 0;
executor.scheduleWithFixedDelay(mainRunnable, INITIAL_DELAY,
delayInMillis, TimeUnit.MILLISECONDS);
}
/**
* Stops the gif.
* If the gif is not running does nothing.
*/
public void stopGif() {
if (executor == null)
return;
executor.shutdown();
// waits until the thread is finished
while (true) {
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
break;
} catch (InterruptedException ignored) {
}
}
executor = null;
}
// calculates the frame and draws it to the bitmap through the canvas
private void draw() {
// if gifStartTime == 0 inits it for the first time
if (gifStartTime == 0)
gifStartTime = SystemClock.uptimeMillis();
long timeElapsed = SystemClock.uptimeMillis() - gifStartTime;
int timeInGif = (int) (timeElapsed % movie.duration());
movie.setTime(timeInGif);
movie.draw(canvas, 0, 0);
}
// invokes the listener
private void invokeListener() {
if (onFrameReadyListener == null)
return;
// if handler was given invokes from it, otherwise invokes from this thread
if (listenerHandler != null)
listenerHandler.post(listenerRunnable);
else
onFrameReadyListener.onFrameReady(bitmap);
}
/**
* Interface definition for a callback to be invoked when the gif changed a frame.
*/
public interface OnFrameReadyListener {
/**
* Called when the gif changed a frame.
* <p>
* Note: If a handler was given with the listener this method
* invokes from the handler, otherwise this method
* invokes from a special thread.
* <p>
* Note: This bitmap is mutable and used by the gif instance
* thus it is not recommended to mutate it.
*
* @param bitmap the new bitmap of the gif
*/
void onFrameReady(Bitmap bitmap);
}
/**
* Definition of a runtime exception class to throw when the inputStream is null.
*/
public static class InputStreamIsNull extends NullPointerException {
/**
* Creates a new instance.
*/
public InputStreamIsNull() {
super();
}
/**
* * Creates a new instance with a message.
*
* @param message the message
*/
public InputStreamIsNull(String message) {
super(message);
}
}
/**
* Definition of a runtime exception class to throw when the inputStream is empty or unavailable.
*/
public static class InputStreamIsEmptyOrUnavailableException extends RuntimeException {
/**
* Creates a new instance.
*/
public InputStreamIsEmptyOrUnavailableException() {
super();
}
/**
* * Creates a new instance with a message.
*
* @param message the message
*/
public InputStreamIsEmptyOrUnavailableException(String message) {
super(message);
}
}
}
GIFView.java:
/**
* A view that can show gifs.
* <p>
* XML Attributes:
* <p>
* gif_src:
* A string that represents the gif''s source.
* <p>
* - If you want to get the gif from a url
* concatenate the string "url:" with the full url.
* <p>
* - if you want to get the gif from the assets directory
* concatenate the string "asset:" with the full path of the gif
* within the assets directory. You can exclude the .gif extension.
* <p>
* for example if you have a gif in the path "assets/ex_dir/ex_gif.gif"
* the string should be: "asset:ex_dir/ex_gif"
* <p>
* delay_in_millis:
* A positive integer that represents how many milliseconds
* should pass between every calculation of the next frame to be set.
*/
public class GIFView extends ImageView {
public static final String RESOURCE_PREFIX_URL = "url:";
public static final String RESOURCE_PREFIX_ASSET = "asset:";
private static final int DEF_VAL_DELAY_IN_MILLIS = 33;
// the gif instance
private GIF gif;
// keeps track if the view is in the middle of setting the gif
private boolean settingGif;
private GIF.OnFrameReadyListener gifOnFrameReadyListener;
private OnSettingGifListener onSettingGifListener;
// delay in millis between frames
private int delayInMillis;
/**
* Creates a new instance in the passed context.
*
* @param context the context
*/
public GIFView(Context context) {
super(context);
init(null);
}
/**
* Creates a new instance in the passed context with the specified set of attributes.
*
* @param context the context
* @param attrs the attributes
*/
public GIFView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
// inits the view
private void init(AttributeSet attrs) {
this.gifOnFrameReadyListener = new GIF.OnFrameReadyListener() {
@Override
public void onFrameReady(Bitmap bitmap) {
setImageBitmap(bitmap);
}
};
setDelayInMillis(DEF_VAL_DELAY_IN_MILLIS);
if (attrs != null)
initAttrs(attrs);
}
// inits the view with the specified attributes
private void initAttrs(AttributeSet attrs) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(
attrs, R.styleable.gif_view,
0, 0);
try {
// gets and sets the delay in millis.
int delayInMillis = typedArray.getInt(R.styleable.gif_view_delay_in_millis,
DEF_VAL_DELAY_IN_MILLIS);
if (delayInMillis != DEF_VAL_DELAY_IN_MILLIS)
setDelayInMillis(delayInMillis);
// gets the source of the gif and sets it
String string = typedArray.getString(R.styleable.gif_view_gif_src);
if (string != null)
setGifResource(typedArray.getString(R.styleable.gif_view_gif_src));
} finally {
typedArray.recycle();
}
}
/**
* Register callbacks to be invoked when the view finished setting a gif.
*
* @param onSettingGifListener the listener to attach
*/
public void setOnSettingGifListener(OnSettingGifListener onSettingGifListener) {
this.onSettingGifListener = onSettingGifListener;
}
/**
* Sets the delay in millis between every calculation of the next frame to be set.
*
* @param delayInMillis the delay in millis
* @throws IllegalArgumentException if delayInMillis is non-positive
*/
public void setDelayInMillis(int delayInMillis) {
if (delayInMillis <= 0)
throw new IllegalArgumentException("delayInMillis must be positive");
this.delayInMillis = delayInMillis;
if (gif != null)
gif.setDelayInMillis(delayInMillis);
}
/**
* Returns true if the view is in the process of setting the gif, false otherwise.
*
* @return true if the view is in the process of setting the gif, false otherwise
*/
public boolean isSettingGif() {
return settingGif;
}
/**
* Sets the gif of this view and starts it.
* <p>
* Note that every exception while setting the gif is only sent to the
* OnSettingGifListener instance attached to this view.
* <p>
* If the view has already begun setting another gif, does nothing.
* You can query this state with isSettingGif().
* <p>
* The string passed must be in the following format:
* <p>
* - If you want to get the gif from a url
* concatenate the string "url:" with the full url.
* <p>
* - if you want to get the gif from the assets directory
* concatenate the string "asset:" with the full path of the gif
* within the assets directory. You can exclude the .gif extension.
* <p>
* You can use the Constants:
* <p>
* GIFView.RESOURCE_PREFIX_URL = "url:"
* GIFView.RESOURCE_PREFIX_ASSET = "asset:"
* <p>
* for example if you have a gif in the path "assets/ex_dir/ex_gif.gif"
* invoke the method like this: setGifResource(GIFView.RESOURCE_PREFIX_ASSET + "ex_dir/ex_gif");
*
* @param string the string
* @throws IllegalArgumentException if the string format is invalid
*/
public void setGifResource(String string) {
if (settingGif)
return;
// stops the gif if it is running
if (gif != null)
gif.stopGif();
// defines some finals for readability
final int URL_START_INDEX = RESOURCE_PREFIX_URL.length();
final int ASSET_START_INDEX = RESOURCE_PREFIX_ASSET.length();
final String GIF_EXTENSION = ".gif";
if (string.startsWith(RESOURCE_PREFIX_URL)) {
// notifies setting gif has started
settingGif = true;
// gets the url
String url = string.substring(URL_START_INDEX);
new AsyncSettingOfGif() {
@Override
protected InputStream getGifInputStream(String url) throws Exception {
// gets the input stream from the url
return (InputStream) new URL(url).getContent();
}
}.execute(url);
} else if (string.startsWith(RESOURCE_PREFIX_ASSET)) {
// notifies setting gif has started
settingGif = true;
// gets the asset path
String assetPath = string.substring(ASSET_START_INDEX)
.replaceAll("[/////]", File.separator); // replacing file separators
if (!assetPath.endsWith(GIF_EXTENSION))
assetPath += GIF_EXTENSION;
new AsyncSettingOfGif() {
@Override
protected InputStream getGifInputStream(String assetPath) throws Exception {
// gets the input stream from the assets directory
return GIFView.this.getResources().getAssets().open(assetPath);
}
}.execute(assetPath);
// if string format is invalid
} else {
throw new IllegalArgumentException("string format is invalid");
}
}
/**
* Called when the view finished to set the gif
* or an exception has occurred.
* If there are no exceptions e is null.
* <p>
* Note that the gif can be initialized properly
* and one or more exceptions can be caught in the way.
*
* @param e the Exception
*/
protected void onFinishSettingGif(Exception e) {
// notifies setting the gif has finished
settingGif = false;
if (gif != null)
onSuccess();
else
onFailure(e);
}
// on finish setting the gif
private void onSuccess() {
gif.setOnFrameReadyListener(gifOnFrameReadyListener, getHandler());
gif.setDelayInMillis(delayInMillis);
startGif();
if (onSettingGifListener != null)
onSettingGifListener.onSuccess(this);
}
// when an exception has occurred while trying to set the gif
private void onFailure(Exception e) {
if (onSettingGifListener != null)
onSettingGifListener.onFailure(this, e);
}
/**
* Starts the gif.
* If the gif is already running does nothing.
*
* @throws IllegalStateException if the gif has not been initialized yet
*/
public void startGif() {
if (gif == null || settingGif)
throw new IllegalStateException("the gif has not been initialized yet");
gif.startGif();
}
/**
* Stops the gif.
* If the gif is not running does nothing.
*
* @throws IllegalStateException if the gif has not been initialized yet
*/
public void stopGif() {
if (gif == null || settingGif)
throw new IllegalStateException("the gif has not been initialized yet");
gif.stopGif();
}
/**
* Interface definition for callbacks to be invoked when setting a gif.
*/
public interface OnSettingGifListener {
/**
* Called when a gif has successfully set.
*
* @param view the GIFView
*/
void onSuccess(GIFView view);
/**
* Called when a gif cannot be set.
*
* @param view the GIFView
* @param e the Exception
*/
void onFailure(GIFView view, Exception e);
}
/**
* Definition of an Exception class to throw when the view cannot initialize the gif.
*/
public static class CannotInitGifException extends Exception {
/**
* Creates a new instance.
*/
public CannotInitGifException() {
super();
}
/**
* * Creates a new instance with a message.
*
* @param message the message
*/
public CannotInitGifException(String message) {
super(message);
}
}
/**
* A sub-class of AsyncTask to easily perform an async task of setting a gif.
* <p>
* The default implementation of AsyncSettingOfGif.doInBackground() is to try and init the gif
* from the input stream returned from AsyncSettingOfGif.getGifInputStream() and notify
* GIFView.onFinishSettingGif() sending to it the exception, if occurred, or null.
* <p>
* Implementations of this class should override AsyncSettingOfGif.getGifInputStream()
* to return the right input stream for the gif based on the string argument.
* The string argument can be, for example, a url to retrieve the input stream from.
*/
protected abstract class AsyncSettingOfGif extends AsyncTask<String, Void, Exception> {
@Override
protected Exception doInBackground(String... string) {
CannotInitGifException exceptionToSend = null;
try (InputStream in = getGifInputStream(string[0])) {
// tries to init the gif
gif = new GIF(in);
} catch (Exception e) {
// prepares the message of the exception
String message = e.getMessage();
if (e instanceof FileNotFoundException)
message = "file not found: " + message;
// prepares the exception to send back
exceptionToSend = new CannotInitGifException(message);
}
return exceptionToSend;
}
/**
* Override this method to return the right input stream for the gif based on the string argument.
* The string argument can be, for example, a url to retrieve the input stream from.
*
* @param string the string
* @return an InputStream of a gif
* @throws Exception if an exception has occurred
*/
protected abstract InputStream getGifInputStream(String string) throws Exception;
@Override
protected void onPostExecute(Exception e) {
onFinishSettingGif(e);
}
}
}
res / values / attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="gif_view">
<attr name="gif_src" format="string" />
<attr name="delay_in_millis" format="integer" />
</declare-styleable>
</resources>