2013-12-16 38 views
5

不工作我會使用顯示預覽PopupWindow基礎上,AirView功能三星SPENSurfaceView內PopupWindow

但問題是,是不是創造了SurfaceView和的SurfaceHolder.Callback方法不被調用。

當彈出窗口被顯示時,表面區域變得透明,因爲表面根本沒有被創建。

SurfaceView不創建並且是透明的:

enter image description here

HoverPreview

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; 
}); 
+0

你可以從'HoverPreview'發佈創建者和'onHover'例程嗎?另外,什麼類是'HoverPreview'構建的? –

+0

@NeilTownsend,發佈了完整的代碼和屏幕截圖 –

+0

是否調用了'surfaceCreated'? –

回答

4

這裏是我的完整工作解決方案:

我借了一些代碼ToolHoverPopup類從SPEN庫,我也定製了這個特殊的彈出這樣,任何創建或充氣,直到實際懸停發生,使我們不消耗資源以在列表中啓用這樣的預覽。

我們需要把我們的預覽連接到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; 
      } 
     }); 

HoverPreview

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; 
      } 
     } 
    } 
}