Java TabHost&x2B;Youtube播放器列表API:使用startService的隐式意图不安全

Java TabHost&x2B;Youtube播放器列表API:使用startService的隐式意图不安全,java,android,youtube,Java,Android,Youtube,你什么都试了,但还是失败了 如果我尝试不使用TabHost,它将非常有效。我需要的是在标签中显示youtube上的视频列表。但这一进程无法启动。 多谢各位 点击 MainActivity.java package z.YoutubeAPI.List.zyoulistlayouts.app; import android.app.TabActivity; import android.content.Intent; import android.os.Bundle; import android

你什么都试了,但还是失败了

如果我尝试不使用TabHost,它将非常有效。我需要的是在标签中显示youtube上的视频列表。但这一进程无法启动。 多谢各位

点击

MainActivity.java

package z.YoutubeAPI.List.zyoulistlayouts.app;

import android.app.TabActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TabHost;



public class MainActivity extends TabActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // create the TabHost that will contain the Tabs
        final TabHost tabHost = getTabHost();

        TabHost.TabSpec tab1 = tabHost.newTabSpec("First Tab");
        TabHost.TabSpec tab2 = tabHost.newTabSpec("Second Tab");
        TabHost.TabSpec tab3 = tabHost.newTabSpec("Third tab");

        // Set the Tab name and Activity
        // that will be opened when particular Tab will be selected
        tab1.setIndicator("Tab1");
        Intent intent = new Intent(this,Tab1Activity.class);
        tab1.setContent(intent);

        tab2.setIndicator("Tab2");
        tab2.setContent(new Intent(this,Tab2Activity.class));

        tab3.setIndicator("Tab3");
        tab3.setContent(new Intent(this,Tab3Activity.class));

        tabHost.addTab(tab1);
        tabHost.addTab(tab2);
        tabHost.addTab(tab3);



    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
        }
    }
Tab1Activity.java——Youtube Android播放器API列表

    package z.YoutubeAPI.List.zyoulistlayouts.app;


import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ListFragment;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.OnFullscreenListener;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

public final class Tab1Activity extends Activity implements OnFullscreenListener{

    /** 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;

    private VideoListFragment listFragment;
    private VideoFragment videoFragment;

    private View videoBox;
    private View closeButton;

    private boolean isFullscreen;

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab1);


        listFragment = (VideoListFragment) getFragmentManager().findFragmentById(R.id.list_fragment);
        videoFragment =
                (VideoFragment) getFragmentManager().findFragmentById(R.id.video_fragment_container);

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

        videoBox.setVisibility(View.INVISIBLE);

        layout();
    }

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);

            layout();
        }

        @Override
        public void onFullscreen(boolean isFullscreen) {
            this.isFullscreen = isFullscreen;

            layout();
        }

        /**
         * Sets up the layout programatically for the three different states. Portrait, landscape or
         * fullscreen+landscape. This has to be done programmatically because we handle the orientation
         * changes ourselves in order to get fluent fullscreen transitions, so the xml layout resources
         * do not get reloaded.
         */
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        private void layout() {
            boolean isPortrait =
                    getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

            listFragment.getView().setVisibility(isFullscreen ? View.GONE : View.VISIBLE);
            listFragment.setLabelVisibility(isPortrait);
            closeButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE);

            if (isFullscreen) {
                videoBox.setTranslationY(0); // Reset any translation that was applied in portrait.
                setLayoutSize(videoFragment.getView(), MATCH_PARENT, MATCH_PARENT);
                setLayoutSizeAndGravity(videoBox, MATCH_PARENT, MATCH_PARENT, Gravity.TOP | Gravity.LEFT);
            } else if (isPortrait) {
                setLayoutSize(listFragment.getView(), MATCH_PARENT, MATCH_PARENT);
                setLayoutSize(videoFragment.getView(), MATCH_PARENT, WRAP_CONTENT);
                setLayoutSizeAndGravity(videoBox, MATCH_PARENT, WRAP_CONTENT, Gravity.BOTTOM);
            } else {
                videoBox.setTranslationY(0); // Reset any translation that was applied in portrait.
                int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
                setLayoutSize(listFragment.getView(), screenWidth / 4, MATCH_PARENT);
                int videoWidth = screenWidth - screenWidth / 4 - dpToPx(LANDSCAPE_VIDEO_PADDING_DP);
                setLayoutSize(videoFragment.getView(), videoWidth, WRAP_CONTENT);
                setLayoutSizeAndGravity(videoBox, videoWidth, WRAP_CONTENT,
                        Gravity.RIGHT | Gravity.CENTER_VERTICAL);
            }
        }

        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        public void onClickClose(@SuppressWarnings("unused") View view) {
            listFragment.getListView().clearChoices();
            listFragment.getListView().requestLayout();
            videoFragment.pause();
            videoBox.animate()
                    .translationYBy(videoBox.getHeight())
                    .setDuration(ANIMATION_DURATION_MILLIS)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            videoBox.setVisibility(View.INVISIBLE);
                        }
                    });
        }

