Java tutorial
/* * Copyright 2012 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.wecandoit.jinju_0_0_4; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.annotation.TargetApi; import android.app.ListFragment; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.database.Cursor; import android.database.MatrixCursor; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.provider.BaseColumns; import android.support.v4.widget.CursorAdapter; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.ViewPropertyAnimator; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.sample.demos.SampleList; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.widget.SearchView; import com.examples.youtubeapidemo.DeveloperKey; import com.google.android.youtube.player.YouTubeApiServiceUtil; 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.YouTubePlayer.OnInitializedListener; import com.google.android.youtube.player.YouTubePlayer.Provider; import com.google.android.youtube.player.YouTubePlayerFragment; import com.google.android.youtube.player.YouTubeThumbnailLoader; import com.google.android.youtube.player.YouTubeThumbnailLoader.ErrorReason; import com.google.android.youtube.player.YouTubeThumbnailView; import com.wecandoit.jinju_mech_lib.jG; import com.yt.activities.YTSDKUtils; import com.yt.common.utils.GData; import com.yt.fragments.SearchListFragment; import com.yt.item.VideoItem; /** * A sample Activity showing how to manage multiple YouTubeThumbnailViews in an * mAdapter for display in a List. When the list items are clicked, the video is * played by using a YouTubePlayerFragment. * <p> * The demo supports custom fullscreen and transitioning between portrait and * landscape without rebuffering. */ @TargetApi(13) public final class jActivity_YoutubeSearchList extends SherlockActivity implements OnFullscreenListener, SearchView.OnQueryTextListener, SearchView.OnSuggestionListener { /** 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 mVideoListFragment; private VideoFragment mVideoFragment; private View mVideoBox; private View mCloseButton; private View mFavoriteButton; private View mFavoriteButtonOn; private View mFavoriteButtonOff; private View mDownloadButton; private boolean isFullscreen; public static String mCurrVideoID; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.smp_youtuble_video_list_demo); mVideoListFragment = (VideoListFragment) getFragmentManager().findFragmentById(R.id.list_fragment); mVideoFragment = (VideoFragment) getFragmentManager().findFragmentById(R.id.video_fragment_container); mVideoBox = findViewById(R.id.video_box); mCloseButton = findViewById(R.id.close_button); //mFavoriteButton = findViewById(R.id.favorite_button); mFavoriteButtonOn = findViewById(R.id.favorite_button_on); mFavoriteButtonOff = findViewById(R.id.favorite_button_off); mFavoriteButtonOn.setVisibility(View.GONE); mFavoriteButton = mFavoriteButtonOff; mDownloadButton = findViewById(R.id.download_button); mVideoBox.setVisibility(View.INVISIBLE); layout(); checkYouTubeApi(); } private static final String[] COLUMNS = { BaseColumns._ID, SearchManager.SUGGEST_COLUMN_TEXT_1, }; private SuggestionsAdapter mSuggestionsAdapter; SearchView mSearchView; @Override public boolean onCreateOptionsMenu(Menu menu) { // Used to put dark icons on light action bar boolean isLight = SampleList.THEME == R.style.Theme_Sherlock_Light; // Create the search view mSearchView = new SearchView(getSupportActionBar().getThemedContext()); // mSearchView.setIconifiedByDefault(false);// jTODO ??. // mSearchView.setIconified(false); // mSearchView.onActionViewExpanded(); mSearchView.setQueryHint("Search for Internet"); mSearchView.setOnQueryTextListener(this); mSearchView.setSubmitButtonEnabled(true); //mSearchView.setOnSuggestionListener(this); if (mSuggestionsAdapter == null) { MatrixCursor cursor = new MatrixCursor(COLUMNS); cursor.addRow(new String[] { "1", "Let It Go" }); cursor.addRow(new String[] { "2", "steve jobs" }); cursor.addRow(new String[] { "3", "TED" }); mSuggestionsAdapter = new SuggestionsAdapter(getSupportActionBar().getThemedContext(), cursor); } mSearchView.setSuggestionsAdapter(mSuggestionsAdapter); mSearchView.setIconified(false); mSearchView.setIconifiedByDefault(false); //mSearchView.getActionView().expandActionView(); mSearchView.requestFocus(); MenuItem searchMenuItem = menu.add("Search"); searchMenuItem.setIcon(isLight ? R.drawable.ic_search_inverse : R.drawable.abs__ic_search) .setActionView(mSearchView) .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); searchMenuItem.expandActionView(); return true; } @Override public boolean onQueryTextSubmit(String query) { jG.Log.d("onQueryTextSubmit = " + query); Pattern pattern = Pattern.compile("\\s+"); Matcher matcher = pattern.matcher(query); String decodedSearchStr = matcher.replaceAll("%20"); String searchUrl = SEARCH_URL_1 + decodedSearchStr + SEARCH_URL_2; new jGetterVideoListFromYouTube().execute(searchUrl); return true; } @Override public boolean onQueryTextChange(String newText) { jG.Log.d("onQueryTextChange = " + newText); return false; } @Override public boolean onSuggestionSelect(int position) { jG.Log.d("onSuggestionSelect = " + position); return false; } @Override public boolean onSuggestionClick(int position) { Cursor c = (Cursor) mSuggestionsAdapter.getItem(position); String query = c.getString(c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1)); jG.Log.d("onSuggestionClick = " + query); mSearchView.setQuery(query, false); return true; } private class SuggestionsAdapter extends CursorAdapter { public SuggestionsAdapter(Context context, Cursor c) { super(context, c, 0); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); View v = inflater.inflate(android.R.layout.simple_list_item_1, parent, false); return v; } @Override public void bindView(View view, Context context, Cursor cursor) { TextView tv = (TextView) view; final int textIndex = cursor.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_1); tv.setText(cursor.getString(textIndex)); } } private void checkYouTubeApi() { YouTubeInitializationResult errorReason = YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(this); if (errorReason.isUserRecoverableError()) { errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show(); } else if (errorReason != YouTubeInitializationResult.SUCCESS) { String errorMessage = String.format(getString(R.string.error_player), errorReason.toString()); jG.Log.e(errorMessage); Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show(); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == RECOVERY_DIALOG_REQUEST) { // Recreate the activity if user performed a recovery action recreate(); } } @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. */ private void layout() { boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; mVideoListFragment.getView().setVisibility(isFullscreen ? View.GONE : View.VISIBLE); mVideoListFragment.setLabelVisibility(isPortrait); mCloseButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE); //mFavoriteButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE); //mDownloadButton.setVisibility(isPortrait ? View.VISIBLE : View.GONE); if (isFullscreen) { mVideoBox.setTranslationY(0); // Reset any translation that was // applied in portrait. setLayoutSize(mVideoFragment.getView(), MATCH_PARENT, MATCH_PARENT); setLayoutSizeAndGravity(mVideoBox, MATCH_PARENT, MATCH_PARENT, Gravity.TOP | Gravity.LEFT); } else if (isPortrait) { setLayoutSize(mVideoListFragment.getView(), MATCH_PARENT, MATCH_PARENT); setLayoutSizeAndGravity(mVideoBox, MATCH_PARENT, WRAP_CONTENT, Gravity.BOTTOM); setLayoutSize(mVideoFragment.getView(), MATCH_PARENT, WRAP_CONTENT); } else { mVideoBox.setTranslationY(0); // Reset any translation that was // applied in portrait. int screenWidth = dpToPx(getResources().getConfiguration().screenWidthDp); setLayoutSize(mVideoListFragment.getView(), screenWidth / 4, MATCH_PARENT); int videoWidth = screenWidth - screenWidth / 4 - dpToPx(LANDSCAPE_VIDEO_PADDING_DP); setLayoutSize(mVideoFragment.getView(), videoWidth, WRAP_CONTENT); setLayoutSizeAndGravity(mVideoBox, videoWidth, WRAP_CONTENT, Gravity.RIGHT | Gravity.CENTER_VERTICAL); } } public void onClickClose(@SuppressWarnings("unused") View view) { mVideoListFragment.getListView().clearChoices(); mVideoListFragment.getListView().requestLayout(); mVideoFragment.pause(); ViewPropertyAnimator animator = mVideoBox.animate().translationYBy(mVideoBox.getHeight()) .setDuration(ANIMATION_DURATION_MILLIS); runOnAnimationEnd(animator, new Runnable() { @Override public void run() { mVideoBox.setVisibility(View.INVISIBLE); } }); } public void onClickDownload(@SuppressWarnings("unused") View view) { YTSDKUtils.getYTSDK().showCustomDialog(jActivity_YoutubeSearchList.this, true, false); YTSDKUtils.getYTSDK().download(jActivity_YoutubeSearchList.this, mCurrVideoID); } public void onClickFavoriteOn(@SuppressWarnings("unused") View view) { jG.Log.d("onClickFavoriteOn"); mFavoriteButton.setVisibility(View.GONE); mFavoriteButton = mFavoriteButtonOff; mFavoriteButton.setVisibility(View.VISIBLE); /* mVideoListFragment.getListView().clearChoices(); mVideoListFragment.getListView().requestLayout(); mVideoFragment.pause(); ViewPropertyAnimator animator = mVideoBox.animate() .translationYBy(mVideoBox.getHeight()) .setDuration(ANIMATION_DURATION_MILLIS); runOnAnimationEnd(animator, new Runnable() { @Override public void run() { mVideoBox.setVisibility(View.INVISIBLE); } }); */ } public void onClickFavoriteOff(@SuppressWarnings("unused") View view) { jG.Log.d("onClickFavoriteOff"); mFavoriteButton.setVisibility(View.GONE); mFavoriteButton = mFavoriteButtonOn; mFavoriteButton.setVisibility(View.VISIBLE); /* mVideoListFragment.getListView().clearChoices(); mVideoListFragment.getListView().requestLayout(); mVideoFragment.pause(); ViewPropertyAnimator animator = mVideoBox.animate() .translationYBy(mVideoBox.getHeight()) .setDuration(ANIMATION_DURATION_MILLIS); runOnAnimationEnd(animator, new Runnable() { @Override public void run() { mVideoBox.setVisibility(View.INVISIBLE); } }); */ } public void onClickFavorite(@SuppressWarnings("unused") View view) { /* mVideoListFragment.getListView().clearChoices(); mVideoListFragment.getListView().requestLayout(); mVideoFragment.pause(); ViewPropertyAnimator animator = mVideoBox.animate() .translationYBy(mVideoBox.getHeight()) .setDuration(ANIMATION_DURATION_MILLIS); runOnAnimationEnd(animator, new Runnable() { @Override public void run() { mVideoBox.setVisibility(View.INVISIBLE); } }); */ } @Override public void onBackPressed() { super.onBackPressed(); //backPressCloseHandler.onBackPressed(); } @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 { public static List<VideoEntry> mVideoList; public static PageAdapter mAdapter; private View mVideoBox; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); 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")); /* */ mVideoList = list;//Collections.unmodifiableList(list); mAdapter = new PageAdapter(getActivity(), mVideoList); mVideoBox = getActivity().findViewById(R.id.video_box); getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); setListAdapter(mAdapter); } @Override public void onListItemClick(ListView l, View v, int position, long id) { if (mVideoList == null) return; String videoId = mVideoList.get(position).videoId; mCurrVideoID = videoId; VideoFragment videoFragment = (VideoFragment) getFragmentManager() .findFragmentById(R.id.video_fragment_container); videoFragment.setVideoId(videoId); // The mVideoBox is INVISIBLE if no video was previously selected, so // we need to show it now. if (mVideoBox.getVisibility() != View.VISIBLE) { if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // Initially translate off the screen so that it can be // animated in from below. mVideoBox.setTranslationY(mVideoBox.getHeight()); } mVideoBox.setVisibility(View.VISIBLE); } // If the fragment is off the screen, we animate it in. if (mVideoBox.getTranslationY() > 0) { mVideoBox.animate().translationY(0).setDuration(ANIMATION_DURATION_MILLIS); } } @Override public void onDestroyView() { super.onDestroyView(); if (mAdapter != null) mAdapter.releaseLoaders(); } public void setLabelVisibility(boolean visible) { if (mAdapter != null) mAdapter.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> mEntries; 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.mEntries = 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 mEntries.size(); } @Override public VideoEntry getItem(int position) { return mEntries.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 = mEntries.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.youtuble_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.youtuble_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.youtuble_loading_thumbnail); String videoId = (String) view.getTag(); loader.setVideo(videoId); } @Override public void onInitializationFailure(YouTubeThumbnailView view, YouTubeInitializationResult loader) { view.setImageResource(R.drawable.youtuble_no_thumbnail); } @Override public void onThumbnailLoaded(YouTubeThumbnailView view, String videoId) { } @Override public void onThumbnailError(YouTubeThumbnailView view, ErrorReason errorReason) { view.setImageResource(R.drawable.youtuble_no_thumbnail); } } } public static final class VideoFragment extends YouTubePlayerFragment implements 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(Provider provider, YouTubePlayer player, boolean restored) { this.player = player; player.addFullscreenControlFlag(YouTubePlayer.FULLSCREEN_FLAG_CUSTOM_LAYOUT); player.setOnFullscreenListener((jActivity_YoutubeSearchList) getActivity()); if (!restored && videoId != null) { player.cueVideo(videoId); } } @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; } } // 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) { 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); } void searchYoutube() { // http://stackoverflow.com/questions/21914165/how-to-search-videos-with-youtube-data-api-in-android } private final String SEARCH_URL_1 = "http://gdata.youtube.com/feeds/api/videos?q="; private final String SEARCH_URL_2 = "&max-results=10&v=2.1&start-index=1"; private class jGetterVideoListFromYouTube extends AsyncTask<String, Void, ArrayList<VideoItem>> { @Override protected void onPreExecute() { super.onPreExecute(); // progressBar.setVisibility(View.VISIBLE); // mGridView.setVisibility(View.GONE); } @Override protected ArrayList<VideoItem> doInBackground(String... params) { ArrayList<VideoItem> videoList = null; String searchUrl = params[0]; if (searchUrl != null && searchUrl.length() > 0) { videoList = GData.getGData(searchUrl, jActivity_YoutubeSearchList.this, null); } return videoList; } @Override protected void onPostExecute(ArrayList<VideoItem> result) { super.onPostExecute(result); // Cancel the Loading Dialog // progressBar.setVisibility(View.GONE); // addVideoList(result); VideoListFragment.mVideoList.clear(); for (VideoItem v : result) { jG.Log.d("v= " + v.getTitle() + " : " + v.getVideoId()); VideoListFragment.mVideoList.add(new VideoEntry(v.getTitle(), v.getVideoId())); } VideoListFragment.mAdapter.notifyDataSetChanged(); } } }