toro icon indicating copy to clipboard operation
toro copied to clipboard

Initial deformed video height

Open Mahmoud-S-Ali opened this issue 6 years ago • 2 comments

Hi @eneim. First of all I really like your library. Thanks for the great work.

I'm experiencing an issue with some video heights when being loaded for the first time. So if I have a list of videos and the first video turned out to have a large height. It starts with the min_height and then being resized to the proper height once the video starts which is expected. If I scroll down to another video that has a smaller height. It doesn't load with the min height, but with the previous video height (which was larger) then is resized to the proper height once the video starts. To show you what I mean.

This is an image of the first video in the list: 20181112_095816

Image of a following video before it starts: 20181112_095756

The following video after starting and being resized: 20181112_095734

And the strange thing that this behavior doesn't occur with all the following videos. Only some random ones.

  • I'm using Toro 3.6.1.2802
  • Tested it on Samsung S8 Android 8.0.0

Here's my xml code:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/margin_small" android:layout_marginTop="@dimen/margin_small" android:orientation="vertical">

<include
    layout="@layout/content_comic_poster_info"
    android:background="@color/colorPrimaryDark" />

<TextView
    android:id="@+id/tv_comic_caption"
    style="@style/Text_Header1_Bold_Light"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:gravity="center"
    android:paddingBottom="@dimen/margin_medium"
    android:paddingLeft="@dimen/margin_large"
    android:paddingRight="@dimen/margin_large"
    android:paddingTop="@dimen/margin_medium"
    android:textColor="@color/black_op87"
    android:visibility="gone"
    tools:text="Once upon a time, I was walking in the street" />

<RelativeLayout
    android:id="@+id/layout_comic_videoRoot"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.exoplayer2.ui.PlayerView
        android:id="@+id/player_comic_contentVideo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="200dp"
        app:resize_mode="fixed_width"
        app:surface_type="surface_view"
        app:use_controller="false">

        <ImageView
            android:id="@+id/iv_comic_videoThumbnail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter" />
    </com.google.android.exoplayer2.ui.PlayerView>


    <ProgressBar
        android:id="@+id/progressbar_comic_loading"
        android:layout_width="@dimen/ic_size_large"
        android:layout_height="@dimen/ic_size_large"
        android:layout_centerInParent="true"
        android:background="@drawable/shape_circle_black_transparent"
        android:indeterminateDrawable="@drawable/progressbar_background"
        android:visibility="invisible" />

    <ImageButton
        android:id="@+id/ib_comic_videoPlayIcon"
        android:layout_width="@dimen/ic_size_large"
        android:layout_height="@dimen/ic_size_large"
        android:layout_centerInParent="true"
        android:background="@drawable/shape_circle_black_transparent"
        android:paddingLeft="2dp"
        android:scaleType="center"
        app:srcCompat="@drawable/ic_play" />

    <FrameLayout
        android:id="@+id/layout_comic_likeImage"
        android:layout_width="@dimen/likeImage_size"
        android:layout_height="@dimen/likeImage_size"
        android:layout_centerInParent="true"
        android:layout_margin="@dimen/margin_medium"
        android:background="@drawable/shape_circular_gradient"
        android:visibility="invisible">

        <ImageView
            android:id="@+id/iv_comic_likeImage"
            android:layout_width="@dimen/likeImage_size"
            android:layout_height="@dimen/likeImage_size"
            app:srcCompat="@drawable/ic_like_active" />
    </FrameLayout>
</RelativeLayout>

<include layout="@layout/content_comic_actions" />

Do you have any thoughts what could be causing this or any ideas on how to avoid it? Thanks in advance

Mahmoud-S-Ali avatar Nov 12 '18 08:11 Mahmoud-S-Ali

Hi @Mahmoud-S-Ali , you issue is kinda about how RecyclerView (RV) works in general. Let me explain it below:

  • A ViewHolder (VH) is reused by RV, which is what makes RV so great.
  • This recycling is also the cause of your trouble: saying a VH "A" is bound for your tall Video. After measuring and playing, it reaches the height as expected. After you scroll enough, this VH "A" is recycled, and rebound to other short Video. Initially, the VH has the LayoutParams of its previous state, which contains the height of the tall Video --> this is why your VH doesn't start from min_height.

The best solution, is that you control the Video's height information (or also width, if possible). If so, you can improve it as follow:

  • Wrap the PlayerView by an AspectRatioFrameLayout.
  • When you bind the ViewHolder, and you know the Video's aspect ratio beforehand, you can set this aspect ratio to the AspectRatioFrameLayout.

This way, it will correctly measure and layout the ViewHolder with expected aspect ratio/height.

If you don't control the Video's aspect ratio information, and you want the VH start with min_height, you can manually reset the height when you bind the ViewHolder.

eneim avatar Nov 12 '18 09:11 eneim

Thanks a lot for the quick and detailed reply. Keep the awesome work man :)

Mahmoud-S-Ali avatar Nov 12 '18 09:11 Mahmoud-S-Ali