How to prevent resize below original size?
Setting "minScale='1'" does not do it. You can still resize below the original TextureView size, which looks very odd and also glitches badly if you have a light theme background.
I have figured out how to set the original view's parameters to maintain the aspect ratio (which for a SurfaceView appears to initialize properly automatically, but does not for a TextureView even with orientation set explicitly to vertical) but I cannot find the original scale value of the view in initView and, if someone tries to resize the view smaller than that cap the scale to the original level when the view was established.
It appears that "minScale" and "maxScale" are intended to prevent this but they don't -- the code looks right in onScale but isn't preventing the problem.
In addition it would be nice to have a double-tap reset scaling to the original value.
Example code demonstrating the problem -- play something in landscape and try to pinch it smaller. You can't. Then pinch zoom it LARGER, then back to smaller below the original "fills the screen" width. You should not be able to with the minScale set to 1 but you can in fact shrink the view below the screen width.
package net.cudasystems.android.videotest;
import android.net.Uri;
import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.TextureView;
import com.google.android.exoplayer2.DefaultLoadControl;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
public class MainActivity extends AppCompatActivity {
private String mURL = "http://point-at-an-mp4 -file";
TextureView mPlayerView;
SimpleExoPlayer player = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPlayerView = findViewById(R.id.video_view);
}
private void initializePlayer() {
DefaultRenderersFactory renderersFactory =
new DefaultRenderersFactory(this, DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON);
player = ExoPlayerFactory.newSimpleInstance(
renderersFactory,
new DefaultTrackSelector(), new DefaultLoadControl());
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
// Make sure the initial aspect ratio is 16:9 (otherwise a TextureView init's to the LARGER of
// the two dimensions of the video irrespective of the orientation setting and screws the aspect ratio!)
int width = metrics.widthPixels;
int newHeight = (width * 9) / 16;
mPlayerView.setLayoutParams(new ConstraintLayout.LayoutParams(width, newHeight));
player.setVideoTextureView(mPlayerView);
mPlayerView.invalidate();
player.setPlayWhenReady(true);
Uri uri = Uri.parse(mURL);
MediaSource mediaSource = buildMediaSource(uri);
player.prepare(mediaSource, true, true);
}
private MediaSource buildMediaSource(Uri uri) {
return new ExtractorMediaSource.Factory(
new DefaultHttpDataSourceFactory("exoplayer-codelab")).
createMediaSource(uri);
}
@Override
public void onStart() {
super.onStart();
if (Util.SDK_INT > 23) {
if (player == null) {
initializePlayer();
}
}
}
@Override
public void onResume() {
super.onResume();
if ((Util.SDK_INT <= 23 || player == null)) {
initializePlayer();
}
}
@Override
public void onPause() {
super.onPause();
if (Util.SDK_INT <= 23) {
releasePlayer();
}
}
@Override
public void onStop() {
super.onStop();
if (Util.SDK_INT > 23) {
releasePlayer();
}
}
private void releasePlayer() {
if (player != null) {
player.release();
player = null;
}
}
}
and the XML for this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/root"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:keepScreenOn="true">
<ua.polohalo.zoomabletextureview.ZoomableTextureView
android:id="@+id/video_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
app:maxScale="4"
app:minScale="1"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Does This work?"
android:textColor="@android:color/holo_red_dark"
app:layout_constraintBottom_toBottomOf="parent" />
</android.support.constraint.ConstraintLayout>
Ok, this is bizarre. With one source I cannot make it misbehave, with another I can..... looking into why now...
Found it -- if you rotate the device you're hosed. This appears to be related to use in a fragment (which is where one of my use cases is and why it didn't show up with some sources and instances of my attempts to use it but did with others); onRestoreInstanceState is not called on rotation in that case, and minScale winds up being zero. This obvious hack around this problem is to recognize the zero value and set it to "1.0f", but I'll see if I can come up with a better answer.
Me too
Biggest issue right now is figuring out why a "reset to default" (double-tap) isn't working correctly. I get the correct size but not the correct 0,0 x/y origin back -- and am not at all sure why.
Pull request sent.
@tickerguy : If Is it possible take a look at to my issue.