textureview onSurfaceTextureAvailable从未在fragment内部调用relativelayout

Ami*_*lko 20 android

从不调用VideoView中的onSurfaceTextureAvailable ...
我有这个持有textureview的视图.

public class MyMediaPlayer extends RelativeLayout{

Context mContext;
VideoView player;//this is a custom textureview that streams video

public MyMediaPlayer(Context context) {
    super(context);
    mContext = context; 
    init();
}
public MyMediaPlayer(Context context, AttributeSet attrs) {
    super(context, attrs);
    mContext = context; 
    init();
}
public MyMediaPlayer(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext = context; 
    init();
}
private void init() {
    setBackgroundColor(Color.BLACK);    
    player = new VideoView(mContext);
    LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
    addView(player,lp);
}
public void setURL(String url){
    player.setVideoPath(url);
}
public void start(){
    player.start();
}

}
Run Code Online (Sandbox Code Playgroud)

VideoView的设置如下:

public class VideoView extends TextureView {

public VideoView(final Context context) {
    super(context);
    mContext = context;
    initVideoView();
}

public VideoView(final Context context, final AttributeSet attrs) {
    super(context, attrs);
    mContext = context;
    initVideoView();
}

public VideoView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    mContext = context;
    initVideoView();
}

public void initVideoView() {
    Log.d(LOG_TAG, "Initializing video view.");
    videoHeight = 0;
    videoWidth = 0;
    setFocusable(false);
    setSurfaceTextureListener(surfaceTextureListener);
}
SurfaceTextureListener surfaceTextureListener = new SurfaceTextureListener() {
    @Override
    public void onSurfaceTextureAvailable(final SurfaceTexture surface, final int width, final int height) {
        Log.d(LOG_TAG, "Surface texture now avaialble.");
        surfaceTexture = surface;
        openVideo();
    }

    @Override
    public void onSurfaceTextureSizeChanged(final SurfaceTexture surface, final int width, final int height) {
        Log.d(LOG_TAG, "Resized surface texture: " + width + '/' + height);
        surfaceWidth = width;
        surfaceHeight = height;
        boolean isValidState =  (targetState == STATE_PLAYING);
        boolean hasValidSize = (videoWidth == width && videoHeight == height);
        if (mediaPlayer != null && isValidState && hasValidSize) {
            start();
        }
    }

    @Override
    public boolean onSurfaceTextureDestroyed(final SurfaceTexture surface) {
        Log.i(LOG_TAG, "Destroyed surface number " + number);
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(final SurfaceTexture surface) {

    }
};
}
Run Code Online (Sandbox Code Playgroud)

MyMediaPlayer设置在xml的片段中.
如果我将VideoView放在片段中,那么一切正常.
但是如果它在mymediaplayer里面,片段onSurfaceTextureAvailable永远不会被调用.

Ste*_*ice 19

onSurfaceTextureAvailable如果SurfaceTexture已经可用,似乎没有被调用.您可以检查它是否可用并按onSurfaceTextureAvailable如下方式调用您的方法.

textureView.setSurfaceTextureListener(this);

/*
 * onSurfaceTextureAvailable does not get called if it is already available.
 */
if (view.isAvailable()) {
    onSurfaceTextureAvailable(view.getSurfaceTexture(), view.getWidth(), view.getHeight());
}
Run Code Online (Sandbox Code Playgroud)

  • 在你的上下文中是什么`view`? (8认同)
  • 我认为`view`应该与第一行的`textureView`相同. (5认同)
  • 如果在表面可用后调用`setSurfaceTextureListener`,则不会得到`onSurfaceTextureAvailable`回调. (3认同)

小智 15

至于我,解决问题的关键是为AndroidManifest.xml中的活动添加android:hardwareAccelerated ="true".

只有在具有hardwareAccelerated属性的TextureView的活动时,才可以在Scrolling-Container(如ListView,ScrollView,ViewPager等)中使用TextureView.

这篇博客的最后几句话提到了这一点

希望对你有效.

  • 我的问题是通过手动调用`onSurfaceTextureAvailable`来解决的.我不认为设置`hardwareAccelerated ="true"`会帮助很多新项目,因为[Target API level> = 14]默认启用硬件加速(http://developer.android.com/guide/topics/图形/硬件accel.html). (2认同)

Tas*_*iwa 8

在我的情况下,我最初让我的TextureView隐形,然后在获取一些数据后加载,这导致onSurfaceTextureAvailable不被调用.我猜想,为了TextureView被称为"可用",它必须是可见的.我的解决方案是TextureView从一开始就让它变得可见.


小智 7

您需要启用硬件加速才能使用TextureView.如果不这样做,则不会调用其回调方法.只需在你的活动的onCreate方法中噘嘴:

getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
Run Code Online (Sandbox Code Playgroud)

它对我有用.


Ran*_*hak 3

我遇到了同样的问题,奇怪的是用以下代码解决了它

videoPreview = (TextureView) linearLayout.findViewById(R.id.videoView);
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)videoPreview.getLayoutParams();
params.height = 130;
params.width = 508;
videoPreview.setLayoutParams(params);
videoPreview.setSurfaceTextureListener(this);
Run Code Online (Sandbox Code Playgroud)

更奇怪的是,如果我只设置宽度或高度,则不起作用。

  • 这个解决方案对我有用,但这种情况是由于一个更大的问题造成的:视图没有正确布局。父布局视图(自定义 ViewGroup)未在纹理视图的父级上正确调用 View.measure(...) 。我只需要修复我的 ViewGroup 控件。 (4认同)