/**
 * A fragment that shows a static list of videos.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
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("Video 1", "VdlDMmEtps8"));
        list.add(new VideoEntry("GMail Tap", "VdlDMmEtps8"));
        list.add(new VideoEntry("Chrome Multitask", "VdlDMmEtps8"));
        list.add(new VideoEntry("Google Fiber", "VdlDMmEtps8"));
        list.add(new VideoEntry("Autocompleter", "VdlDMmEtps8"));
        list.add(new VideoEntry("GMail Motion", "VdlDMmEtps8"));
        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 = getActivity().findViewById(R.id.video_box);
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        setListAdapter(adapter);
    }

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

        VideoFragment videoFragment =
                (VideoFragment) 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.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, YouTubeThumbnailLoader.ErrorReason errorReason) {
            view.setImageResource(R.drawable.no_thumbnail);
        }
    }

}

public static final class VideoFragment extends YouTubePlayerFragment
        implements YouTubePlayer.OnInitializedListener {

    private YouTubePlayer player;
    private String videoId;

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

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

        initialize(DeveloperKey.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(YouTubePlayer.Provider provider, YouTubePlayer player, boolean restored) {
        this.player = player;
        player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT);
        player.setOnFullscreenListener((Tab1Activity) getActivity());
        if (!restored && videoId != null) {
            player.cueVideo(videoId);
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.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;
    }
}

    // Utility methods for layouting.

    private int dpToPx(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
    }

    private static void setLayoutSize(View view, int width, int height) {
        ViewGroup.LayoutParams params = view.getLayoutParams();
        params.width = width;
        params.height = height;
        view.setLayoutParams(params);
    }

    private static void setLayoutSizeAndGravity(View view, int width, int height, int gravity) {
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
        params.width = width;
        params.height = height;
        params.gravity = gravity;
        view.setLayoutParams(params);
    }

}
package z.YoutubeAPI.List.zyoulistlaypes.app;
导入android.annotation.TargetApi;
导入android.app.Activity;
导入android.app.ListFragment;
导入android.content.Context;
导入android.content.res.Configuration;
导入android.os.Build;
导入android.os.Bundle;
导入android.view.Gravity;
导入android.view.LayoutInflater;
导入android.view.view;
导入android.view.ViewGroup;
导入android.widget.BaseAdapter;
导入android.widget.FrameLayout;
导入android.widget.ListView;
导入android.widget.TextView;
导入com.google.android.youtube.player.youtube初始化结果;
导入com.google.android.youtube.player.YouTubePlayer;
导入com.google.android.youtube.player.youtubeplyer.onFullScreenStener;
导入com.google.android.youtube.player.YouTubePlayerFragment;
导入com.google.android.youtube.player.YouTubeThumbnailLoader;
导入com.google.android.youtube.player.YouTubeThumbnailView;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入静态android.view.ViewGroup.LayoutParams.MATCH_父项;
导入静态android.view.ViewGroup.LayoutParams.WRAP_内容;
公共最终类Tab1Activity扩展了FullScreenListener上的活动实现{
/**沿纵向向上滑动视频的动画持续时间*/
私有静态最终整数动画\u持续时间\u毫秒=300;
/**视频列表和视频之间的横向填充*/
专用静态最终整数横向\视频\填充\ DP=5;
私有视频列表片段列表片段;
私人视频片段;
私视电视盒;
私人视图关闭按钮;
全屏显示私有布尔值;
@TargetApi(构建版本代码蜂窝)
@凌驾
创建时的公共void(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.tab1);
listFragment=(VideoListFragment)getFragmentManager().findFragmentById(R.id.list_fragment);
视频片段=
(VideoFragment)getFragmentManager().findFragmentById(R.id.video\u fragment\u容器);
videoBox=findviewbyd(R.id.video\u box);
closeButton=findViewById(R.id.close_按钮);
videoBox.setVisibility(视图.不可见);
布局();
}
@凌驾
公共无效OnConfiguration已更改(配置newConfig){
super.onConfigurationChanged(newConfig);
布局();
}
@凌驾
全屏上的公共无效(布尔值为全屏){
this.isFullscreen=isFullscreen;
布局();
}
/**
*以编程方式设置三种不同状态的布局。纵向、横向或纵向
*全屏+横向。这必须以编程方式完成,因为我们处理方向
*改变我们自己,以获得流畅的全屏转换,因此xml布局资源
*不要重新加载。
*/
@TargetApi(构建版本代码蜂窝)
私人空间布局(){
布尔isPortrait=
getResources().getConfiguration().orientation==Configuration.orientation\u纵向;
listFragment.getView().setVisibility(isFullscreen?View.GONE:View.VISIBLE);
setLabelVisibility(isPortrait);
closeButton.setVisibility(isPortrait?View.VISIBLE:View.GONE);
如果(全屏显示){
videoBox.setTranslationY(0);//重置应用于纵向的任何平移。
setLayoutSize(videoFragment.getView(),匹配父项,匹配父项);
setLayoutSizeAndGravity(视频框,匹配父项,匹配父项,Gravity.TOP | Gravity.LEFT);
}否则如果(isPortrait){
setLayoutSize(listFragment.getView(),匹配父项,匹配父项);
setLayoutSize(videoFragment.getView(),匹配父项,包装内容);
setLayoutSizeAndGravity(视频框、匹配父项、换行内容、Gravity.BOTTOM);
}否则{
videoBox.setTranslationY(0);//重置应用于纵向的任何平移。
int screenWidth=dpToPx(getResources().getConfiguration().screenWidthDp);
setLayoutSize(listFragment.getView(),屏幕宽度/4,匹配父项);
int videoWidth=screenWidth-screenWidth/4-dpToPx(横向视频填充DP);
setLayoutSize(videoFragment.getView()、videoWidth、包装内容);
设置LayoutSizeAndGravity(视频框、视频宽度、包裹内容、,
重力.右|重力.中心|垂直);
}
}
@TargetApi(Build.VERSION\u code.JELLY\u BEAN)
public void onClickClose(@SuppressWarnings(“未使用”)视图){
listFragment.getListView().clearChoices();
listFragment.getListView().requestLayout();
暂停();
videoBox.animate()
.translationBy(videoBox.getHeight())
.setDuration(动画持续时间)
.withEndAction(新的可运行(){
@凌驾
公开募捐{
videoBox.setVisibility(视图.不可见);
}
});
}
/**
*显示静态视频列表的片段。
*/
@TargetApi(构建版本代码蜂窝)
公共静态最终类视频列表Fragmen
    package z.YoutubeAPI.List.zyoulistlayouts.app;


