gpt4 book ai didi

android - SurfaceView 在 PopupWindow 中不工作

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:46:19 29 4
gpt4 key购买 nike

我将使用基于 AirViewPopupWindow 显示预览三星SPen的特点

但问题是 SurfaceView 没有创建,也没有调用 SurfaceHolder.Callback 方法。

当显示弹出窗口时,表面区域变得透明,因为根本没有创建表面。

SurfaceView 未创建并且是透明的:

enter image description here

悬停预览:

public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {
private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
View mAnchorView = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;

public HoverPreview(Context context, String videoPath, int position) {
super(context);
this.videoPath = videoPath;
this.position = position;
setupLayout(context);
}

public HoverPreview(Context context, AttributeSet attrs) {
super(context, attrs);
setupLayout(context);
}

public HoverPreview(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupLayout(context);
}

private void setupLayout(Context context) {
this.context = context;
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.media_browser_hover, this);
}

@Override
protected void onFinishInflate() {
super.onFinishInflate();
}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");

final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;

mHolder = surfaceHolder;

mMediaPlayer = new MediaPlayer();

try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
}

mMediaPlayer.setDisplay(mHolder);
mAnchorView.setTag(mMediaPlayer);

mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
@Override
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int i, int i2) {
mHolder.setFixedSize(i, i2);
}
});

mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;

if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
}
}
});

Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
//thumbnailImageView.setTag(null);
}
}

public void setAnchorView(View view) {
mAnchorView = view;
}

@Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");

mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);

mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}

} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
if (mAnchorView.getTag() != null) {
MediaPlayer mMediaPlayer = (MediaPlayer) mAnchorView.getTag();
mMediaPlayer.stop();
mMediaPlayer.release();
mAnchorView.setTag(null);
}
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}
}

显示预览的代码:

final PopupWindow popupWindow = new PopupWindow(context);
final HoverPreview hoverPreview = new HoverPreview(context, videoPath, 0);
hoverPreview.setAnchorView(thumbnailImageView);
thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
@Override
public boolean onHover(View view, MotionEvent motionEvent) {
hoverPreview.onHover(view, motionEvent);
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
popupWindow.setContentView(hoverPreview);
popupWindow.setWidth(600);
popupWindow.setHeight(400);
popupWindow.showAtLocation(thumbnailImageView, ToolHoverPopup.Gravity.NO_GRAVITY, 10, 10);
Log.d(TAG, "Manual Hover Enter");
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "Manual Hover Exit");
if (popupWindow != null)
popupWindow.dismiss();
}
return true;
});

最佳答案

这是我完整的工作解决方案:

我从 SPen 库的 ToolHoverPopup 类中借用了一些代码,我还为这个特殊的弹出窗口定制了一些代码,以便在实际悬停发生之前不会创建或膨胀任何东西,这样我们就不会消耗资源在列表中启用此类预览。

我们需要将预览附加到 Window,因此我们必须管理所有通常由 PopupWindow 完成的底层定位工作,所以我完全消除了对 PopupWindow 的依赖,现在我的 HoverPreview 类可以正常工作并管理所有作业,它还能够确定悬停检测延迟(以毫秒为单位)。

截图(SurfaceView已创建)

enter image description here

用法:(由于布局包含SurfaceView并且是资源密集型的,我手动触发onHover事件,以便只有在执行真正的悬停时才执行真正的表面创建. 此外,我不会在需要之前创建任何 HoverPreview 对象)

        thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
@Override
public boolean onHover(View view, MotionEvent motionEvent) {
HoverPreview hoverPreview;
if (thumbnailImageView.getTag() == null) {
hoverPreview = new HoverPreview(context, getActivity().getWindow(), videoPath, 0);
hoverPreview.setHoverDetectTime(1000);
thumbnailImageView.setTag(hoverPreview);
} else
hoverPreview = (HoverPreview) thumbnailImageView.getTag();

hoverPreview.onHover(null, motionEvent);

if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT)
thumbnailImageView.setTag(null);

return true;
}
});

悬停预览:

