Java 从内部类:Fragment访问时查看null

Java 从内部类:Fragment访问时查看null,java,android,android-youtube-api,Java,Android,Android Youtube Api,我已经为android采集了示例应用程序VideoListDemoActivityclass,并将其转换为fragment,以便在我的应用程序中使用 在内部类VideoListFragment中,访问来自fragment的视图videoBox,该视图返回null。在活动中,视图不为null,但在片段中,它无法获取片段视图的引用。我已经附上了我为这个类修改的代码 错误异常 2021-04-28 16:42:18.695 27495-27495/com.gardify.android E/Andro

我已经为android采集了示例应用程序
VideoListDemoActivity
class,并将其转换为
fragment
,以便在我的应用程序中使用

在内部类
VideoListFragment
中,访问来自fragment的视图
videoBox
,该视图返回
null
。在活动中,视图不为null,但在片段中,它无法获取片段视图的引用。我已经附上了我为这个类修改的代码

错误异常

2021-04-28 16:42:18.695 27495-27495/com.gardify.android E/AndroidRuntime:致命异常:主 进程:com.gardify.android,PID:27495 java.lang.NullPointerException:尝试对空对象引用调用虚拟方法“int android.view.view.getVisibility()” 在com.gardify.android.ui.video.VideoFragment$VideoListFragment.onListItemClick(VideoFragment.java:192)上

修改类

public final class VideoFragment extends Fragment {

    /**
     * The duration of the animation sliding up the video in portrait.
     */
    private static final int ANIMATION_DURATION_MILLIS = 300;
    /**
     * The padding between the video list and the video in landscape orientation.
     */
    private static final int LANDSCAPE_VIDEO_PADDING_DP = 5;

    /**
     * The request code when calling startActivityForResult to recover from an API service error.
     */
    private static final int RECOVERY_DIALOG_REQUEST = 1;

    private VideoListFragment listFragment;
    private YoutubeFragment videoFragment;

    private View videoBox;
    private View closeButton;

    private View root;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        root = inflater.inflate(R.layout.video_fragment, container, false);

        videoBox = root.findViewById(R.id.video_box);
        closeButton = root.findViewById(R.id.close_button);

        videoBox.setVisibility(View.INVISIBLE);