import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ListFragment;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.OnFullscreenListener;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

public final class Tab1Activity extends Activity implements OnFullscreenListener{

    /** 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;

    private VideoListFragment listFragment;
    private VideoFragment videoFragment;

    private View videoBox;
    private View closeButton;

    private boolean isFullscreen;

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.tab1);


        listFragment = (VideoListFragment) getFragmentManager().findFragmentById(R.id.list_fragment);
        videoFragment =
                (VideoFragment) getFragmentManager().findFragmentById(R.id.video_fragment_container);

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

        videoBox.setVisibility(View.INVISIBLE);

        layout();
    }

        @Override
        public void onConfigurationChanged(Configuration newConfig) {
            super.onConfigurationChanged(newConfig);

            layout();
        }

        @Override
        public void onFullscreen(boolean isFullscreen) {
            this.isFullscreen = isFullscreen;

            layout();
        }

        /**
         * Sets up the layout programatically for the three different states. Portrait, landscape or
         * fullscreen+landscape. This has to be done programmatically because we handle the orientation
         * changes ourselves in order to get fluent fullscreen transitions, so the xml layout resources
         * do not get reloaded.
         */
        @TargetApi(Build.VERSION_CODES.HONEYCOMB)
        private void layout() {
            boolean isPortrait =
                    getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;

            listFragment.getView().setVisibility(isFullscreen ? View.GONE : View.VISIBLE);
            listFragment.setLabelVisibility(isPortrait);
            closeButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE);