public class HoverPreview extends LinearLayout implements View.OnHoverListener, SurfaceHolder.Callback {

private static final int MSG_SHOW_POPUP = 1;

private static final int MSG_DISMISS_POPUP = 2;

private static final int HOVER_DETECT_TIME_MS = 300;

private static final int POPUP_TIMEOUT_MS = 60 * 1000;

protected int mHoverDetectTimeMS;

private static final String TAG = "HoverPreview";
private SurfaceHolder mHolder = null;
String videoPath;
int position;
private boolean IsMediaPlayerReady = false;
private MediaPlayer mMediaPlayer;
private SurfaceView mSurfaceView;
Context context;
private HoverPopupHandler mHandler;
Window window;

public HoverPreview(Context context, Window window, String videoPath, int position) {
super(context);
this.mHoverDetectTimeMS = HOVER_DETECT_TIME_MS;
this.videoPath = videoPath;
this.position = position;
this.window = window;
setupLayout(context);
}

private void setupLayout(Context context) {
this.context = context;

LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rootView = inflater.inflate(R.layout.media_browser_hover, this);

mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
}

View rootView;

@Override
protected void onFinishInflate() {
super.onFinishInflate();
}

@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface created");

final Surface surface = surfaceHolder.getSurface();
if (surface == null) return;
if (!surface.isValid()) return;

mHolder = surfaceHolder;

mMediaPlayer = new MediaPlayer();

try {
mMediaPlayer.setDataSource(videoPath);
} catch (IOException e) {
e.printStackTrace();
return;
}

mMediaPlayer.setDisplay(mHolder);

mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.d(TAG, "MediaPlayer preview is prepared");
IsMediaPlayerReady = true;

int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
Point size = new Point();
int screenHeight = 0;
int screenWidth = 0;
Display display = getDisplay();

display.getSize(size);
screenWidth = size.x - (350 + 30); // margin + padding
screenHeight = size.y;

FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView.getLayoutParams();

lp.width = screenWidth;
lp.height = (int) (((float) videoHeight / (float) videoWidth) * (float) screenWidth);
mSurfaceView.setLayoutParams(lp);

if (mMediaPlayer != null && IsMediaPlayerReady) {
if (position > 0)
mMediaPlayer.seekTo(position);
mMediaPlayer.start();
findViewById(R.id.media_browser_hoverRootFrameLayout).setVisibility(VISIBLE);
}
}
});

Log.d(TAG, "MediaPlayer is created");
try {
mMediaPlayer.prepare();
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
Log.d(TAG, "HoverSurface changed");
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
Log.d(TAG, "HoverSurface destroyed");
try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {

}
}

@Override
public boolean onHover(View view, MotionEvent motionEvent) {
try {
if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
Log.d(TAG, "ACTION_HOVER_ENTER");
show(); // checks the timing
} else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
Log.d(TAG, "ACTION_HOVER_EXIT");
dismiss();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage() + Utils.toString(e.getStackTrace()));
}
return false;
}

/**
* Sets the time that detecting hovering.
*
* @param ms The time, milliseconds
*/
public void setHoverDetectTime(int ms) {
mHoverDetectTimeMS = ms;
}

public void dismiss() {
dismissPopup();
}

private void dismissPopup() {
// remove pending message and dismiss popup
getMyHandler().removeMessages(MSG_SHOW_POPUP);
getMyHandler().removeMessages(MSG_DISMISS_POPUP);

try {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
} catch (Exception e) {

}

if (getParent() != null)
((ViewGroup) getParent()).removeView(this);
}

private Handler getMyHandler() {
if (mHandler == null)
mHandler = new HoverPopupHandler();
return mHandler;
}

public void show() {
// send message to show.
if (getMyHandler().hasMessages(MSG_SHOW_POPUP)) {
return;
// getHandler().removeMessages(MSG_SHOW_POPUP);
}
getMyHandler().sendEmptyMessageDelayed(MSG_SHOW_POPUP, mHoverDetectTimeMS);
}

private void showPopup() {
if (getParent() == null) {
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
PixelFormat.TRANSLUCENT);

params.gravity = Gravity.CENTER_VERTICAL;
params.x = 350;

window.addContentView(this, params);
}

mHolder = mSurfaceView.getHolder();
if (mHolder != null) {
mHolder.addCallback(this);
}
}

;

private class HoverPopupHandler extends Handler {

@Override
public void handleMessage(Message msg) {

// if (DEBUG)
// android.util.Log.e(TAG, "handleMessage : " + ((msg.what == MSG_SHOW_POPUP) ? "SHOW" : "DISMISS"));

switch (msg.what) {
case MSG_SHOW_POPUP:
showPopup();
sendEmptyMessageDelayed(MSG_DISMISS_POPUP, POPUP_TIMEOUT_MS);
break;
case MSG_DISMISS_POPUP:
dismissPopup();
break;
}
}
}
}

关于android - SurfaceView 在 PopupWindow 中不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20608875/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com