        return root;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        listFragment = (VideoListFragment) getActivity().getFragmentManager().findFragmentById(R.id.list_fragment);
        videoFragment = (YoutubeFragment) getActivity().getFragmentManager().findFragmentById(R.id.video_fragment_container);
        checkYouTubeApi();

    }

    private void checkYouTubeApi() {
        YouTubeInitializationResult errorReason =
                YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(getActivity());
        if (errorReason.isUserRecoverableError()) {
            errorReason.getErrorDialog(getActivity(), RECOVERY_DIALOG_REQUEST).show();
        } else if (errorReason != YouTubeInitializationResult.SUCCESS) {
            String errorMessage = getResources().getString(R.string.an_error_occurred);
            Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RECOVERY_DIALOG_REQUEST) {
            // Recreate the activity if user performed a recovery action
            getActivity().recreate();
        }
    }

    public void onClickClose(@SuppressWarnings("unused") View view) {
        listFragment.getListView().clearChoices();
        listFragment.getListView().requestLayout();
        videoFragment.pause();
        ViewPropertyAnimator animator = videoBox.animate()
                .translationYBy(videoBox.getHeight())
                .setDuration(ANIMATION_DURATION_MILLIS);
        runOnAnimationEnd(animator, new Runnable() {
            @Override
            public void run() {
                videoBox.setVisibility(View.INVISIBLE);
            }
        });
    }

    @TargetApi(16)
    private void runOnAnimationEnd(ViewPropertyAnimator animator, final Runnable runnable) {
        if (Build.VERSION.SDK_INT >= 16) {
            animator.withEndAction(runnable);
        } else {
            animator.setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    runnable.run();
                }
            });
        }
    }

    /**
     * A fragment that shows a static list of videos.
     */
    public static final class VideoListFragment extends ListFragment {

        private static final List<VideoEntry> VIDEO_LIST;

        static {
            List<VideoEntry> list = new ArrayList<VideoEntry>();
            list.add(new VideoEntry("YouTube Collection", "Y_UmWdcTrrc"));
            list.add(new VideoEntry("GMail Tap", "1KhZKNZO8mQ"));
            list.add(new VideoEntry("Chrome Multitask", "UiLSiqyDf4Y"));
            list.add(new VideoEntry("Google Fiber", "re0VRK6ouwI"));
            list.add(new VideoEntry("Autocompleter", "blB_X38YSxQ"));
            list.add(new VideoEntry("GMail Motion", "Bu927_ul_X0"));
            list.add(new VideoEntry("Translate for Animals", "3I24bSteJpw"));
            VIDEO_LIST = Collections.unmodifiableList(list);
        }

        private PageAdapter adapter;
        private View videoBox;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            adapter = new PageAdapter(getActivity(), VIDEO_LIST);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            videoBox = getView().findViewById(R.id.video_box);
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            setListAdapter(adapter);
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            String videoId = VIDEO_LIST.get(position).videoId;

            YoutubeFragment videoFragment = (YoutubeFragment) getFragmentManager().findFragmentById(R.id.video_fragment_container);

            videoFragment.setVideoId(videoId);

            // The videoBox is INVISIBLE if no video was previously selected, so we need to show it now.
            if (videoBox.getVisibility() != View.VISIBLE) {
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    // Initially translate off the screen so that it can be animated in from below.
                    videoBox.setTranslationY(videoBox.getHeight());
                }
                videoBox.setVisibility(View.VISIBLE);
            }

            // If the fragment is off the screen, we animate it in.
            if (videoBox.getTranslationY() > 0) {
                videoBox.animate().translationY(0).setDuration(ANIMATION_DURATION_MILLIS);
            }
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();

            adapter.releaseLoaders();
        }

        public void setLabelVisibility(boolean visible) {
            adapter.setLabelVisibility(visible);
        }

    }

    /**
     * Adapter for the video list. Manages a set of YouTubeThumbnailViews, including initializing each
     * of them only once and keeping track of the loader of each one. When the ListFragment gets
     * destroyed it releases all the loaders.
     */
    private static final class PageAdapter extends BaseAdapter {

        private final List<VideoEntry> entries;
        private final List<View> entryViews;
        private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
        private final LayoutInflater inflater;
        private final ThumbnailListener thumbnailListener;

        private boolean labelsVisible;

        public PageAdapter(Context context, List<VideoEntry> entries) {
            this.entries = entries;

            entryViews = new ArrayList<View>();
            thumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>();
            inflater = LayoutInflater.from(context);
            thumbnailListener = new ThumbnailListener();

            labelsVisible = true;
        }

        public void releaseLoaders() {
            for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap.values()) {
                loader.release();
            }
        }

        public void setLabelVisibility(boolean visible) {
            labelsVisible = visible;
            for (View view : entryViews) {
                view.findViewById(R.id.text).setVisibility(visible ? View.VISIBLE : View.GONE);
            }
        }

        @Override
        public int getCount() {
            return entries.size();
        }

        @Override
        public VideoEntry getItem(int position) {
            return entries.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            VideoEntry entry = entries.get(position);

            // There are three cases here
            if (view == null) {
                // 1) The view has not yet been created - we need to initialize the YouTubeThumbnailView.
                view = inflater.inflate(R.layout.video_list_item, parent, false);
                YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.thumbnail);
                thumbnail.setTag(entry.videoId);
                thumbnail.initialize(DeveloperKey.YOUTUBE_API_DEVELOPER_KEY, thumbnailListener);
            } else {
                YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.thumbnail);
                YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(thumbnail);
                if (loader == null) {
                    // 2) The view is already created, and is currently being initialized. We store the
                    //    current videoId in the tag.
                    thumbnail.setTag(entry.videoId);
                } else {
                    // 3) The view is already created and already initialized. Simply set the right videoId
                    //    on the loader.
                    //thumbnail.setImageResource(R.drawable.loading_thumbnail);
                    loader.setVideo(entry.videoId);
                }
            }
            TextView label = ((TextView) view.findViewById(R.id.text));
            label.setText(entry.text);
            label.setVisibility(labelsVisible ? View.VISIBLE : View.GONE);
            return view;
        }

        private final class ThumbnailListener implements
                YouTubeThumbnailView.OnInitializedListener,
                YouTubeThumbnailLoader.OnThumbnailLoadedListener {

            @Override
            public void onInitializationSuccess(
                    YouTubeThumbnailView view, YouTubeThumbnailLoader loader) {
                loader.setOnThumbnailLoadedListener(this);
                thumbnailViewToLoaderMap.put(view, loader);
                view.setImageResource(R.drawable.loading_thumbnail);
                String videoId = (String) view.getTag();
                loader.setVideo(videoId);
            }

            @Override
            public void onInitializationFailure(
                    YouTubeThumbnailView view, YouTubeInitializationResult loader) {
                view.setImageResource(R.drawable.no_thumbnail);
            }

            @Override
            public void onThumbnailLoaded(YouTubeThumbnailView view, String videoId) {
            }

            @Override
            public void onThumbnailError(YouTubeThumbnailView view, ErrorReason errorReason) {
                view.setImageResource(R.drawable.no_thumbnail);
            }
        }

    }

    public static final class YoutubeFragment extends YouTubePlayerFragment
            implements OnInitializedListener {

        private YouTubePlayer player;
        private String videoId;

        public static YoutubeFragment newInstance() {
            return new YoutubeFragment();
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            initialize(DeveloperKey.YOUTUBE_API_DEVELOPER_KEY, this);
        }

        @Override
        public void onDestroy() {
            if (player != null) {
                player.release();
            }
            super.onDestroy();
        }

        public void setVideoId(String videoId) {
            if (videoId != null && !videoId.equals(this.videoId)) {
                this.videoId = videoId;
                if (player != null) {
                    player.cueVideo(videoId);
                }
            }
        }

        public void pause() {
            if (player != null) {
                player.pause();
            }
        }

        @Override
        public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean restored) {
            this.player = player;
        }

        @Override
        public void onInitializationFailure(Provider provider, YouTubeInitializationResult result) {
            this.player = null;
        }

    }

    private static final class VideoEntry {
        private final String text;
        private final String videoId;

        public VideoEntry(String text, String videoId) {
            this.text = text;
            this.videoId = videoId;
        }
    }


}
公共最终类VideoFragment扩展片段{
/**
*沿纵向向上滑动视频的动画持续时间。
*/
私有静态最终整数动画\u持续时间\u毫秒=300;
/**
*视频列表和视频之间的横向填充。
*/
专用静态最终整数横向\视频\填充\ DP=5;
/**
*调用startActivityForResult以从API服务错误中恢复时的请求代码。
*/
私有静态最终整数恢复对话框请求=1;
私有视频列表片段列表片段;
私人YoutubeFragment视频片段;
私视电视盒;
私人视图关闭按钮;
私有视图根;
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
根=充气机。充气(R.layout.video_碎片,容器,假);
videoBox=root.findviewbyd(R.id.video\u-box);
closeButton=root.findviewbyd(R.id.close\u按钮);
videoBox.setVisibility(视图.不可见);
返回根;
}
@凌驾
已创建公用void onview(@NonNull视图,@Nullable Bundle savedInstanceState){
super.onViewCreated(视图,savedInstanceState);
listFragment=(VideoListFragment)getActivity().getFragmentManager().findFragmentById(R.id.list_fragment);
videoFragment=(YoutubeFragment)getActivity().getFragmentManager().findFragmentById(R.id.video\u fragment\u容器);
检查youtubeapi();
}
私有void checkYouTubeApi(){
YouTube初始化结果错误原因=
YouTubeApiServiceUtil.youtubeapiserviceavailable(getActivity());
if(errorReason.isUserRecoverableError()){
errorReason.getErrorDialog(getActivity(),RECOVERY_DIALOG_REQUEST).show();
}else if(errorReason!=YouTubeInitializationResult.SUCCESS){
String errorMessage=getResources().getString(R.String.a\u发生错误);
Toast.makeText(getActivity(),errorMessage,Toast.LENGTH_LONG).show();
}
}
@凌驾
ActivityResult上的公共void(int请求代码、int结果代码、意图数据){
if(requestCode==恢复对话框请求){
//如果用户执行了恢复操作,请重新创建活动
getActivity().重新创建();
}
}
public void onClickClose(@SuppressWarnings(“未使用”)视图){
listFragment.getListView().clearChoices();
listFragment.getListView().requestLayout();
暂停();
ViewPropertyAnimator animator=videoBox.animate()
.translationBy(videoBox.getHeight())
.setDuration(动画持续时间);
runOnAnimationEnd(动画师,新Runnable(){
@凌驾
公开募捐{
videoBox.setVisibility(视图.不可见);
}
});
}
@塔吉塔皮(16)
私有void runOnAnimationEnd(ViewPropertyAnimator animator,最终可运行){
如果(Build.VERSION.SDK_INT>=16){
动画师。withEndAction(可运行);
}否则{
setListener(新的AnimatorListenerAdapter(){
@凌驾
AnimationEnd上的公共无效(Animator动画){
runnable.run();
}
});
}
}
/**
*显示静态视频列表的片段。
*/
公共静态最终类VideoListFragment扩展ListFragment{
私有静态最终列表视频_列表;
静止的{
列表=新的ArrayList();
添加(新的视频条目(“YouTube收藏”、“Y_UmWdcTrrc”);
添加(新的视频条目(“GMail点击”,“1KhZKNZO8mQ”);
添加(新的视频条目(“Chrome多任务”、“UiLSiqyDf4Y”);
添加(新的视频条目(“谷歌光纤”、“re0VRK6ouwI”);
添加(新的视频输入(“自动完成器”、“blB_X38YSxQ”);
添加(新的视频条目(“GMail动态”,“Bu927_ul_X0”);
添加(新的视频条目(“动物翻译”、“3I24bSteJpw”);
视频列表=集合。不可修改列表(列表);
}
专用页面适配器;
私视电视盒;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
adapter=新页面适配器(getActivity(),视频列表);
}
@凌驾
已创建ActivityState上的公共无效(Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
videoBox=getView().findviewbyd(R.id.video\u-box);
getListView().setChoiceMode(ListView.CHOICE\u MODE\u SINGLE);
setListAdapter(适配器);
}
@凌驾
public void onListItemClick(列表视图l、视图v、整数位置、长id){
字符串videoId=VIDEO_LIST.get(position).videoId;
YoutubeFragment videoFragment=(YoutubeFragment)getFragmentManager().fi
public final class VideoFragment extends Fragment {

    /**
     * The duration of the animation sliding up the video in portrait.
     */
    private static final int ANIMATION_DURATION_MILLIS = 300;
    /**
     * The padding between the video list and the video in landscape orientation.
     */
    private static final int LANDSCAPE_VIDEO_PADDING_DP = 5;

    /**
     * The request code when calling startActivityForResult to recover from an API service error.
     */
    private static final int RECOVERY_DIALOG_REQUEST = 1;

    private VideoListFragment listFragment;
    private YoutubeFragment videoFragment;

    private View videoBox;
    private View closeButton;

    private View root;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        root = inflater.inflate(R.layout.video_fragment, container, false);

        videoBox = root.findViewById(R.id.video_box);
        closeButton = root.findViewById(R.id.close_button);

        videoBox.setVisibility(View.INVISIBLE);

        return root;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        listFragment = (VideoListFragment) getActivity().getFragmentManager().findFragmentById(R.id.list_fragment);
        videoFragment = (YoutubeFragment) getActivity().getFragmentManager().findFragmentById(R.id.video_fragment_container);
        checkYouTubeApi();

    }

    private void checkYouTubeApi() {
        YouTubeInitializationResult errorReason =
                YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(getActivity());
        if (errorReason.isUserRecoverableError()) {
            errorReason.getErrorDialog(getActivity(), RECOVERY_DIALOG_REQUEST).show();
        } else if (errorReason != YouTubeInitializationResult.SUCCESS) {
            String errorMessage = getResources().getString(R.string.an_error_occurred);
            Toast.makeText(getActivity(), errorMessage, Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == RECOVERY_DIALOG_REQUEST) {
            // Recreate the activity if user performed a recovery action
            getActivity().recreate();
        }
    }

    public void onClickClose(@SuppressWarnings("unused") View view) {
        listFragment.getListView().clearChoices();
        listFragment.getListView().requestLayout();
        videoFragment.pause();
        ViewPropertyAnimator animator = videoBox.animate()
                .translationYBy(videoBox.getHeight())
                .setDuration(ANIMATION_DURATION_MILLIS);
        runOnAnimationEnd(animator, new Runnable() {
            @Override
            public void run() {
                videoBox.setVisibility(View.INVISIBLE);
            }
        });
    }

    @TargetApi(16)
    private void runOnAnimationEnd(ViewPropertyAnimator animator, final Runnable runnable) {
        if (Build.VERSION.SDK_INT >= 16) {
            animator.withEndAction(runnable);
        } else {
            animator.setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    runnable.run();
                }
            });
        }
    }

    /**
     * A fragment that shows a static list of videos.
     */
    public static final class VideoListFragment extends ListFragment {

        private static final List<VideoEntry> VIDEO_LIST;

        static {
            List<VideoEntry> list = new ArrayList<VideoEntry>();
            list.add(new VideoEntry("YouTube Collection", "Y_UmWdcTrrc"));
            list.add(new VideoEntry("GMail Tap", "1KhZKNZO8mQ"));
            list.add(new VideoEntry("Chrome Multitask", "UiLSiqyDf4Y"));
            list.add(new VideoEntry("Google Fiber", "re0VRK6ouwI"));
            list.add(new VideoEntry("Autocompleter", "blB_X38YSxQ"));
            list.add(new VideoEntry("GMail Motion", "Bu927_ul_X0"));
            list.add(new VideoEntry("Translate for Animals", "3I24bSteJpw"));
            VIDEO_LIST = Collections.unmodifiableList(list);
        }

        private PageAdapter adapter;
        private View videoBox;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            adapter = new PageAdapter(getActivity(), VIDEO_LIST);
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);

            videoBox = getView().findViewById(R.id.video_box);
            getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            setListAdapter(adapter);
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            String videoId = VIDEO_LIST.get(position).videoId;

            YoutubeFragment videoFragment = (YoutubeFragment) getFragmentManager().findFragmentById(R.id.video_fragment_container);

            videoFragment.setVideoId(videoId);

            // The videoBox is INVISIBLE if no video was previously selected, so we need to show it now.
            if (videoBox.getVisibility() != View.VISIBLE) {
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                    // Initially translate off the screen so that it can be animated in from below.
                    videoBox.setTranslationY(videoBox.getHeight());
                }
                videoBox.setVisibility(View.VISIBLE);
            }

            // If the fragment is off the screen, we animate it in.
            if (videoBox.getTranslationY() > 0) {
                videoBox.animate().translationY(0).setDuration(ANIMATION_DURATION_MILLIS);
            }
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();

            adapter.releaseLoaders();
        }

        public void setLabelVisibility(boolean visible) {
            adapter.setLabelVisibility(visible);
        }

    }

    /**
     * Adapter for the video list. Manages a set of YouTubeThumbnailViews, including initializing each
     * of them only once and keeping track of the loader of each one. When the ListFragment gets
     * destroyed it releases all the loaders.
     */
    private static final class PageAdapter extends BaseAdapter {

        private final List<VideoEntry> entries;
        private final List<View> entryViews;
        private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
        private final LayoutInflater inflater;
        private final ThumbnailListener thumbnailListener;

        private boolean labelsVisible;

        public PageAdapter(Context context, List<VideoEntry> entries) {
            this.entries = entries;

            entryViews = new ArrayList<View>();
            thumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>();
            inflater = LayoutInflater.from(context);
            thumbnailListener = new ThumbnailListener();

            labelsVisible = true;
        }

        public void releaseLoaders() {
            for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap.values()) {
                loader.release();
            }
        }

        public void setLabelVisibility(boolean visible) {
            labelsVisible = visible;
            for (View view : entryViews) {
                view.findViewById(R.id.text).setVisibility(visible ? View.VISIBLE : View.GONE);
            }
        }

        @Override
        public int getCount() {
            return entries.size();
        }

        @Override
        public VideoEntry getItem(int position) {
            return entries.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = convertView;
            VideoEntry entry = entries.get(position);

            // There are three cases here
            if (view == null) {
                // 1) The view has not yet been created - we need to initialize the YouTubeThumbnailView.
                view = inflater.inflate(R.layout.video_list_item, parent, false);
                YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.thumbnail);
                thumbnail.setTag(entry.videoId);
                thumbnail.initialize(DeveloperKey.YOUTUBE_API_DEVELOPER_KEY, thumbnailListener);
            } else {
                YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.thumbnail);
                YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(thumbnail);
                if (loader == null) {
                    // 2) The view is already created, and is currently being initialized. We store the
                    //    current videoId in the tag.
                    thumbnail.setTag(entry.videoId);
                } else {
                    // 3) The view is already created and already initialized. Simply set the right videoId
                    //    on the loader.
                    //thumbnail.setImageResource(R.drawable.loading_thumbnail);
                    loader.setVideo(entry.videoId);
                }
            }
            TextView label = ((TextView) view.findViewById(R.id.text));
            label.setText(entry.text);
            label.setVisibility(labelsVisible ? View.VISIBLE : View.GONE);
            return view;
        }

        private final class ThumbnailListener implements
                YouTubeThumbnailView.OnInitializedListener,
                YouTubeThumbnailLoader.OnThumbnailLoadedListener {

            @Override
            public void onInitializationSuccess(
                    YouTubeThumbnailView view, YouTubeThumbnailLoader loader) {
                loader.setOnThumbnailLoadedListener(this);
                thumbnailViewToLoaderMap.put(view, loader);
                view.setImageResource(R.drawable.loading_thumbnail);
                String videoId = (String) view.getTag();
                loader.setVideo(videoId);
            }

            @Override
            public void onInitializationFailure(
                    YouTubeThumbnailView view, YouTubeInitializationResult loader) {
                view.setImageResource(R.drawable.no_thumbnail);
            }

            @Override
            public void onThumbnailLoaded(YouTubeThumbnailView view, String videoId) {
            }

            @Override
            public void onThumbnailError(YouTubeThumbnailView view, ErrorReason errorReason) {
                view.setImageResource(R.drawable.no_thumbnail);
            }
        }

    }

    public static final class YoutubeFragment extends YouTubePlayerFragment
            implements OnInitializedListener {

        private YouTubePlayer player;
        private String videoId;

        public static YoutubeFragment newInstance() {
            return new YoutubeFragment();
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            initialize(DeveloperKey.YOUTUBE_API_DEVELOPER_KEY, this);
        }

        @Override
        public void onDestroy() {
            if (player != null) {
                player.release();
            }
            super.onDestroy();
        }

        public void setVideoId(String videoId) {
            if (videoId != null && !videoId.equals(this.videoId)) {
                this.videoId = videoId;
                if (player != null) {
                    player.cueVideo(videoId);
                }
            }
        }

        public void pause() {
            if (player != null) {
                player.pause();
            }
        }

        @Override
        public void onInitializationSuccess(Provider provider, YouTubePlayer player, boolean restored) {
            this.player = player;
        }

        @Override
        public void onInitializationFailure(Provider provider, YouTubeInitializationResult result) {
            this.player = null;
        }

    }

    private static final class VideoEntry {
        private final String text;
        private final String videoId;

        public VideoEntry(String text, String videoId) {
            this.text = text;
            this.videoId = videoId;
        }
    }


}
<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <fragment
      class="com.gardify.android.ui.video.VideoFragment$VideoListFragment"
      android:id="@+id/list_fragment"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

  <LinearLayout
      android:id="@+id/video_box"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"

      android:layout_gravity="bottom"
      android:orientation="vertical">

    <ImageButton
        android:id="@+id/close_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:src="@android:drawable/btn_dialog"
        android:onClick="onClickClose"/>

    <fragment
        class="com.gardify.android.ui.video.VideoFragment$YoutubeFragment"
        android:id="@+id/video_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

  </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>