android – SurfaceView在PopupWindow中无法正常工作

前端之家收集整理的这篇文章主要介绍了android – SurfaceView在PopupWindow中无法正常工作前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我将使用基于三星SPen的AirView功能的PopupWindow显示预览

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

显示弹出窗口时,表面区域变为透明,因为根本不创建表面.

SurfaceView未创建且透明:

HoverPreview:

  1. public class HoverPreview extends LinearLayout implements View.OnHoverListener,SurfaceHolder.Callback {
  2. private static final String TAG = "HoverPreview";
  3. private SurfaceHolder mHolder = null;
  4. View mAnchorView = null;
  5. String videoPath;
  6. int position;
  7. private boolean IsMediaPlayerReady = false;
  8. private MediaPlayer mMediaPlayer;
  9. private SurfaceView mSurfaceView;
  10. Context context;
  11. public HoverPreview(Context context,String videoPath,int position) {
  12. super(context);
  13. this.videoPath = videoPath;
  14. this.position = position;
  15. setupLayout(context);
  16. }
  17. public HoverPreview(Context context,AttributeSet attrs) {
  18. super(context,attrs);
  19. setupLayout(context);
  20. }
  21. public HoverPreview(Context context,AttributeSet attrs,int defStyle) {
  22. super(context,attrs,defStyle);
  23. setupLayout(context);
  24. }
  25. private void setupLayout(Context context) {
  26. this.context = context;
  27. LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  28. inflater.inflate(R.layout.media_browser_hover,this);
  29. }
  30. @Override
  31. protected void onFinishInflate() {
  32. super.onFinishInflate();
  33. }
  34. @Override
  35. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  36. Log.d(TAG,"HoverSurface created");
  37. final Surface surface = surfaceHolder.getSurface();
  38. if (surface == null) return;
  39. if (!surface.isValid()) return;
  40. mHolder = surfaceHolder;
  41. mMediaPlayer = new MediaPlayer();
  42. try {
  43. mMediaPlayer.setDataSource(videoPath);
  44. } catch (IOException e) {
  45. e.printStackTrace();
  46. }
  47. mMediaPlayer.setDisplay(mHolder);
  48. mAnchorView.setTag(mMediaPlayer);
  49. mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
  50. @Override
  51. public void onVideoSizeChanged(MediaPlayer mediaPlayer,int i,int i2) {
  52. mHolder.setFixedSize(i,i2);
  53. }
  54. });
  55. mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  56. @Override
  57. public void onPrepared(MediaPlayer mediaPlayer) {
  58. Log.d(TAG,"MediaPlayer preview is prepared");
  59. IsMediaPlayerReady = true;
  60. if (mMediaPlayer != null && IsMediaPlayerReady) {
  61. if (position > 0)
  62. mMediaPlayer.seekTo(position);
  63. mMediaPlayer.start();
  64. }
  65. }
  66. });
  67. Log.d(TAG,"MediaPlayer is created");
  68. try {
  69. mMediaPlayer.prepare();
  70. } catch (IOException e) {
  71. e.printStackTrace();
  72. }
  73. }
  74. @Override
  75. public void surfaceChanged(SurfaceHolder surfaceHolder,int i2,int i3) {
  76. Log.d(TAG,"HoverSurface changed");
  77. }
  78. @Override
  79. public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
  80. Log.d(TAG,"HoverSurface destroyed");
  81. if (mMediaPlayer != null) {
  82. mMediaPlayer.stop();
  83. mMediaPlayer.release();
  84. //thumbnailImageView.setTag(null);
  85. }
  86. }
  87. public void setAnchorView(View view) {
  88. mAnchorView = view;
  89. }
  90. @Override
  91. public boolean onHover(View view,MotionEvent motionEvent) {
  92. try {
  93. if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
  94. Log.d(TAG,"ACTION_HOVER_ENTER");
  95. mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
  96. mHolder = mSurfaceView.getHolder();
  97. if (mHolder != null) {
  98. mHolder.addCallback(this);
  99. }
  100. } else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
  101. Log.d(TAG,"ACTION_HOVER_EXIT");
  102. if (mAnchorView.getTag() != null) {
  103. MediaPlayer mMediaPlayer = (MediaPlayer) mAnchorView.getTag();
  104. mMediaPlayer.stop();
  105. mMediaPlayer.release();
  106. mAnchorView.setTag(null);
  107. }
  108. }
  109. } catch (Exception e) {
  110. Log.e(TAG,e.getMessage() + Utils.toString(e.getStackTrace()));
  111. }
  112. return false;
  113. }
  114. }