            if (isFullscreen) {
                videoBox.setTranslationY(0); // Reset any translation that was applied in portrait.
                setLayoutSize(videoFragment.getView(), MATCH_PARENT, MATCH_PARENT);
                setLayoutSizeAndGravity(videoBox, MATCH_PARENT, MATCH_PARENT, Gravity.TOP | Gravity.LEFT);
            } else if (isPortrait) {
                setLayoutSize(listFragment.getView(), MATCH_PARENT, MATCH_PARENT);
                setLayoutSize(videoFragment.getView(), MATCH_PARENT, WRAP_CONTENT);
                setLayoutSizeAndGravity(videoBox, MATCH_PARENT, WRAP_CONTENT, Gravity.BOTTOM);
            } else {
                videoBox.setTranslationY(0); // Reset any translation that was applied in portrait.
                int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp);
                setLayoutSize(listFragment.getView(), screenWidth / 4, MATCH_PARENT);
                int videoWidth = screenWidth - screenWidth / 4 - dpToPx(LANDSCAPE_VIDEO_PADDING_DP);
                setLayoutSize(videoFragment.getView(), videoWidth, WRAP_CONTENT);
                setLayoutSizeAndGravity(videoBox, videoWidth, WRAP_CONTENT,
                        Gravity.RIGHT | Gravity.CENTER_VERTICAL);
            }
        }

        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        public void onClickClose(@SuppressWarnings("unused") View view) {
            listFragment.getListView().clearChoices();
            listFragment.getListView().requestLayout();
            videoFragment.pause();
            videoBox.animate()
                    .translationYBy(videoBox.getHeight())
                    .setDuration(ANIMATION_DURATION_MILLIS)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            videoBox.setVisibility(View.INVISIBLE);
                        }
                    });
        }

/**
 * A fragment that shows a static list of videos.
 */
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
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("Video 1", "VdlDMmEtps8"));
        list.add(new VideoEntry("GMail Tap", "VdlDMmEtps8"));
        list.add(new VideoEntry("Chrome Multitask", "VdlDMmEtps8"));
        list.add(new VideoEntry("Google Fiber", "VdlDMmEtps8"));
        list.add(new VideoEntry("Autocompleter", "VdlDMmEtps8"));
        list.add(new VideoEntry("GMail Motion", "VdlDMmEtps8"));
        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 = getActivity().findViewById(R.id.video_box);
        getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
        setListAdapter(adapter);
    }

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

        VideoFragment videoFragment =
                (VideoFragment) 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.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, YouTubeThumbnailLoader.ErrorReason errorReason) {
            view.setImageResource(R.drawable.no_thumbnail);
        }
    }

}

public static final class VideoFragment extends YouTubePlayerFragment
        implements YouTubePlayer.OnInitializedListener {

    private YouTubePlayer player;
    private String videoId;

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

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

        initialize(DeveloperKey.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(YouTubePlayer.Provider provider, YouTubePlayer player, boolean restored) {
        this.player = player;
        player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT);
        player.setOnFullscreenListener((Tab1Activity) getActivity());
        if (!restored && videoId != null) {
            player.cueVideo(videoId);
        }
    }

    @Override
    public void onInitializationFailure(YouTubePlayer.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;
    }
}

    // Utility methods for layouting.

    private int dpToPx(int dp) {
        return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
    }

    private static void setLayoutSize(View view, int width, int height) {
        ViewGroup.LayoutParams params = view.getLayoutParams();
        params.width = width;
        params.height = height;
        view.setLayoutParams(params);
    }

    private static void setLayoutSizeAndGravity(View view, int width, int height, int gravity) {
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
        params.width = width;
        params.height = height;
        params.gravity = gravity;
        view.setLayoutParams(params);
    }

}
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">


<fragment
    class="z.YoutubeAPI.List.zyoulistlayouts.app.Tab1Activity$VideoListFragment"
    android:id="@+id/list_fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

<LinearLayout
    android:id="@+id/video_box"
    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="z.YoutubeAPI.List.zyoulistlayouts.app.Tab1Activity$VideoFragment"
        android:id="@+id/video_fragment_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>
    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="z.YoutubeAPI.List.zyoulistlayouts.app" >

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="z.YoutubeAPI.List.zyoulistlayouts.app.MainActivity"
            android:label="@string/app_name">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".Tab1Activity"
            android:configChanges="orientation|keyboardHidden|screenSize">
        </activity>

        <activity android:name=".Tab2Activity"></activity>
        <activity android:name=".Tab3Activity"></activity>

    </application>

</manifest>