Gifv player
This commit is contained in:
@@ -15,6 +15,7 @@ import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.model.DisplayItemsParent;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.displayitems.FooterStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.ImageStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.PhotoStatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.displayitems.StatusDisplayItem;
|
||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewer;
|
||||
@@ -122,18 +123,18 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
public void openPhotoViewer(String parentID, Status _status, int attachmentIndex){
|
||||
final Status status=_status.reblog!=null ? _status.reblog : _status;
|
||||
currentPhotoViewer=new PhotoViewer(getActivity(), status.mediaAttachments, attachmentIndex, new PhotoViewer.Listener(){
|
||||
private PhotoStatusDisplayItem.Holder transitioningHolder;
|
||||
private ImageStatusDisplayItem.Holder transitioningHolder;
|
||||
|
||||
@Override
|
||||
public void setPhotoViewVisibility(int index, boolean visible){
|
||||
PhotoStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
ImageStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
if(holder!=null)
|
||||
holder.photo.setAlpha(visible ? 1f : 0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startPhotoViewTransition(int index, @NonNull Rect outRect, @NonNull int[] outCornerRadius){
|
||||
PhotoStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
ImageStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
if(holder!=null){
|
||||
transitioningHolder=holder;
|
||||
View view=transitioningHolder.photo;
|
||||
@@ -170,7 +171,7 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
|
||||
@Override
|
||||
public Drawable getPhotoViewCurrentDrawable(int index){
|
||||
PhotoStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
ImageStatusDisplayItem.Holder holder=findPhotoViewHolder(index);
|
||||
if(holder!=null)
|
||||
return holder.photo.getDrawable();
|
||||
return null;
|
||||
@@ -181,14 +182,14 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
currentPhotoViewer=null;
|
||||
}
|
||||
|
||||
private PhotoStatusDisplayItem.Holder findPhotoViewHolder(int index){
|
||||
private ImageStatusDisplayItem.Holder findPhotoViewHolder(int index){
|
||||
int offset=0;
|
||||
for(StatusDisplayItem item:displayItems){
|
||||
if(item.parentID.equals(parentID)){
|
||||
if(item instanceof PhotoStatusDisplayItem){
|
||||
if(item instanceof ImageStatusDisplayItem){
|
||||
RecyclerView.ViewHolder holder=list.findViewHolderForAdapterPosition(getMainAdapterOffset()+offset+index);
|
||||
if(holder instanceof PhotoStatusDisplayItem.Holder){
|
||||
return (PhotoStatusDisplayItem.Holder) holder;
|
||||
if(holder instanceof ImageStatusDisplayItem.Holder){
|
||||
return (ImageStatusDisplayItem.Holder) holder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -264,10 +265,10 @@ public abstract class BaseStatusListFragment<T extends DisplayItemsParent> exten
|
||||
position-=getMainAdapterOffset();
|
||||
if(position>=0 && position<displayItems.size()){
|
||||
StatusDisplayItem item=displayItems.get(position);
|
||||
if(item instanceof PhotoStatusDisplayItem){
|
||||
int total=((PhotoStatusDisplayItem) item).totalPhotos;
|
||||
if(item instanceof ImageStatusDisplayItem){
|
||||
int total=((ImageStatusDisplayItem) item).totalPhotos;
|
||||
if(total>1){
|
||||
int index=((PhotoStatusDisplayItem) item).index;
|
||||
int index=((ImageStatusDisplayItem) item).index;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.graphics.Outline;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
|
||||
public class GifVStatusDisplayItem extends ImageStatusDisplayItem{
|
||||
public GifVStatusDisplayItem(String parentID, Status status, Attachment photo, BaseStatusListFragment parentFragment, int index, int totalPhotos){
|
||||
super(parentID, parentFragment, photo, status, index, totalPhotos);
|
||||
request=new UrlImageLoaderRequest(photo.previewUrl, 1000, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type getType(){
|
||||
return Type.GIFV;
|
||||
}
|
||||
|
||||
public static class Holder extends ImageStatusDisplayItem.Holder<GifVStatusDisplayItem>{
|
||||
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
super(activity, R.layout.display_item_gifv, parent);
|
||||
View play=findViewById(R.id.play_button);
|
||||
play.setOutlineProvider(new ViewOutlineProvider(){
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline){
|
||||
outline.setOval(0, 0, view.getWidth(), view.getHeight());
|
||||
outline.setAlpha(.99f); // fixes shadow rendering
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
|
||||
public abstract class ImageStatusDisplayItem extends StatusDisplayItem{
|
||||
public final int index;
|
||||
public final int totalPhotos;
|
||||
protected Attachment attachment;
|
||||
protected ImageLoaderRequest request;
|
||||
protected Fragment parentFragment;
|
||||
protected Status status;
|
||||
|
||||
public ImageStatusDisplayItem(String parentID, BaseStatusListFragment parentFragment, Attachment photo, Status status, int index, int totalPhotos){
|
||||
super(parentID, parentFragment);
|
||||
this.attachment=photo;
|
||||
this.parentFragment=parentFragment;
|
||||
this.status=status;
|
||||
this.index=index;
|
||||
this.totalPhotos=totalPhotos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
return request;
|
||||
}
|
||||
|
||||
public static abstract class Holder<T extends ImageStatusDisplayItem> extends StatusDisplayItem.Holder<T> implements ImageLoaderViewHolder{
|
||||
public final ImageView photo;
|
||||
|
||||
public Holder(Activity activity, @LayoutRes int layout, ViewGroup parent){
|
||||
super(activity, layout, parent);
|
||||
photo=findViewById(R.id.photo);
|
||||
photo.setOnClickListener(this::onViewClick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(ImageStatusDisplayItem item){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable drawable){
|
||||
photo.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
photo.setImageDrawable(item.attachment.blurhashPlaceholder);
|
||||
}
|
||||
|
||||
private void onViewClick(View v){
|
||||
if(item.parentFragment instanceof PhotoViewerHost){
|
||||
Status contentStatus=item.status.reblog!=null ? item.status.reblog : item.status;
|
||||
((PhotoViewerHost) item.parentFragment).openPhotoViewer(item.parentID, item.status, contentStatus.mediaAttachments.indexOf(item.attachment));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +1,19 @@
|
||||
package org.joinmastodon.android.ui.displayitems;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.joinmastodon.android.R;
|
||||
import org.joinmastodon.android.fragments.BaseStatusListFragment;
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
import org.joinmastodon.android.model.Status;
|
||||
import org.joinmastodon.android.ui.photoviewer.PhotoViewerHost;
|
||||
|
||||
import me.grishka.appkit.imageloader.ImageLoaderViewHolder;
|
||||
import me.grishka.appkit.imageloader.requests.ImageLoaderRequest;
|
||||
import me.grishka.appkit.imageloader.requests.UrlImageLoaderRequest;
|
||||
import me.grishka.appkit.utils.BindableViewHolder;
|
||||
|
||||
public class PhotoStatusDisplayItem extends StatusDisplayItem{
|
||||
private Attachment attachment;
|
||||
private ImageLoaderRequest request;
|
||||
private Fragment parentFragment;
|
||||
private Status status;
|
||||
public final int index, totalPhotos;
|
||||
public class PhotoStatusDisplayItem extends ImageStatusDisplayItem{
|
||||
public PhotoStatusDisplayItem(String parentID, Status status, Attachment photo, BaseStatusListFragment parentFragment, int index, int totalPhotos){
|
||||
super(parentID, parentFragment);
|
||||
this.status=status;
|
||||
this.attachment=photo;
|
||||
super(parentID, parentFragment, photo, status, index, totalPhotos);
|
||||
request=new UrlImageLoaderRequest(photo.url, 1000, 1000);
|
||||
this.parentFragment=parentFragment;
|
||||
this.index=index;
|
||||
this.totalPhotos=totalPhotos;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -39,44 +21,10 @@ public class PhotoStatusDisplayItem extends StatusDisplayItem{
|
||||
return Type.PHOTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getImageCount(){
|
||||
return 1;
|
||||
}
|
||||
public static class Holder extends ImageStatusDisplayItem.Holder<PhotoStatusDisplayItem>{
|
||||
|
||||
@Override
|
||||
public ImageLoaderRequest getImageRequest(int index){
|
||||
return request;
|
||||
}
|
||||
|
||||
public static class Holder extends StatusDisplayItem.Holder<PhotoStatusDisplayItem> implements ImageLoaderViewHolder{
|
||||
public final ImageView photo;
|
||||
public Holder(Activity activity, ViewGroup parent){
|
||||
super(activity, R.layout.display_item_photo, parent);
|
||||
photo=findViewById(R.id.photo);
|
||||
photo.setOnClickListener(this::onViewClick);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(PhotoStatusDisplayItem item){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setImage(int index, Drawable drawable){
|
||||
photo.setImageDrawable(drawable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearImage(int index){
|
||||
photo.setImageDrawable(item.attachment.blurhashPlaceholder);
|
||||
}
|
||||
|
||||
private void onViewClick(View v){
|
||||
if(item.parentFragment instanceof PhotoViewerHost){
|
||||
Status contentStatus=item.status.reblog!=null ? item.status.reblog : item.status;
|
||||
((PhotoViewerHost) item.parentFragment).openPhotoViewer(item.parentID, item.status, contentStatus.mediaAttachments.indexOf(item.attachment));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ public abstract class StatusDisplayItem{
|
||||
case REBLOG_OR_REPLY_LINE -> new ReblogOrReplyLineStatusDisplayItem.Holder(activity, parent);
|
||||
case TEXT -> new TextStatusDisplayItem.Holder(activity, parent);
|
||||
case PHOTO -> new PhotoStatusDisplayItem.Holder(activity, parent);
|
||||
case GIFV -> new GifVStatusDisplayItem.Holder(activity, parent);
|
||||
case FOOTER -> new FooterStatusDisplayItem.Holder(activity, parent);
|
||||
default -> throw new UnsupportedOperationException();
|
||||
};
|
||||
@@ -63,7 +64,7 @@ public abstract class StatusDisplayItem{
|
||||
int photoIndex=0;
|
||||
int totalPhotos=0;
|
||||
for(Attachment attachment:statusForContent.mediaAttachments){
|
||||
if(attachment.type==Attachment.Type.IMAGE){
|
||||
if(attachment.type==Attachment.Type.IMAGE || attachment.type==Attachment.Type.GIFV){
|
||||
totalPhotos++;
|
||||
}
|
||||
}
|
||||
@@ -71,6 +72,9 @@ public abstract class StatusDisplayItem{
|
||||
if(attachment.type==Attachment.Type.IMAGE){
|
||||
items.add(new PhotoStatusDisplayItem(parentID, status, attachment, fragment, photoIndex, totalPhotos));
|
||||
photoIndex++;
|
||||
}else if(attachment.type==Attachment.Type.GIFV){
|
||||
items.add(new GifVStatusDisplayItem(parentID, status, attachment, fragment, photoIndex, totalPhotos));
|
||||
photoIndex++;
|
||||
}
|
||||
}
|
||||
items.add(new FooterStatusDisplayItem(parentID, fragment, statusForContent, accountID));
|
||||
|
||||
@@ -3,10 +3,16 @@ package org.joinmastodon.android.ui.photoviewer;
|
||||
import android.app.Activity;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.TextureView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
@@ -16,6 +22,8 @@ import android.widget.ImageView;
|
||||
|
||||
import org.joinmastodon.android.model.Attachment;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
@@ -28,6 +36,8 @@ import me.grishka.appkit.utils.BindableViewHolder;
|
||||
import me.grishka.appkit.utils.CubicBezierInterpolator;
|
||||
|
||||
public class PhotoViewer implements ZoomPanView.Listener{
|
||||
private static final String TAG="PhotoViewer";
|
||||
|
||||
private Activity activity;
|
||||
private List<Attachment> attachments;
|
||||
private int currentIndex;
|
||||
@@ -37,6 +47,7 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
private FrameLayout windowView;
|
||||
private ViewPager2 pager;
|
||||
private ColorDrawable background=new ColorDrawable(0xff000000);
|
||||
private ArrayList<MediaPlayer> players=new ArrayList<>();
|
||||
|
||||
public PhotoViewer(Activity activity, List<Attachment> attachments, int index, Listener listener){
|
||||
this.activity=activity;
|
||||
@@ -79,7 +90,7 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
int[] radius=new int[4];
|
||||
if(listener.startPhotoViewTransition(index, rect, radius)){
|
||||
RecyclerView rv=(RecyclerView) pager.getChildAt(0);
|
||||
PhotoViewHolder holder=(PhotoViewHolder) rv.findViewHolderForAdapterPosition(index);
|
||||
BaseHolder holder=(BaseHolder) rv.findViewHolderForAdapterPosition(index);
|
||||
holder.zoomPanView.animateIn(rect, radius);
|
||||
}
|
||||
|
||||
@@ -121,7 +132,7 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
int[] radius=new int[4];
|
||||
if(listener.startPhotoViewTransition(index, rect, radius)){
|
||||
RecyclerView rv=(RecyclerView) pager.getChildAt(0);
|
||||
PhotoViewHolder holder=(PhotoViewHolder) rv.findViewHolderForAdapterPosition(index);
|
||||
BaseHolder holder=(BaseHolder) rv.findViewHolderForAdapterPosition(index);
|
||||
holder.zoomPanView.animateOut(rect, radius, velocityY);
|
||||
}else{
|
||||
windowView.animate()
|
||||
@@ -140,6 +151,8 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
|
||||
@Override
|
||||
public void onDismissed(){
|
||||
for(MediaPlayer player:players)
|
||||
player.release();
|
||||
listener.setPhotoViewVisibility(pager.getCurrentItem(), true);
|
||||
wm.removeView(windowView);
|
||||
listener.photoViewerDismissed();
|
||||
@@ -193,16 +206,20 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
void photoViewerDismissed();
|
||||
}
|
||||
|
||||
private class PhotoViewAdapter extends RecyclerView.Adapter<PhotoViewHolder>{
|
||||
private class PhotoViewAdapter extends RecyclerView.Adapter<BaseHolder>{
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public PhotoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
return new PhotoViewHolder();
|
||||
public BaseHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType){
|
||||
return switch(viewType){
|
||||
case 0 -> new PhotoViewHolder();
|
||||
case 1 -> new GifVViewHolder();
|
||||
default -> throw new IllegalStateException("Unexpected value: "+viewType);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull PhotoViewHolder holder, int position){
|
||||
public void onBindViewHolder(@NonNull BaseHolder holder, int position){
|
||||
holder.bind(attachments.get(position));
|
||||
}
|
||||
|
||||
@@ -210,27 +227,63 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
public int getItemCount(){
|
||||
return attachments.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position){
|
||||
Attachment att=attachments.get(position);
|
||||
return switch(att.type){
|
||||
case IMAGE -> 0;
|
||||
case GIFV -> 1;
|
||||
default -> throw new IllegalStateException("Unexpected value: "+att.type);
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(@NonNull BaseHolder holder){
|
||||
super.onViewDetachedFromWindow(holder);
|
||||
if(holder instanceof GifVViewHolder){
|
||||
((GifVViewHolder) holder).reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(@NonNull BaseHolder holder){
|
||||
super.onViewAttachedToWindow(holder);
|
||||
if(holder instanceof GifVViewHolder){
|
||||
((GifVViewHolder) holder).prepareAndStartPlayer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class PhotoViewHolder extends BindableViewHolder<Attachment> implements ViewImageLoader.Target{
|
||||
public ImageView imageView;
|
||||
private abstract class BaseHolder extends BindableViewHolder<Attachment>{
|
||||
public ZoomPanView zoomPanView;
|
||||
|
||||
public PhotoViewHolder(){
|
||||
public BaseHolder(){
|
||||
super(new ZoomPanView(activity));
|
||||
zoomPanView=(ZoomPanView) itemView;
|
||||
zoomPanView.setListener(PhotoViewer.this);
|
||||
itemView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
imageView=new ImageView(activity);
|
||||
((FrameLayout)itemView).addView(imageView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
|
||||
zoomPanView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(Attachment item){
|
||||
zoomPanView.setScrollDirections(getAbsoluteAdapterPosition()>0, getAbsoluteAdapterPosition()<attachments.size()-1);
|
||||
}
|
||||
}
|
||||
|
||||
private class PhotoViewHolder extends BaseHolder implements ViewImageLoader.Target{
|
||||
public ImageView imageView;
|
||||
|
||||
public PhotoViewHolder(){
|
||||
imageView=new ImageView(activity);
|
||||
zoomPanView.addView(imageView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(Attachment item){
|
||||
super.onBind(item);
|
||||
FrameLayout.LayoutParams params=(FrameLayout.LayoutParams) imageView.getLayoutParams();
|
||||
params.width=item.getWidth();
|
||||
params.height=item.getHeight();
|
||||
zoomPanView.setScrollDirections(getAbsoluteAdapterPosition()>0, getAbsoluteAdapterPosition()<attachments.size()-1);
|
||||
ViewImageLoader.load(this, listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition()), new UrlImageLoaderRequest(item.url), false);
|
||||
}
|
||||
|
||||
@@ -244,4 +297,98 @@ public class PhotoViewer implements ZoomPanView.Listener{
|
||||
return imageView;
|
||||
}
|
||||
}
|
||||
|
||||
private class GifVViewHolder extends BaseHolder implements MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener, TextureView.SurfaceTextureListener{
|
||||
public TextureView textureView;
|
||||
public FrameLayout wrap;
|
||||
public MediaPlayer player;
|
||||
private Surface surface;
|
||||
private boolean playerReady;
|
||||
|
||||
public GifVViewHolder(){
|
||||
textureView=new TextureView(activity);
|
||||
wrap=new FrameLayout(activity);
|
||||
zoomPanView.addView(wrap, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
|
||||
wrap.addView(textureView);
|
||||
|
||||
textureView.setSurfaceTextureListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBind(Attachment item){
|
||||
super.onBind(item);
|
||||
playerReady=false;
|
||||
FrameLayout.LayoutParams params=(FrameLayout.LayoutParams) wrap.getLayoutParams();
|
||||
params.width=item.getWidth();
|
||||
params.height=item.getHeight();
|
||||
wrap.setBackground(listener.getPhotoViewCurrentDrawable(getAbsoluteAdapterPosition()));
|
||||
if(itemView.isAttachedToWindow()){
|
||||
prepareAndStartPlayer();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPrepared(MediaPlayer mp){
|
||||
Log.d(TAG, "onPrepared() called with: mp = ["+mp+"]");
|
||||
playerReady=true;
|
||||
if(surface!=null)
|
||||
startPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height){
|
||||
this.surface=new Surface(surface);
|
||||
if(playerReady)
|
||||
startPlayer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface){
|
||||
this.surface=null;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface){
|
||||
|
||||
}
|
||||
|
||||
private void startPlayer(){
|
||||
player.setSurface(surface);
|
||||
player.setLooping(true);
|
||||
player.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onError(MediaPlayer mp, int what, int extra){
|
||||
Log.e(TAG, "gif player onError() called with: mp = ["+mp+"], what = ["+what+"], extra = ["+extra+"]");
|
||||
return false;
|
||||
}
|
||||
|
||||
public void prepareAndStartPlayer(){
|
||||
playerReady=false;
|
||||
player=new MediaPlayer();
|
||||
players.add(player);
|
||||
player.setOnPreparedListener(this);
|
||||
player.setOnErrorListener(this);
|
||||
try{
|
||||
player.setDataSource(activity, Uri.parse(item.url));
|
||||
player.prepareAsync();
|
||||
}catch(IOException x){
|
||||
Log.w(TAG, "Error initializing gif player", x);
|
||||
}
|
||||
}
|
||||
|
||||
public void reset(){
|
||||
playerReady=false;
|
||||
player.release();
|
||||
players.remove(player);
|
||||
player=null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user