显示预览的代码

  1. final PopupWindow popupWindow = new PopupWindow(context);
  2. final HoverPreview hoverPreview = new HoverPreview(context,videoPath,0);
  3. hoverPreview.setAnchorView(thumbnailImageView);
  4. thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
  5. @Override
  6. public boolean onHover(View view,MotionEvent motionEvent) {
  7. hoverPreview.onHover(view,motionEvent);
  8. if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_ENTER) {
  9. popupWindow.setContentView(hoverPreview);
  10. popupWindow.setWidth(600);
  11. popupWindow.setHeight(400);
  12. popupWindow.showAtLocation(thumbnailImageView,ToolHoverPopup.Gravity.NO_GRAVITY,10,10);
  13. Log.d(TAG,"Manual Hover Enter");
  14. } else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
  15. Log.d(TAG,"Manual Hover Exit");
  16. if (popupWindow != null)
  17. popupWindow.dismiss();
  18. }
  19. return true;
  20. });
最佳答案
这是我完整的工作解决方案:

我从SPen库中借用了ToolHoverPopup类中的一些代码,我也为这个特殊的弹出窗口进行了自定义,以便在实际悬停发生之前不会创建或膨胀任何内容,这样我们就不会消耗资源来在列表中启用这样的预览.

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

截图(SurfaceView已创建)

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

  1. thumbnailImageView.setOnHoverListener(new View.OnHoverListener() {
  2. @Override
  3. public boolean onHover(View view,MotionEvent motionEvent) {
  4. HoverPreview hoverPreview;
  5. if (thumbnailImageView.getTag() == null) {
  6. hoverPreview = new HoverPreview(context,getActivity().getWindow(),0);
  7. hoverPreview.setHoverDetectTime(1000);
  8. thumbnailImageView.setTag(hoverPreview);
  9. } else
  10. hoverPreview = (HoverPreview) thumbnailImageView.getTag();
  11. hoverPreview.onHover(null,motionEvent);
  12. if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT)
  13. thumbnailImageView.setTag(null);
  14. return true;
  15. }
  16. });

