Java tutorial
/* * Copyright (c) 2015 Matthieu Harl * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package fr.shywim.antoinedaniel.ui.fragment; import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.database.Cursor; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v4.view.ViewCompat; import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.BounceInterpolator; import android.view.animation.RotateAnimation; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupMenu; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import com.squareup.picasso.Picasso; import java.io.File; import java.util.Random; import fr.shywim.antoinedaniel.R; import fr.shywim.antoinedaniel.provider.ProviderConstants; import fr.shywim.antoinedaniel.provider.ProviderContract; import fr.shywim.antoinedaniel.service.DownloadService; import fr.shywim.antoinedaniel.service.SoundService; import fr.shywim.antoinedaniel.sync.AppState; import fr.shywim.antoinedaniel.ui.MainActivity; import fr.shywim.antoinedaniel.ui.widget.NotifyingScrollView; import fr.shywim.antoinedaniel.ui.widget.SquareImageView; import fr.shywim.antoinedaniel.utils.AnalyticsUtils; import fr.shywim.antoinedaniel.utils.LogUtils; import fr.shywim.antoinedaniel.utils.Running; import fr.shywim.antoinedaniel.utils.SoundUtils; import fr.shywim.antoinedaniel.utils.UiUtils; public class VideoDetailsFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> { private static final String TAG = LogUtils.makeLogTag(VideoDetailsFragment.class); public static final String ARG_VIDEO_ID = "arg_video_id"; public static final String ARG_VIDEO_NAME = "arg_video_name"; public static final String THMB_TRANSITION_NAME = "video_thmb"; private String mVideoId; private String mVideoName; private Context mContext; private Drawable mActionBarBackground; private View mStatusBarBg; private View mActionBarLayout; private TextView mActionBarTitle; private ImageView mImageView; private LinearLayout mSoundsSample; private LinearLayout mMusicsList; private TextView mSoundsCat; private TextView mMusicsCat; private int mImageViewOriginalHeight = 0; private int mLastDamping = 0; public static VideoDetailsFragment newInstance(String videoId, String videoName) { VideoDetailsFragment fragment = new VideoDetailsFragment(); Bundle args = new Bundle(); args.putString(ARG_VIDEO_ID, videoId); args.putString(ARG_VIDEO_NAME, videoName); fragment.setArguments(args); return fragment; } public VideoDetailsFragment() { } @Override public void onAttach(Activity activity) { super.onAttach(activity); mContext = activity; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle args = getArguments(); if (args != null && args.containsKey(ARG_VIDEO_ID) && args.containsKey(ARG_VIDEO_NAME)) { mVideoId = args.getString(ARG_VIDEO_ID); mVideoName = args.getString(ARG_VIDEO_NAME); } else { throw new RuntimeException("Missing arguments!"); } } @Override public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Loader<Cursor> loader = getLoaderManager().getLoader(MainActivity.LoaderID.VIDEO_DETAILS_SOUNDS); Bundle args = new Bundle(); args.putString(ARG_VIDEO_ID, mVideoId); if (loader == null) { getLoaderManager().initLoader(MainActivity.LoaderID.VIDEO_DETAILS_SOUNDS, args, this); } else { getLoaderManager().restartLoader(MainActivity.LoaderID.VIDEO_DETAILS_SOUNDS, args, this); } loader = getLoaderManager().getLoader(MainActivity.LoaderID.VIDEO_DETAILS_MUSICS); if (loader == null) { getLoaderManager().initLoader(MainActivity.LoaderID.VIDEO_DETAILS_MUSICS, args, this); } else { getLoaderManager().restartLoader(MainActivity.LoaderID.VIDEO_DETAILS_MUSICS, args, this); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) { View root = inflater.inflate(R.layout.fragment_video_details, container, false); String[] videoNameSplit = mVideoName.split("-", 2); ((TextView) root.findViewById(R.id.title)).setText(videoNameSplit[0].trim()); if (videoNameSplit.length > 1) { ((TextView) root.findViewById(R.id.subtitle)).setText(videoNameSplit[1].trim()); } if (Running.kitkatAndUp()) { mStatusBarBg = root.findViewById(R.id.statusbar_bg); UiUtils.setStatusBarBackground(mStatusBarBg, getResources()); mStatusBarBg.setAlpha(0); } mActionBarLayout = root.findViewById(R.id.actionbar_layout); mActionBarLayout.setY(UiUtils.getStatusBarHeight(getResources())); mActionBarTitle = (TextView) mActionBarLayout.findViewById(R.id.actionbar_title); mActionBarTitle.setText(videoNameSplit[0].trim()); mActionBarTitle.setAlpha(0); mActionBarBackground = mActionBarLayout.getBackground(); mActionBarBackground.setAlpha(0); Toolbar toolbar = (Toolbar) root.findViewById(R.id.toolbar_actionbar); ((FragmentsCallbacks) mContext).setActionBarToolbar(toolbar); toolbar.setTitle(""); toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha); toolbar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getFragmentManager().popBackStack(); } }); mImageView = (ImageView) root.findViewById(R.id.image); ViewCompat.setTransitionName(mImageView, THMB_TRANSITION_NAME + mVideoId); String imageLink = SoundUtils.getSoundImgPath(mContext, mVideoId); Picasso.with(mContext).load(new File(imageLink)).into(mImageView); NotifyingScrollView scrollView = (NotifyingScrollView) root.findViewById(R.id.scroll_view); scrollView.setOnScrollChangedListener(mScrollChangedListener); mSoundsSample = (LinearLayout) root.findViewById(R.id.sounds); mMusicsList = (LinearLayout) root.findViewById(R.id.musics); mSoundsCat = (TextView) root.findViewById(R.id.sounds_cat_title); mMusicsCat = (TextView) root.findViewById(R.id.musics_cat_title); return root; } @Override public void onDetach() { super.onDetach(); mContext = null; } private int getColumnNumber() { Configuration configuration = getResources().getConfiguration(); return configuration.screenWidthDp / 100; } private NotifyingScrollView.OnScrollChangedListener mScrollChangedListener = new NotifyingScrollView.OnScrollChangedListener() { @Override public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) { if (mImageViewOriginalHeight <= 0) { mImageViewOriginalHeight = mImageView.getHeight(); } int currentHeaderHeight = mImageView.getHeight(); final float ratio = (float) Math.min(Math.max(t, 0), currentHeaderHeight) / currentHeaderHeight; mActionBarBackground.setAlpha((int) (ratio * 255)); mActionBarTitle.setAlpha(ratio); if (mStatusBarBg != null) { mStatusBarBg.setAlpha(ratio); } int damping = (int) (0.5f * Math.max(t, 0)); int offset = mLastDamping - damping; mImageView.offsetTopAndBottom(offset); mLastDamping = damping; } }; //********************************************************************************************** //* LoaderManager * //********************************************************************************************** @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { switch (id) { case MainActivity.LoaderID.VIDEO_DETAILS_SOUNDS: if (args != null) { if (args.containsKey(ARG_VIDEO_ID)) { String where = ProviderContract.SoundEntry.TABLE_NAME + '.' + ProviderContract.SoundEntry.COLUMN_LINK + "=?"; String[] whereArgs = new String[] { args.getString(ARG_VIDEO_ID) }; return new CursorLoader(mContext, ProviderConstants.SOUND_URI, null, where, whereArgs, null); } } break; case MainActivity.LoaderID.VIDEO_DETAILS_MUSICS: if (args != null) { if (args.containsKey(ARG_VIDEO_ID)) { String where = ProviderContract.MusicEntry.TABLE_NAME + '.' + ProviderContract.MusicEntry.COLUMN_EPISODE_LINK + " LIKE '" + args.getString(ARG_VIDEO_ID) + "%'"; return new CursorLoader(mContext, ProviderConstants.MUSICS_URI, null, where, null, null); } } break; } return null; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { int id = loader.getId(); if (cursor.isClosed()) { Bundle args = new Bundle(); args.putString(ARG_VIDEO_ID, mVideoId); getLoaderManager().restartLoader(id, args, this); return; } switch (id) { case MainActivity.LoaderID.VIDEO_DETAILS_SOUNDS: if (cursor.getCount() == 0) { ((View) mSoundsCat.getParent()).setVisibility(View.GONE); mSoundsSample.setVisibility(View.GONE); } else { ((View) mSoundsCat.getParent()).setVisibility(View.VISIBLE); mSoundsSample.setVisibility(View.VISIBLE); mSoundsCat.setText(cursor.getCount() + " Sons"); displayRandomSounds(mSoundsSample, cursor); } break; case MainActivity.LoaderID.VIDEO_DETAILS_MUSICS: if (cursor.getCount() == 0) { mMusicsCat.setVisibility(View.GONE); mMusicsList.setVisibility(View.GONE); } else { mMusicsCat.setVisibility(View.VISIBLE); mMusicsList.setVisibility(View.VISIBLE); mMusicsCat.setText(cursor.getCount() + " Musiques"); displayMusics(mMusicsList, cursor); } break; } cursor.close(); } @Override public void onLoaderReset(Loader<Cursor> loader) { //((CursorAdapter) mSoundsSample.getAdapter()).swapCursor(null); } private void displayMusics(ViewGroup layout, Cursor cursor) { if (layout != null) { layout.removeAllViews(); } if (cursor.getCount() <= 0 || layout == null) { return; } for (int i = 0; i < cursor.getCount(); i++) { View view = LayoutInflater.from(mContext).inflate(R.layout.list_music_item, layout, false); cursor.moveToPosition(i); bindMusic(view, cursor); layout.addView(view); } } private void bindMusic(View view, Cursor cursor) { final TextView titleView = (TextView) view.findViewById(R.id.music_title); final TextView artistView = (TextView) view.findViewById(R.id.music_artist); final TextView timeView = (TextView) view.findViewById(R.id.music_time); final ImageView artView = (ImageView) view.findViewById(R.id.music_art); final Button youtubeView = (Button) view.findViewById(R.id.music_youtube); final Button gplayView = (Button) view.findViewById(R.id.music_gplay); final Button amazonView = (Button) view.findViewById(R.id.music_amazon); // Title String title = cursor.getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_TITLE)); titleView.setText(title); // Artist String artist = cursor.getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_ARTIST)); artistView.setText(artist); // Ep Link (Time, Click) final String epLink = cursor .getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_EPISODE_LINK)); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mContext.getString(R.string.youtube_link_prefix) + epLink)); mContext.startActivity(intent); } }); if (epLink.contains("?t=")) { timeView.setText(epLink.substring(epLink.indexOf('=') + 1)); } // Store Links final String ytLink = cursor.getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_YOUTUBE)); if (ytLink == null || ytLink.isEmpty()) { youtubeView.setEnabled(false); } else { youtubeView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mContext.getString(R.string.youtube_link_prefix) + ytLink)); mContext.startActivity(intent); } }); youtubeView.setEnabled(true); } final String gpLink = cursor.getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_GPLAY)); if (gpLink == null || gpLink.isEmpty()) { gplayView.setEnabled(false); } else { gplayView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mContext.getString(R.string.play_music_prefix) + gpLink)); mContext.startActivity(intent); } }); gplayView.setEnabled(true); } final String amLink = cursor.getString(cursor.getColumnIndex(ProviderContract.MusicEntry.COLUMN_AMAZON)); if (amLink == null || amLink.isEmpty()) { amazonView.setEnabled(false); } else { amazonView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(mContext.getString(R.string.amazon_prefix) + amLink)); mContext.startActivity(intent); } }); amazonView.setEnabled(true); } artView.setTag(ytLink); String file = mContext.getString(R.string.api_get_yt_thmb_music) + ytLink; Picasso.with(mContext).load(file).placeholder(R.drawable.noimg).into(artView); } private void displayRandomSounds(ViewGroup layout, Cursor cursor) { if (layout != null) { layout.removeAllViews(); } if (cursor.getCount() <= 0 || layout == null) { return; } Random rdm = new Random(); for (int i = 0; i < getColumnNumber(); i++) { int pos; if (cursor.getCount() > getColumnNumber()) { pos = rdm.nextInt(cursor.getCount()); } else { pos = i; } View view = LayoutInflater.from(mContext).inflate(R.layout.grid_single, layout, false); cursor.moveToPosition(pos); if (i >= cursor.getCount()) { view.setVisibility(View.INVISIBLE); } else { bindSound(view, cursor); } layout.addView(view); } } private void bindSound(View view, Cursor cursor) { AppState appState = AppState.getInstance(); final View card = view; final View downloadFrame = view.findViewById(R.id.sound_download_frame); final TextView tv = (TextView) view.findViewById(R.id.grid_text); final SquareImageView siv = (SquareImageView) view.findViewById(R.id.grid_image); final ImageView star = (ImageView) view.findViewById(R.id.ic_sound_fav); final ImageView menu = (ImageView) view.findViewById(R.id.ic_sound_menu); final String soundName = cursor .getString(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_SOUND_NAME)); String imgId = cursor.getString(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_IMAGE_NAME)); final String description = cursor.getString(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_DESC)); final boolean favorite = appState.favSounds.contains(soundName) || cursor.getInt(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_FAVORITE)) == 1; final boolean widget = appState.widgetSounds.contains(soundName) || cursor.getInt(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_WIDGET)) == 1; final boolean downloaded = cursor .getInt(cursor.getColumnIndex(ProviderContract.SoundEntry.COLUMN_DOWNLOADED)) != 0; new Handler().post(new Runnable() { @Override public void run() { ContentValues cv = new ContentValues(); File sndFile = new File(mContext.getExternalFilesDir(null) + "/snd/" + soundName + ".ogg"); if (downloaded && !sndFile.exists()) { cv.put(ProviderContract.SoundEntry.COLUMN_DOWNLOADED, 0); mContext.getContentResolver().update( Uri.withAppendedPath(ProviderConstants.SOUND_DOWNLOAD_NOTIFY_URI, soundName), cv, null, null); } } }); final View.OnClickListener playSound = new View.OnClickListener() { @Override public void onClick(View v) { String category = mContext.getString(R.string.ana_cat_sound); String action = mContext.getString(R.string.ana_act_play); Bundle extras = new Bundle(); extras.putString(SoundFragment.SOUND_TO_PLAY, soundName); extras.putBoolean(SoundFragment.LOOP, SoundUtils.isLoopingSet()); Intent intent = new Intent(mContext, SoundService.class); intent.putExtras(extras); mContext.startService(intent); AnalyticsUtils.sendEvent(category, action, soundName); } }; final View.OnClickListener downloadSound = new View.OnClickListener() { @Override public void onClick(View v) { card.setOnClickListener(null); RotateAnimation animation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); animation.setInterpolator(new BounceInterpolator()); animation.setFillAfter(true); animation.setFillEnabled(true); animation.setDuration(1000); animation.setRepeatCount(Animation.INFINITE); animation.setRepeatMode(Animation.RESTART); downloadFrame.findViewById(R.id.sound_download_icon).startAnimation(animation); DownloadService.startActionDownloadSound(mContext, soundName, new SoundUtils.DownloadResultReceiver(new Handler(), downloadFrame, playSound, this)); } }; if (downloaded) { downloadFrame.setVisibility(View.GONE); downloadFrame.findViewById(R.id.sound_download_icon).clearAnimation(); card.setOnClickListener(playSound); } else { downloadFrame.setAlpha(1); downloadFrame.findViewById(R.id.sound_download_icon).setScaleX(1); downloadFrame.findViewById(R.id.sound_download_icon).setScaleY(1); downloadFrame.setVisibility(View.VISIBLE); card.setOnClickListener(downloadSound); } menu.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final ImageView menuIc = (ImageView) v; PopupMenu popup = new PopupMenu(mContext, menuIc); Menu menu = popup.getMenu(); popup.getMenuInflater().inflate(R.menu.sound_menu, menu); if (favorite) menu.findItem(R.id.action_sound_fav).setTitle("Retirer des favoris"); if (widget) menu.findItem(R.id.action_sound_wid).setTitle("Retirer du widget"); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.action_sound_fav: SoundUtils.addRemoveFavorite(mContext, soundName); return true; case R.id.action_sound_wid: SoundUtils.addRemoveWidget(mContext, soundName); return true; /*case R.id.action_sound_add: return true;*/ case R.id.action_sound_ring: SoundUtils.addRingtone(mContext, soundName, description); return true; case R.id.action_sound_share: AnalyticsUtils.sendEvent(mContext.getString(R.string.ana_cat_soundcontext), mContext.getString(R.string.ana_act_weblink), soundName); ClipboardManager clipboard = (ClipboardManager) mContext .getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("BAD link", "http://bad.shywim.fr/" + soundName); clipboard.setPrimaryClip(clip); Toast.makeText(mContext, R.string.toast_link_copied, Toast.LENGTH_LONG).show(); return true; case R.id.action_sound_delete: SoundUtils.delete(mContext, soundName); return true; default: return false; } } }); popup.setOnDismissListener(new PopupMenu.OnDismissListener() { @Override public void onDismiss(PopupMenu menu) { menuIc.setColorFilter(mContext.getResources().getColor(R.color.text_caption_dark)); } }); menuIc.setColorFilter(mContext.getResources().getColor(R.color.black)); popup.show(); } }); tv.setText(description); siv.setTag(imgId); if (appState.favSounds.contains(soundName)) { star.setVisibility(View.VISIBLE); } else if (favorite) { star.setVisibility(View.VISIBLE); appState.favSounds.add(soundName); } else { star.setVisibility(View.INVISIBLE); } File file = new File(mContext.getExternalFilesDir(null) + "/img/" + imgId + ".jpg"); Picasso.with(mContext).load(file).placeholder(R.drawable.noimg).fit().into(siv); } }