HoverPreview:

  1. public class HoverPreview extends LinearLayout implements View.OnHoverListener,SurfaceHolder.Callback {
  2. private static final int MSG_SHOW_POPUP = 1;
  3. private static final int MSG_DISMISS_POPUP = 2;
  4. private static final int HOVER_DETECT_TIME_MS = 300;
  5. private static final int POPUP_TIMEOUT_MS = 60 * 1000;
  6. protected int mHoverDetectTimeMS;
  7. private static final String TAG = "HoverPreview";
  8. private SurfaceHolder mHolder = null;
  9. String videoPath;
  10. int position;
  11. private boolean IsMediaPlayerReady = false;
  12. private MediaPlayer mMediaPlayer;
  13. private SurfaceView mSurfaceView;
  14. Context context;
  15. private HoverPopupHandler mHandler;
  16. Window window;
  17. public HoverPreview(Context context,Window window,int position) {
  18. super(context);
  19. this.mHoverDetectTimeMS = HOVER_DETECT_TIME_MS;
  20. this.videoPath = videoPath;
  21. this.position = position;
  22. this.window = window;
  23. setupLayout(context);
  24. }
  25. private void setupLayout(Context context) {
  26. this.context = context;
  27. LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  28. rootView = inflater.inflate(R.layout.media_browser_hover,this);
  29. mSurfaceView = (SurfaceView) findViewById(R.id.media_browser_hoverSurfaceView);
  30. }
  31. View rootView;
  32. @Override
  33. protected void onFinishInflate() {
  34. super.onFinishInflate();
  35. }
  36. @Override
  37. public void surfaceCreated(SurfaceHolder surfaceHolder) {
  38. Log.d(TAG,"HoverSurface created");
  39. final Surface surface = surfaceHolder.getSurface();
  40. if (surface == null) return;
  41. if (!surface.isValid()) return;
  42. mHolder = surfaceHolder;
  43. mMediaPlayer = new MediaPlayer();
  44. try {
  45. mMediaPlayer.setDataSource(videoPath);
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. return;
  49. }
  50. mMediaPlayer.setDisplay(mHolder);
  51. mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
  52. @Override
  53. public void onPrepared(MediaPlayer mediaPlayer) {
  54. Log.d(TAG,"MediaPlayer preview is prepared");
  55. IsMediaPlayerReady = true;
  56. int videoWidth = mMediaPlayer.getVideoWidth();
  57. int videoHeight = mMediaPlayer.getVideoHeight();
  58. Point size = new Point();
  59. int screenHeight = 0;
  60. int screenWidth = 0;
  61. Display display = getDisplay();
  62. display.getSize(size);
  63. screenWidth = size.x - (350 + 30); // margin + padding
  64. screenHeight = size.y;
  65. FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mSurfaceView.getLayoutParams();
  66. lp.width = screenWidth;
  67. lp.height = (int) (((float) videoHeight / (float) videoWidth) * (float) screenWidth);
  68. mSurfaceView.setLayoutParams(lp);
  69. if (mMediaPlayer != null && IsMediaPlayerReady) {
  70. if (position > 0)
  71. mMediaPlayer.seekTo(position);
  72. mMediaPlayer.start();
  73. findViewById(R.id.media_browser_hoverRootFrameLayout).setVisibility(VISIBLE);
  74. }
  75. }
  76. });
  77. Log.d(TAG,"HoverSurface destroyed");
  78. try {
  79. if (mMediaPlayer != null) {
  80. mMediaPlayer.stop();
  81. mMediaPlayer.release();
  82. }
  83. } catch (Exception e) {
  84. }
  85. }
  86. @Override
  87. public boolean onHover(View view,"ACTION_HOVER_ENTER");
  88. show(); // checks the timing
  89. } else if (motionEvent.getAction() == MotionEvent.ACTION_HOVER_EXIT) {
  90. Log.d(TAG,"ACTION_HOVER_EXIT");
  91. dismiss();
  92. }
  93. } catch (Exception e) {
  94. Log.e(TAG,e.getMessage() + Utils.toString(e.getStackTrace()));
  95. }
  96. return false;
  97. }
  98. /**
  99. * Sets the time that detecting hovering.
  100. *
  101. * @param ms The time,milliseconds
  102. */
  103. public void setHoverDetectTime(int ms) {
  104. mHoverDetectTimeMS = ms;
  105. }
  106. public void dismiss() {
  107. dismissPopup();
  108. }
  109. private void dismissPopup() {
  110. // remove pending message and dismiss popup
  111. getMyHandler().removeMessages(MSG_SHOW_POPUP);
  112. getMyHandler().removeMessages(MSG_DISMISS_POPUP);
  113. try {
  114. if (mMediaPlayer != null) {
  115. mMediaPlayer.stop();
  116. mMediaPlayer.release();
  117. }
  118. } catch (Exception e) {
  119. }
  120. if (getParent() != null)
  121. ((ViewGroup) getParent()).removeView(this);
  122. }
  123. private Handler getMyHandler() {
  124. if (mHandler == null)
  125. mHandler = new HoverPopupHandler();
  126. return mHandler;
  127. }
  128. public void show() {
  129. // send message to show.
  130. if (getMyHandler().hasMessages(MSG_SHOW_POPUP)) {
  131. return;
  132. // getHandler().removeMessages(MSG_SHOW_POPUP);
  133. }
  134. getMyHandler().sendEmptyMessageDelayed(MSG_SHOW_POPUP,mHoverDetectTimeMS);
  135. }
  136. private void showPopup() {
  137. if (getParent() == null) {
  138. final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
  139. WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.MATCH_PARENT,WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,PixelFormat.TRANSLUCENT);
  140. params.gravity = Gravity.CENTER_VERTICAL;
  141. params.x = 350;
  142. window.addContentView(this,params);
  143. }
  144. mHolder = mSurfaceView.getHolder();
  145. if (mHolder != null) {
  146. mHolder.addCallback(this);
  147. }
  148. }
  149. ;
  150. private class HoverPopupHandler extends Handler {
  151. @Override
  152. public void handleMessage(Message msg) {
  153. // if (DEBUG)
  154. // android.util.Log.e(TAG,"handleMessage : " + ((msg.what == MSG_SHOW_POPUP) ? "SHOW" : "DISMISS"));
  155. switch (msg.what) {
  156. case MSG_SHOW_POPUP:
  157. showPopup();
  158. sendEmptyMessageDelayed(MSG_DISMISS_POPUP,POPUP_TIMEOUT_MS);
  159. break;
  160. case MSG_DISMISS_POPUP:
  161. dismissPopup();
  162. break;
  163. }
  164. }
  165. }
  166. }

猜你在找的Android相关文章