I have a VideoLayout that displays a video using ExoPlayer. That VideoLayout is used twice in a Fragment (previewVideoLayout and fullVideoLayout in the code).
The Fragment shows by default previewVideoLayout; if the user presses a button in the Activity, it shows fullVideoLayout on top of previewVideoLayout with an animation. previewVideoLayout always plays OK, but fullVideoLayout doesn't display the video, though it plays its sound (on top of previewVideoLayout sound).
Is there a reason why, calling the same methods on both layouts, one plays but the second one doesn't? In case it's relevant; the Fragment is inside a ViewPager.
VideLayout:
public class VideoLayout {
public static final int MUTE_VOLUME = 0;
public static final int MAX_VOLUME = 100;
public static final int UPDATE_INTERVAL = 30;
protected static final String ARG_VIDEO_URL = "VIDEO_URL";
private final Context context;
private String videoUrl;
private HttpProxyCacheServer proxy;
private boolean visibleForUser;
private SimpleExoPlayer player;
private SimpleExoPlayerView simpleExoPlayerView;
private boolean pendingPlay;
private ProgressBar pbLoadIndicator;
private TimerTask updateProgressTask;
private Timer timer;
private ProgressBar videoProgress;
private ViewGroup layout;
private VideoFragment.VideoPreviewCallbacks videoPreviewCallbacks;
private String tag;
private boolean isFullVideo;
public VideoLayout(Context context, String videoUrl, boolean isFullVideo) {
this.context = context;
this.isFullVideo = isFullVideo;
this.videoUrl = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
}
public void onAttach(Context context) {
if (context instanceof VideoFragment.VideoPreviewCallbacks) {
videoPreviewCallbacks = (VideoFragment.VideoPreviewCallbacks) context;
}
}
public void onCreate() {
this.videoUrl = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";
initPlayer();
}
public void onCreateView(ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = (ViewGroup) inflater.inflate(getLayoutRes(), null);
String tag = createTag();
if (parent.findViewWithTag(tag) == null) {
layout.setTag(tag);
parent.addView(layout, parent.getChildCount());
}
}
public void onViewCreated(View view) {
bindViews(view);
setupPlayerView();
}
public void onResume() {
if (pendingPlay && visibleForUser) {
pendingPlay = false;
startPlayer();
}
}
public void onPause() {
pausePlayer();
}
public void onDestroy() {
player.release();
}
public void setUserVisibleHint(boolean isVisibleToUser) {
visibleForUser = isVisibleToUser;
if (layout != null) {
layout.setVisibility(isVisibleToUser ? VISIBLE : GONE);
}
if (visibleForUser && simpleExoPlayerView != null) {
startPlayer();
} else if (!visibleForUser && simpleExoPlayerView != null) {
pausePlayer();
} else if (visibleForUser) {
pendingPlay = true;
}
}
private void bindViews(View view) {
simpleExoPlayerView = (SimpleExoPlayerView) view.findViewById(R.id.simpleExoPlayerView);
simpleExoPlayerView.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.white));
pbLoadIndicator = (ProgressBar) view.findViewById(R.id.pbLoadIndicator);
videoProgress = (ProgressBar) view.findViewById(R.id.progress_video);
}
private void setupPlayerView() {
simpleExoPlayerView.setUseController(false);
simpleExoPlayerView.setPlayer(player);
}
private void initPlayer() {
if (player == null) {
initProxy();
DefaultBandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
final LoopingMediaSource loopingSource = getVideoPlayerMediaSource(bandwidthMeter);
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
player = ExoPlayerFactory.newSimpleInstance(getContext(), trackSelector, loadControl);
player.addListener(new PlayerEventListener() {
#Override
public void onLoadingChanged(boolean isLoading) {
if (pbLoadIndicator != null)
pbLoadIndicator.setVisibility(isLoading ? View.VISIBLE : View.GONE);
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (pbLoadIndicator != null)
pbLoadIndicator.setVisibility(playWhenReady ? View.GONE : View.VISIBLE);
}
});
player.prepare(loopingSource);
player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
}
}
private void initProxy() {
proxy = VideoCache.getProxy(getContext());
}
#NonNull
private LoopingMediaSource getVideoPlayerMediaSource(DefaultBandwidthMeter bandwidthMeter) {
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(),
Util.getUserAgent(getContext(), "lifive.buy"), bandwidthMeter);
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();
Uri url = Uri.parse(videoUrl);
MediaSource videoSource;
if (videoUrl.contains(".mp4")) {
url = Uri.parse(proxy.getProxyUrl(videoUrl));
videoSource = new ExtractorMediaSource(url,
dataSourceFactory, extractorsFactory, null, null);
} else {
videoSource = new HlsMediaSource(url, dataSourceFactory, null, null);
}
return new LoopingMediaSource(videoSource);
}
public void enableProgress(boolean enable) {
videoProgress.setVisibility(enable ? VISIBLE : View.GONE);
}
private void startPlayer() {
player.setPlayWhenReady(true);
createUpdateTimer();
}
/**
* creates the timer that updates the progress bar
*/
private void createUpdateTimer() {
cancelUpdateTimer();
updateProgressTask = new TimerTask() {
#Override
public void run() {
if (player != null) {
notifyUpdate();
}
}
};
timer = new Timer();
timer.scheduleAtFixedRate(updateProgressTask, 0, UPDATE_INTERVAL);
}
/**
* cancels the timer that updates the progress bar
*/
private void cancelUpdateTimer() {
if (timer != null) {
timer.cancel();
}
}
/**
* notifies that the UI should be updated. See createUpdateTimer
*/
private void notifyUpdate() {
new Handler(Looper.getMainLooper()).post(() -> {
updateProgressBar();
if (player.getDuration() > 0 && videoPreviewCallbacks != null) {
videoPreviewCallbacks.onProgress(player.getCurrentPosition(), player.getDuration());
}
});
}
private void updateProgressBar() {
videoProgress.setMax((int) player.getDuration());
videoProgress.setProgress((int) player.getCurrentPosition());
}
private void pausePlayer() {
pendingPlay = true;
player.setPlayWhenReady(false);
player.seekTo(1);
cancelUpdateTimer();
}
public int getVisibility() {
return layout == null ? GONE : layout.getVisibility();
}
public void muteSound(boolean on) {
player.setVolume(on ? MUTE_VOLUME : MAX_VOLUME);
}
private int getLayoutRes() {
return isFullVideo ? R.layout.layout_full_video_player : R.layout.layout_video_player;
}
private String createTag() {
if (this.tag == null)
this.tag = "VideoLayout" + hashCode();
return this.tag;
}
private Context getContext() {
return context.getApplicationContext();
}
Fragment:
public class VideoFragment extends Fragment {
protected static final String ARG_VIDEO_URL = "VIDEO_URL";
private static final String ARG_FULL_VIDEO_URL = "FULL_VIDEO_URL";
private VideoLayout previewVideoLayout;
private VideoLayout fullVideoLayout;
private String videoUrl;
private String fullVideoUrl;
private ViewGroup parent;
public VideoFragment() {
}
/**
* #param videoUrl video url
* #return A new instance of fragment VideoPreviewFragment.
*/
public static VideoFragment newInstance(String videoUrl, String fullVideoUrl) {
VideoFragment fragment = new VideoFragment();
Bundle args = new Bundle();
args.putString(ARG_VIDEO_URL, videoUrl);
args.putString(ARG_FULL_VIDEO_URL, fullVideoUrl);
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof VideoPreviewCallbacks) {
if (getCurrentLayout() != null)
getCurrentLayout().onAttach(getContext());
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
videoUrl = getArguments().getString(ARG_VIDEO_URL);
fullVideoUrl = getArguments().getString(ARG_FULL_VIDEO_URL);
if (previewVideoLayout == null) {
previewVideoLayout = new VideoLayout(getContext(), videoUrl, false);
previewVideoLayout.setUserVisibleHint(getUserVisibleHint());
previewVideoLayout.onCreate();
}
if (fullVideoLayout == null && fullVideoUrl != null) {
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View inflate = inflater.inflate(R.layout.fragment_video_preview, container, false);
parent = (ViewGroup) inflate.findViewById(R.id.fragment_video_preview_root);
previewVideoLayout.onCreateView(parent);
return inflate;
}
#Override
public void onViewCreated(View view, Bundle savedInstance) {
super.onViewCreated(view, savedInstance);
previewVideoLayout.onViewCreated(view);
}
#Override
public void onResume() {
super.onResume();
if (previewVideoLayout != null)
previewVideoLayout.onResume();
if (fullVideoLayout != null)
fullVideoLayout.onResume();
}
#Override
public void onPause() {
super.onPause();
if (previewVideoLayout != null)
previewVideoLayout.onPause();
if (fullVideoLayout != null)
fullVideoLayout.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
if (previewVideoLayout != null)
previewVideoLayout.onDestroy();
if (fullVideoLayout != null)
fullVideoLayout.onDestroy();
}
#Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (previewVideoLayout != null)
previewVideoLayout.setUserVisibleHint(isVisibleToUser);
if (fullVideoLayout != null)
fullVideoLayout.setUserVisibleHint(isVisibleToUser);
}
public void enableProgress(boolean enable) {
if (previewVideoLayout != null)
previewVideoLayout.enableProgress(enable);
if (fullVideoLayout != null)
fullVideoLayout.enableProgress(enable);
}
private VideoLayout getCurrentLayout() {
if (fullVideoLayout != null)
return fullVideoLayout.getVisibility() == View.VISIBLE ? fullVideoLayout : previewVideoLayout;
return previewVideoLayout;
}
public void muteSound(boolean on) {
if(previewVideoLayout!=null)
previewVideoLayout.muteSound(on);
if(fullVideoLayout!=null)
fullVideoLayout.muteSound(on);
}
public void showFullVideo() {
fullVideoLayout = new VideoLayout(getContext(), fullVideoUrl, true);
fullVideoLayout.setUserVisibleHint(getUserVisibleHint());
fullVideoLayout.onCreate();
fullVideoLayout.onCreateView(parent);
fullVideoLayout.onViewCreated(getView());
fullVideoLayout.onResume();
}
public interface VideoPreviewCallbacks {
void onProgress(long currentMillis, long durationInMillis);
}
Related
I have a problem with my detail activity layout screen. The details in the screen are showing but the screen loading does not stop after that. I need help to stop my screen loading after the details in the screen has been shown.
The main layout activity loads for a certain amount of time and it works fine but the detail activity layout keeps on loading without stopping.
DetailsFragment.java
public class DetailsFragment extends Fragment {
private static final String LOG_TAG = DetailsFragment.class.getSimpleName();
private static final String ARG_NEWS = "arg_news";
private static final String SAVE_NEWS = "save_news";
private static final String SAVE_FAVORITE_NEWS = "save_favorite_news";
private static final String SAVE_FAVORITE_SORT = "save_favorite_sort";
private static final String SAVE_FULLY_LOADED = "save_fully_loaded";
private static final String SAVE_SHARE_MENU_VISIBILITY = "save_share_menu_visibility";
private final ResponseReceiver mReceiver = new ResponseReceiver();
private Context mContext;
private News mNews;
private ShareActionProvider mShareActionProvider;
private MenuItem mShareMenuItem;
private ImageView mPosterImageView;
private OnLoadingFragmentListener mLoadingListener;
private boolean mIsFavoriteNews;
private boolean mIsFavoriteSort;
private boolean mIsFullyLoaded;
private boolean mIsShareMenuItemVisible;
public DetailsFragment() {
// Required empty public constructor
}
// Create new Fragment instance
public static DetailsFragment newInstance(News newsSelected) {
DetailsFragment fragment = new DetailsFragment();
Bundle args = new Bundle();
args.putParcelable(ARG_NEWS, newsSelected);
fragment.setArguments(args);
return fragment;
}
public static DetailsFragment newInstance() {
DetailsFragment fragment = new DetailsFragment();
return fragment;
}
// Listener to handle star button clicks. This button adds and remove news from
// content provider
private final View.OnClickListener mStarButtonOnClickListener = new View.OnClickListener() {
public void onClick(View view) {
// Can't save it to favorites db if news poster is not ready yet
if (mPosterImageView != null && !Utils.hasImage(mPosterImageView)) {
Toast.makeText(mContext, R.string.please_wait_poster_download,
Toast.LENGTH_SHORT).show();
return;
}
if (mIsFavoriteNews) {
if (removeFavoriteNews(mNews) > 0) {
Toast.makeText(mContext, R.string.success_remove_favorites, Toast
.LENGTH_SHORT)
.show();
((ImageButton) view).setImageResource(R.drawable.ic_star_border);
// Delete poster image stored in internal storage
Utils.deleteFileFromInternalStorage(mContext, mNews.getTitle());
mIsFavoriteNews = false;
} else {
Toast.makeText(mContext, R.string.fail_remove_favorites,
Toast.LENGTH_SHORT).show();
}
} else {
if (addFavoriteNews(mNews) != null) {
Toast.makeText(mContext, R.string.success_add_favorites, Toast
.LENGTH_SHORT).show();
((ImageButton) view).setImageResource(R.drawable.ic_star);
// Save poster image to internal storage
Bitmap posterBitmap = Utils.getBitmapFromImageView(mPosterImageView);
Utils.saveBitmapToInternalStorage(mContext, posterBitmap, mNews.getTitle());
mIsFavoriteNews = true;
} else {
Toast.makeText(mContext, R.string.fail_add_favorites, Toast
.LENGTH_SHORT).show();
}
}
}
};
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnLoadingFragmentListener) {
mLoadingListener = (OnLoadingFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnLoadingInteractionListener");
}
mContext = context;
}
#Override
public void onDetach() {
super.onDetach();
mLoadingListener = null;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mNews = getArguments().getParcelable(ARG_NEWS);
mIsFavoriteNews = isFavoriteNews(mContext, mNews);
mIsFavoriteSort = Utils.isFavoriteSort(mContext);
}
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.details_menu, menu);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
mShareMenuItem = menu.findItem(R.id.menu_item_share);
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider
(mShareMenuItem);
setShareMenuItemAction();
super.onPrepareOptionsMenu(menu);
}
private void setShareMenuItemAction() {
if (mNews != null ) {
//String videoKey = mNews.getVideos()[0].getKey();
if (mShareActionProvider != null
&& mShareMenuItem != null) {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
mShareActionProvider.setShareIntent(shareIntent);
mShareMenuItem.setVisible(true);
}
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(SAVE_NEWS, mNews);
outState.putBoolean(SAVE_FAVORITE_NEWS, mIsFavoriteNews);
outState.putBoolean(SAVE_FAVORITE_SORT, mIsFavoriteSort);
outState.putBoolean(SAVE_FULLY_LOADED, mIsFullyLoaded);
outState.putBoolean(SAVE_SHARE_MENU_VISIBILITY, mIsShareMenuItemVisible);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mNews == null) {
return null;
}
// Restore objects value
if (savedInstanceState != null) {
mNews = savedInstanceState.getParcelable(SAVE_NEWS);
mIsFavoriteNews = savedInstanceState.getBoolean(SAVE_FAVORITE_NEWS);
mIsFavoriteSort = savedInstanceState.getBoolean(SAVE_FAVORITE_SORT);
mIsFullyLoaded = savedInstanceState.getBoolean(SAVE_FULLY_LOADED);
mIsShareMenuItemVisible = savedInstanceState.getBoolean(SAVE_SHARE_MENU_VISIBILITY);
}
View view = inflater.inflate(R.layout.fragment_details, container, false);
mPosterImageView = (ImageView) view.findViewById(R.id.news_img);
Glide.with(mContext).load(mNews.getImageUri())
.dontAnimate().into(mPosterImageView);
TextView titleView = (TextView) view.findViewById(R.id.title_content);
titleView.setText(mNews.getTitle());
TextView publishDateView = (TextView) view.findViewById(R.id.publish_date_content);
String date = Utils.formatDateForLocale(mNews.getPublishedDate());
publishDateView.setText(date);
TextView author = (TextView) view.findViewById(R.id.author_name);
author.setText(mNews.getAuthor());
TextView descriptionView = (TextView) view.findViewById(R.id.description_content);
TextView fullNewsUrl = (TextView) view.findViewById(R.id.news_full);
fullNewsUrl.setText(mNews.getFullNewsUrl());
// In portuguese, some news does not contain overview data. In that case, displays
// default text: #string/overview_not_available
if (!TextUtils.isEmpty(mNews.getDescription())) {
descriptionView.setText(mNews.getDescription());
}
ImageButton starButton = (ImageButton) view.findViewById(R.id.star_button);
starButton.setOnClickListener(mStarButtonOnClickListener);
if (mIsFavoriteNews) {
starButton.setImageResource(R.drawable.ic_star);
} else {
starButton.setImageResource(R.drawable.ic_star_border);
}
starButton.setVisibility(View.VISIBLE);
FrameLayout detailFrame = (FrameLayout) view.findViewById(R.id.detail_frame);
detailFrame.setVisibility(View.VISIBLE);
return view;
}
// Method that adds a News to content provider
private Uri addFavoriteNews(News news) {
Uri newsReturnUri = null;
try {
ContentValues newsContentValues = createNewsValues(news);
newsReturnUri = mContext.getContentResolver().insert(FavoriteNewsContract
.NewsEntry
.CONTENT_URI, newsContentValues);
} catch (SQLException e) {
Log.d(LOG_TAG, "SQLException while adding news to Favorite db");
e.printStackTrace();
}
return newsReturnUri;
}
// Method that removes a News from content provider
private int removeFavoriteNews(News news) {
int newsRemoved = mContext.getContentResolver().delete(FavoriteNewsContract
.NewsEntry.CONTENT_URI,
FavoriteNewsContract
.NewsEntry._ID + " = ?", new String[]{news.getTitle()});
return newsRemoved;
}
// Create news content values
private ContentValues createNewsValues(News news) {
ContentValues newsContentValues = new ContentValues();
// newsContentValues.put(FavoriteNewsContract.NewsEntry._ID, Integer.parseInt(news
// .getId()));
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_TITLE, news.getTitle());
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_PUBLISH_DATE, news
.getPublishedDate());
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_AUTHOR, news
.getAuthor());
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_DESCRIPTION, news
.getDescription());
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_FULL_NEWS_URL, news
.getFullNewsUrl());
newsContentValues.put(FavoriteNewsContract.NewsEntry.COLUMN_IMG_URL, news
.getImageUri()
.toString());
return newsContentValues;
}
// Method that query content provider and checks whether is a Favorite news or not
private boolean isFavoriteNews(Context ctx, News news) {
String newsID = news.getTitle();
Cursor cursor = ctx.getContentResolver().query(FavoriteNewsContract.NewsEntry
.CONTENT_URI, null,
FavoriteNewsContract.NewsEntry._ID + " = " + newsID, null, null);
if (cursor != null && cursor.moveToNext()) {
int newsIdColumnIndex = cursor.getColumnIndex(FavoriteNewsContract.NewsEntry._ID);
if (TextUtils.equals(newsID, cursor.getString(newsIdColumnIndex))) {
return true;
}
}
if (cursor != null) {
cursor.close();
}
return false;
}
#Override
public void onResume() {
super.onResume();
if (mNews != null) {
if (mReceiver != null) {
LocalBroadcastManager.getInstance(mContext)
.registerReceiver(mReceiver, new IntentFilter(Constants
.ACTION_EXTRA_INFO_RESULT));
}
if (!mIsFullyLoaded && !mIsFavoriteSort) {
Intent intent = new Intent(mContext, NewsIntentService.class);
intent.setAction(Constants.ACTION_EXTRA_INFO_REQUEST);
intent.putExtra(NewsIntentService.EXTRA_INFO_NEWS_ID, mNews.getTitle());
mContext.startService(intent);
if (mLoadingListener != null) {
mLoadingListener.onLoadingDisplay(true, true);
}
}
}
}
#Override
public void onPause() {
super.onPause();
if (mReceiver != null) {
LocalBroadcastManager.getInstance(mContext).unregisterReceiver(mReceiver);
}
}
// BroadcastReceiver for network call
public class ResponseReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent == null || intent.getAction() == null) {
return;
}
if (intent.getAction().equals(Constants.ACTION_EXTRA_INFO_RESULT)) {
setShareMenuItemAction();
} else {
Toast.makeText(mContext, R.string.toast_failed_to_retrieve_data,
Toast.LENGTH_SHORT).show();
}
if (mLoadingListener != null) {
mLoadingListener.onLoadingDisplay(true, false);
}
mIsFullyLoaded = true;
}
}
}
DetailsActivity.java
public class DetailsActivity extends AppCompatActivity implements OnLoadingFragmentListener {
private static final String LOG_TAG = DetailsActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
if (savedInstanceState == null) {
Intent intent = getIntent();
if (intent != null && intent.hasExtra(Constants.EXTRA_NEWS)) {
News news = intent
.getParcelableExtra(Constants.EXTRA_NEWS);
DetailsFragment detailsFragment = DetailsFragment.newInstance(news);
getSupportFragmentManager().beginTransaction()
.add(R.id.details_fragment_container, detailsFragment).commit();
} else {
Log.d(LOG_TAG, "Something went wrong. Intent doesn't have Constants.EXTRA_NEWS" +
" extra. Finishing DetailsActivity.");
finish();
}
}
}
#Override
public void onLoadingDisplay(boolean fromDetails, boolean display) {
Fragment loadingFragment = getSupportFragmentManager()
.findFragmentByTag(LoadingFragment.FRAGMENT_TAG);
if (display && loadingFragment == null) {
loadingFragment = LoadingFragment.newInstance();
if (fromDetails) {
getSupportFragmentManager().beginTransaction()
.add(R.id.details_fragment_container,
loadingFragment, LoadingFragment.FRAGMENT_TAG).commit();
} else {
getSupportFragmentManager().beginTransaction()
.add(R.id.news_fragment_container,
loadingFragment, LoadingFragment.FRAGMENT_TAG).commit();
}
} else if (!display && loadingFragment != null) {
getSupportFragmentManager().beginTransaction()
.remove(loadingFragment).commit();
}
}
}
LoadingFragment.xml
public class LoadingFragment extends Fragment {
public static final String FRAGMENT_TAG = LoadingFragment.class.getSimpleName();
private static final String LOG_TAG = LoadingFragment.class.getSimpleName();
public LoadingFragment() {
// Required empty public constructor
}
public static LoadingFragment newInstance() {
LoadingFragment fragment = new LoadingFragment();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_loading, container, false);
return view;
}
}
fragment_loading.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/semiTransparentBlack"
android:clickable="true"
tools:context=".ui.LoadingFragment">
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center" />
</FrameLayout>
Most likely you need to change the loading View (ProgressBar?) visibility to INVISIBLE or GONE at the appropriate time, probably when loading is complete.
If the loading View is contained in some kind of dialog, then you would need to dismiss it at the appropriate time.
use onDestroy
#Override
public void onDestroy() {
super.onDestroy();
mLoadingListener = null;
}
and also you should remove ResponseReceiver
if (mLoadingListener != null) {
mLoadingListener.onLoadingDisplay(true, false);
}
Hi all I am now integrating youtube API in my app where I have to parse the list of video id's from API then I have to show the videos in a list view when we click on it the video has to be played Until this works fine
There after when the user selects the full-screen mode that is landscape mode I get some errors
public final class VideoGallery extends Fragment implements OnFullscreenListener {
public static Context context;
public static final int ANIMATION_DURATION_MILLIS = 300;
public static final int LANDSCAPE_VIDEO_PADDING_DP = 5;
public final int RECOVERY_DIALOG_REQUEST = 1;
public static VideoListFragment listFragment;
public static VideoFragment videoFragment;
View videoBox;
View view;
View closeButton;
boolean isFullscreen;
public static YouTubePlayer.OnFullscreenListener onFullscreenListener;
static boolean back = false;
FrameLayout relativeLayout;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = getContext();
onFullscreenListener = this;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
relativeLayout = new FrameLayout(getActivity());
inflater.inflate(R.layout.video_list_demo, relativeLayout, true);
MainActivity.headerText.setText("Video Gallery");
listFragment = (VideoGallery.VideoListFragment) getChildFragmentManager().findFragmentById(R.id.list_fragment);
videoFragment = (VideoGallery.VideoFragment) getActivity().getFragmentManager().findFragmentById(R.id.video_fragment_container);
videoBox = relativeLayout.findViewById(R.id.video_box);
closeButton = relativeLayout.findViewById(R.id.close_button);
closeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(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);
}
});
}
});
videoBox.setVisibility(View.INVISIBLE);
layout();
checkYouTubeApi();
return relativeLayout;
}
private void checkYouTubeApi() {
YouTubeInitializationResult errorReason =
YouTubeApiServiceUtil.isYouTubeApiServiceAvailable(context);
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(getActivity(), RECOVERY_DIALOG_REQUEST).show();
} else if (errorReason != YouTubeInitializationResult.SUCCESS) {
String errorMessage =
String.format(getString(R.string.error_player), errorReason.toString());
Toast.makeText(context, 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();
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
layout();
}
#Override
public void onFullscreen(boolean isFullscreen) {
this.isFullscreen = isFullscreen;
layout();
}
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;
setLayoutSize(videoFragment.getView(), videoWidth, WRAP_CONTENT);
setLayoutSizeAndGravity(videoBox, videoWidth, WRAP_CONTENT,
Gravity.RIGHT | Gravity.CENTER_VERTICAL);
}
}
#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();
}
});
}
}
public static final class VideoListFragment extends ListFragment {
private static List<VideoEntry> VIDEO_LIST;
private PageAdapter adapter;
private View videoBox;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
callApi();
}
private void callApi() {
new DoGet(this, "videogallery").execute(WebserviceEndpoints.VIDEO_GALLERY);
}
public void handleVideoGalleryResponse(String response) {
try {
List<VideoEntry> list = new ArrayList<VideoEntry>();
if (response.length() > 0) {
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.optJSONArray("items");
for (int i = 0; i < array.length(); i++) {
JSONObject data = array.optJSONObject(i);
JSONObject obj = data.optJSONObject("id");
JSONObject obj1 = data.optJSONObject("snippet");
String videoId = obj.optString("videoId");
String videoTitle = obj1.getString("title");
if (!videoId.equals("")) {
list.add(new VideoEntry(videoTitle, videoId));
}
}
VIDEO_LIST = Collections.unmodifiableList(list);
adapter = new PageAdapter(getActivity(), VIDEO_LIST);
setListAdapter(adapter);
}
} catch (Exception e) {
Log.d("", "handleResponse: ", e);
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
videoBox = getActivity().findViewById(R.id.video_box);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
String videoId = VIDEO_LIST.get(position).videoId;
back = false;
VideoFragment videoFragment = (VideoFragment) getActivity().getFragmentManager().findFragmentById(R.id.video_fragment_container);
videoFragment.setVideoId(videoId);
if (videoBox.getVisibility() != View.VISIBLE) {
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
videoBox.setTranslationY(videoBox.getHeight());
}
videoBox.setVisibility(View.VISIBLE);
}
if (videoBox.getTranslationY() > 0) {
videoBox.animate().translationY(0).setDuration(ANIMATION_DURATION_MILLIS);
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
VideoFragment f = (VideoFragment) getActivity().getFragmentManager().findFragmentById(R.id.video_fragment_container);
if (f != null)
getActivity().getFragmentManager().beginTransaction().remove(f).commit();
if (adapter != null)
adapter.releaseLoaders();
}
public void setLabelVisibility(boolean visible) {
if (adapter != null)
adapter.setLabelVisibility(visible);
}
}
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("AIzaSyB8BPeIbu5T1-flG4tpEdrHDPI3Rk2VTDY", 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.no_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.no_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;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initialize("AIzaSyB8BPeIbu5T1-flG4tpEdrHDPI3Rk2VTDY", 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(onFullscreenListener);
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;
}
}
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);
}
}
This is my fragment
The layout file is
<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
android:id="#+id/list_fragment"
class="com.mycristoparish.Fragments.VideoGallery$VideoListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
<LinearLayout
android:id="#+id/video_box"
android:layout_width="match_parent"
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" />
<fragment
android:id="#+id/video_fragment_container"
class="com.mycristoparish.Fragments.VideoGallery$VideoFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</merge>
When I try to play the video in full-screen mode I get the following error
java.lang.IllegalArgumentException: Binary XML file line #42: Duplicate id 0x7f0d0117, tag null, or parent id 0x7f0d0115 with another fragment for com.mycristoparish.Fragments.VideoGallery$VideoFragment
Please guide me how can I move further.
Thanks in advance.
The problem is that you are inflating a layout with a fragment inside a fragment.You cannot do it and so you get the error.However you can dynamically add them.
More details
Note: You cannot inflate a layout into a fragment when that layout includes a . Nested fragments are only supported when added to a fragment dynamically.
I'm new in this android world. I'm currently working on android project i.e., music player but i got stopped at one point since my recycler view doesn't display anything which is supposed to be a list of songs.
I even checked my logcat but cannot figured out whether the data is binding or not.Any kind of help will be grateful.
SongListAdapter.java
public class SongListAdapter extends RecyclerView.Adapter<SongListAdapter.MyViewHolder> {
ArrayList<SongDetailsJDO> mSongDetailsJDOs;
LayoutInflater mLayoutInflater;
Context mContext;
private static final String TAG = "SongListAdapter";
private boolean mIsSongPlaying = false;
private String mCurrentSongId = "-1";
public SongListAdapter(Context context, ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
mContext = context;
mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSongDetailsJDOs = pSongDetailsJDOs;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View lView = mLayoutInflater.inflate(R.layout.recycler_view_item, parent, false);
return new MyViewHolder(lView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Uri lUri = null;
if (mSongDetailsJDOs.get(position).getAlbumId() != null && !mSongDetailsJDOs.get(position).getAlbumId().equals("")) {
lUri = ContentUris.withAppendedId(Uri.parse("content://media/external/audio/albumart"), Long.parseLong(mSongDetailsJDOs.get(position).getAlbumId()));
Picasso.with(mContext).load(lUri).resize(100, 100).placeholder(R.drawable.placeholder).into(holder.albumImageIV);
} else
holder.albumImageIV.setImageResource(R.drawable.placeholder);
String lTrackName = mSongDetailsJDOs.get(position).getTitle();
if (lTrackName != null)
holder.trackNameTV.setText(lTrackName.trim());
else
holder.trackNameTV.setText("<Unknown>");
String lAlbumName = mSongDetailsJDOs.get(position).getAlbumName();
if (lAlbumName != null)
holder.albumAndArtistDetailsTV.setText(lAlbumName.trim());
else
holder.albumAndArtistDetailsTV.setText("<Unknown>");
if (mSongDetailsJDOs.get(position).getFavouriteStatus() == 1)
holder.favouriteIV.setImageResource(R.drawable.fav);
else
holder.favouriteIV.setImageResource(R.drawable.fav_u);
// TODO: #holder.animationDrawable use it change Visibility and start (Animation)
if (mIsSongPlaying && mSongDetailsJDOs.get(position).getSongId().equals(mCurrentSongId)) {
holder.eqIv.setVisibility(View.VISIBLE);
holder.animationDrawable = (AnimationDrawable) holder.eqIv.getBackground();
holder.animationDrawable.start();
} else {
holder.eqIv.setVisibility(View.INVISIBLE);
}
}
#Override
public int getItemCount() {
if (mSongDetailsJDOs != null)
return mSongDetailsJDOs.size();
else
return 0;
}
/**
* Called when data is being updated in DB
*/
public void favChanged(int pPosition, int pFavStatus) {
mSongDetailsJDOs.get(pPosition).setFavouriteStatus(pFavStatus);
notifyItemChanged(pPosition);
}
/**
* View Holder class for Rec view
*/
class MyViewHolder extends RecyclerView.ViewHolder {
ImageView albumImageIV;
TextView trackNameTV;
TextView albumAndArtistDetailsTV;
ImageView favouriteIV;
ImageView eqIv;
AnimationDrawable animationDrawable;
MyViewHolder(View itemView) {
super(itemView);
albumImageIV = (ImageView) itemView.findViewById(R.id.album_artwork_iv);
trackNameTV = (TextView) itemView.findViewById(R.id.title_name_tv);
albumAndArtistDetailsTV = (TextView) itemView.findViewById(R.id.artist_author_name_tv);
favouriteIV = (ImageView) itemView.findViewById(R.id.fav_iv);
eqIv = (ImageView) itemView.findViewById(R.id.eq_iv);
}
}
/**
* Swap the data with the new JDO list
*
* #param pSongDetailsJDOs
*/
public void swapData(ArrayList<SongDetailsJDO> pSongDetailsJDOs) {
mSongDetailsJDOs = pSongDetailsJDOs;
notifyDataSetChanged();
}
/**
* Returns the list of currently loaded JDO's
* #return
*/
public List<SongDetailsJDO> getData() {
return mSongDetailsJDOs;
}
/**
* Gets the #{#link SongDetailsJDO} object at the specified position
* #param pPosition
* #return the {#link SongDetailsJDO} object
*/
public SongDetailsJDO getItemAtPosition(int pPosition) {
return mSongDetailsJDOs.get(pPosition);
}
/**
* Update Song Play status
* #param pStatus the status weather is playing or not
* #param lSongId the song id the playing song
*/
public void updateSongPlayStatus(boolean pStatus, String lSongId) {
mIsSongPlaying = pStatus;
mCurrentSongId = lSongId;
notifyDataSetChanged();
}
}
SongListActivity.java
public class SongsListActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>, SharedPreferences.OnSharedPreferenceChangeListener {
private RecyclerView mRecyclerView;
private SongListAdapter mAdapter;
private ArrayList<SongDetailsJDO> mSongDetailsJDOs;
private TextView mNoSongTV;
private static final int LOADER_ID = 101;
private int REQUEST_CODE = 102;
private static final String TAG = "SongsListActivity";
private SharedPreferences mSharedPreferences;
private SharedPreferences.Editor mPrefEditor;
private SharedPreferences.OnSharedPreferenceChangeListener mOnSharedPreferenceChangeListener;
private FirebaseAnalytics mFirebaseAnalytics;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView) findViewById(R.id.rec_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(SongsListActivity.this));
mNoSongTV = (TextView) findViewById(R.id.no_song_tv);
mSongDetailsJDOs = new ArrayList<>();
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
mPrefEditor = mSharedPreferences.edit();
mSharedPreferences.registerOnSharedPreferenceChangeListener(this);
FirebaseApp.initializeApp(this);
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
loadData();
}
private void loadData() {
FirebaseCrash.report(new Exception("OMG An Exception"));
boolean lIsAppLoadingFirstTime = mSharedPreferences.getBoolean(getString(R.string.is_app_loading_first_time), true);
if (lIsAppLoadingFirstTime) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
} else {
mPrefEditor.putBoolean(getString(R.string.is_app_loading_first_time), false);
mPrefEditor.apply();
new LoadDataToDbBackground().execute();
// TODO: Create Loader here
}
} else {
loadDataToRecyclerView();
if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
// TODO: Create Loader here
SongDetailsJDO lJDO = getSongJDO(mSharedPreferences.getString(getString(R.string.song_id), ""));
startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
.putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
}
}
}
private class LoadDataToDbBackground extends AsyncTask<Void, Integer, Void> {
ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(SongsListActivity.this);
mProgressDialog.setMessage("Please Wait");
mProgressDialog.setTitle("Loading");
mProgressDialog.show();
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
mProgressDialog.dismiss();
super.onPostExecute(aVoid);
}
#Override
protected Void doInBackground(Void... params) {
CommonHelper lHelper = new CommonHelper();
lHelper.loadSongToDB(SongsListActivity.this);
runOnUiThread(new Runnable() {
#Override
public void run() {
loadDataToRecyclerView();
}
});
return null;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == 0) {
boolean lGranted = true;
for (int lResult : grantResults) {
if (lResult == PackageManager.PERMISSION_DENIED)
lGranted = false;
}
if (lGranted)
loadData();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
if (data != null && data.getExtras() != null && resultCode == PlayerActivity.RESULT_CODE) {
//if data changed reload the recyclerView
if (data.getBooleanExtra(getString(R.string.is_data_changed), false)) {
mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
mAdapter.swapData(mSongDetailsJDOs);
}
}
}
// updateCurrentSongIndication();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater lMenuInflater = getMenuInflater();
lMenuInflater.inflate(R.menu.menu_song_list, menu);
SearchManager lSearchManager = (SearchManager) getSystemService(SEARCH_SERVICE);
SearchView lSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
lSearchView.setSearchableInfo(lSearchManager.getSearchableInfo(getComponentName()));
lSearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public boolean onQueryTextChange(String newText) {
filterRecView(newText);
return true;
}
});
return true;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(this, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.TITLE + " ASC");
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
ArrayList<SongDetailsJDO> lSongDetailsNew = new ArrayList<>();
if (data.moveToFirst()) {
do {
lSongDetailsNew.add(new SongDetailsJDO(data.getString(data.getColumnIndex(MediaStore.Audio.Media.TITLE)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID)),
data.getString(data.getColumnIndex(MediaStore.Audio.Media._ID)),
data.getInt(data.getColumnIndex(MediaStore.Audio.Media.DURATION)), 0));
} while (data.moveToNext());
}
compareDataAndMakeChangesToDB(lSongDetailsNew);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
#Override
protected void onResume() {
super.onResume();
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
Log.d(TAG, "onWindowFocusChanged: ");
updateCurrentSongIndication();
}
private void updateCurrentSongIndication() {
if (mSharedPreferences.getBoolean(getString(R.string.is_song_playing), false)) {
mAdapter.updateSongPlayStatus(true, mSharedPreferences.getString(getString(R.string.song_id), ""));
mRecyclerView.smoothScrollToPosition(getPositionOfSongId(mSharedPreferences.getString(getString(R.string.song_id), "")));
} else {
if(mAdapter!=null)
mAdapter.updateSongPlayStatus(false, "-1");
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updateCurrentSongIndication();
}
private void compareDataAndMakeChangesToDB(ArrayList<SongDetailsJDO> pSongDetailsNew) {
Log.d(TAG, "compareDataAndMakeChangesToDB: Called ============");
ArrayList<String> lSongIdsToBeDeleted = new ArrayList<>();
for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
lSongIdsToBeDeleted.add(lSongDetailsJDO.getSongId());
}
ArrayList<SongDetailsJDO> lNewSongsToBeAdded = new ArrayList<>();
for (SongDetailsJDO lSongDetailsJDO : pSongDetailsNew) {
if (lSongIdsToBeDeleted.contains(lSongDetailsJDO.getSongId())) {
lSongIdsToBeDeleted.remove(lSongDetailsJDO.getSongId());
} else
lNewSongsToBeAdded.add(lSongDetailsJDO);
}
if (lSongIdsToBeDeleted.size() > 0 || lNewSongsToBeAdded.size() > 0) {
SongDetailTable lSongDetailTable = new SongDetailTable(this);
lSongDetailTable.removeSongsForIds(lSongIdsToBeDeleted);
lSongDetailTable.insertSongs(lNewSongsToBeAdded);
loadDataToRecyclerView();
//
// SongPlayerService lSongPlayerService = SongPlayerService.getRunningInstance();
// if (lSongPlayerService != null)
// lSongPlayerService.dataChanged();
}
}
public void onFavClick(View pView) {
//Firebase Logging
Bundle lBundle = new Bundle();
lBundle.putString(FirebaseAnalytics.Param.ITEM_CATEGORY,"Favourite Clicked");
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.VIEW_ITEM,lBundle);
int lPosition = mRecyclerView.getChildLayoutPosition((View) pView.getParent());
SongDetailsJDO lSongDetailsJDO = mAdapter.getItemAtPosition(lPosition);
String lSongId = lSongDetailsJDO.getSongId();
SongDetailTable lSongDetailTable = new SongDetailTable(this);
int lNewFavStatus = lSongDetailsJDO.getFavouriteStatus() == 0 ? 1 : 0;
lSongDetailTable.setFavouriteStatus(lSongId, lNewFavStatus);
mAdapter.favChanged(lPosition, lNewFavStatus);
SongPlayerService mSongPlayerService = SongPlayerService.getRunningInstance();
if (mSongPlayerService != null)
mSongPlayerService.favChanged(lPosition, lNewFavStatus);
}
public void onRowClick(View pView) {
int lPosition = mRecyclerView.getChildLayoutPosition(pView);
SongDetailsJDO lJDO = mAdapter.getItemAtPosition(lPosition);
startActivityForResult(new Intent(SongsListActivity.this, PlayerActivity.class)
.putExtra(getString(R.string.song_jdo), lJDO), REQUEST_CODE);
overridePendingTransition(R.anim.from_right, R.anim.scale_down);
}
private SongDetailsJDO getSongJDO(String pSongId) {
SongDetailsJDO lJDO = null;
for (SongDetailsJDO lSongDetailsJDO : mSongDetailsJDOs) {
if (lSongDetailsJDO.getSongId().equals(pSongId)) {
lJDO = lSongDetailsJDO;
break;
}
}
return lJDO;
}
private void filterRecView(String pText) {
if (pText != null) {
if (pText.equals("")) {
mAdapter.swapData(mSongDetailsJDOs);
toggleVisibilityForNoResult(mSongDetailsJDOs.size(), pText);
} else {
ArrayList<SongDetailsJDO> lSongDetailsJDOs = new ArrayList<>();
pText = pText.toLowerCase();
for (SongDetailsJDO lDetailsJDO : mSongDetailsJDOs) {
if (lDetailsJDO.getTitle().toLowerCase().contains(pText) || lDetailsJDO.getAlbumName() != null && lDetailsJDO.getAlbumName().toLowerCase().contains(pText))
lSongDetailsJDOs.add(lDetailsJDO);
}
toggleVisibilityForNoResult(lSongDetailsJDOs.size(), pText);
mAdapter.swapData(lSongDetailsJDOs);
}
}
}
public void toggleVisibilityForNoResult(int pNumberOfSongs, String query) {
if (pNumberOfSongs == 0) {
mNoSongTV.setVisibility(View.VISIBLE);
mNoSongTV.setText(getString(R.string.nosong) + " " + query);
} else
mNoSongTV.setVisibility(View.INVISIBLE);
}
public void loadDataToRecyclerView() {
//Loading data to RecyclerView
mSongDetailsJDOs = new SongDetailTable(this).getAllSongs();
mAdapter = new SongListAdapter(SongsListActivity.this, mSongDetailsJDOs);
mRecyclerView.setAdapter(mAdapter);
}
public int getPositionOfSongId(String pSongId) {
int lPostion = -1;
for (int i = 0; i < mSongDetailsJDOs.size(); i++) {
if (mSongDetailsJDOs.get(i).getSongId().equals(pSongId)) {
lPostion = i;
break;
}
}
return lPostion;
}
}
Looking at your problem its not possible to tell exact cause of an issue.
But still i will give some hint over issue.
Check your code inside
mSongDetailsJDOs.size(); what is size of the list, it should be > 0. If not then check inside your activity how you are passing list.
#Override
public int getItemCount() {
if (mSongDetailsJDOs != null)
return mSongDetailsJDOs.size();
else
return 0;
}
If above list is > 0 then check it inside onBindViewHolder() that you are getting position one by one and try to render one item a time.
let me know if above works for you.
I am working on integrating some video into one of my Activities. It plays fine, but I have to click play for it to actually play. I searched the forums and the developer site and cannot find anything relating to autoplay or autostart. Any suggestions?
MainActivity.java
...
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
VideoView mVideoView = (VideoView) findViewById(R.id.videoView);
mVideoView.setVideoPath("file:///android_asset/video1.MP4");
mVideoView.setMediaController(new MediaController(this));
mVideoView.seekTo(1);
//mVideoView.requestFocus();
}
My contain_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment"
android:name="imaker.MediaAutoPlay.MainActivityFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:layout="#layout/fragment_main">
<VideoView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/videoView"
android:layout_height="fill_parent"
android:layout_width="fill_parent" />
</fragment>
mVideoView.start() for start video
to start video
or you can also use
mVideoView.seekTo(1)
Auto Play Video like same as Facebook Youtube popular apps Popular Apps
Build.Gradle app module
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.google.android.exoplayer:exoplayer:2.7.3'
implementation 'org.jsoup:jsoup:1.10.3'
implementation 'com.github.bumptech.glide:glide:4.9.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.9.0'
Auto Play
public class ExoPlayerRecyclerView extends RecyclerView {
private static final String TAG = "ExoPlayerRecyclerView";
private static final String AppName = "Android ExoPlayer";
/**
* PlayerViewHolder UI component
* Watch PlayerViewHolder class
*/
private ImageView mediaCoverImage, volumeControl;
private ProgressBar progressBar;
private View viewHolderParent;
private FrameLayout mediaContainer;
private PlayerView videoSurfaceView;
private SimpleExoPlayer videoPlayer;
/**
* variable declaration
*/
// Media List
private ArrayList<MediaObject> mediaObjects = new ArrayList<>();
private int videoSurfaceDefaultHeight = 0;
private int screenDefaultHeight = 0;
private Context context;
private int playPosition = -1;
private boolean isVideoViewAdded;
private RequestManager requestManager;
// controlling volume state
private VolumeState volumeState;
private OnClickListener videoViewClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
toggleVolume();
}
};
public ExoPlayerRecyclerView(#NonNull Context context) {
super(context);
init(context);
}
public ExoPlayerRecyclerView(#NonNull Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
this.context = context.getApplicationContext();
Display display = ((WindowManager) Objects.requireNonNull(
getContext().getSystemService(Context.WINDOW_SERVICE))).getDefaultDisplay();
Point point = new Point();
display.getSize(point);
videoSurfaceDefaultHeight = point.x;
screenDefaultHeight = point.y;
videoSurfaceView = new PlayerView(this.context);
videoSurfaceView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_ZOOM);
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
//Create the player using ExoPlayerFactory
videoPlayer = ExoPlayerFactory.newSimpleInstance(context, trackSelector);
// Disable Player Control
videoSurfaceView.setUseController(false);
// Bind the player to the view.
videoSurfaceView.setPlayer(videoPlayer);
// Turn on Volume
setVolumeControl(VolumeState.ON);
addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (mediaCoverImage != null) {
// show the old thumbnail
mediaCoverImage.setVisibility(VISIBLE);
}
// There's a special case when the end of the list has been reached.
// Need to handle that with this bit of logic
if (!recyclerView.canScrollVertically(1)) {
playVideo(true);
} else {
playVideo(false);
}
}
}
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
}
});
addOnChildAttachStateChangeListener(new OnChildAttachStateChangeListener() {
#Override
public void onChildViewAttachedToWindow(#NonNull View view) {
}
#Override
public void onChildViewDetachedFromWindow(#NonNull View view) {
if (viewHolderParent != null && viewHolderParent.equals(view)) {
resetVideoView();
}
}
});
videoPlayer.addListener(new Player.EventListener() {
#Override
public void onTimelineChanged(Timeline timeline, #Nullable Object manifest, int reason) {
}
#Override
public void onTracksChanged(TrackGroupArray trackGroups,
TrackSelectionArray trackSelections) {
}
#Override
public void onLoadingChanged(boolean isLoading) {
}
#Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
switch (playbackState) {
case Player.STATE_BUFFERING:
Log.e(TAG, "onPlayerStateChanged: Buffering video.");
if (progressBar != null) {
progressBar.setVisibility(VISIBLE);
}
break;
case Player.STATE_ENDED:
Log.d(TAG, "onPlayerStateChanged: Video ended.");
videoPlayer.seekTo(0);
break;
case Player.STATE_IDLE:
break;
case Player.STATE_READY:
Log.e(TAG, "onPlayerStateChanged: Ready to play.");
if (progressBar != null) {
progressBar.setVisibility(GONE);
}
if (!isVideoViewAdded) {
addVideoView();
}
break;
default:
break;
}
}
#Override
public void onRepeatModeChanged(int repeatMode) {
}
#Override
public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {
}
#Override
public void onPlayerError(ExoPlaybackException error) {
}
#Override
public void onPositionDiscontinuity(int reason) {
}
#Override
public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {
}
#Override
public void onSeekProcessed() {
}
});
}
public void playVideo(boolean isEndOfList) {
int targetPosition;
if (!isEndOfList) {
int startPosition = ((LinearLayoutManager) Objects.requireNonNull(
getLayoutManager())).findFirstVisibleItemPosition();
int endPosition = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
// if there is more than 2 list-items on the screen, set the difference to be 1
if (endPosition - startPosition > 1) {
endPosition = startPosition + 1;
}
// something is wrong. return.
if (startPosition < 0 || endPosition < 0) {
return;
}
// if there is more than 1 list-item on the screen
if (startPosition != endPosition) {
int startPositionVideoHeight = getVisibleVideoSurfaceHeight(startPosition);
int endPositionVideoHeight = getVisibleVideoSurfaceHeight(endPosition);
targetPosition =
startPositionVideoHeight > endPositionVideoHeight ? startPosition : endPosition;
} else {
targetPosition = startPosition;
}
} else {
targetPosition = mediaObjects.size() - 1;
}
Log.d(TAG, "playVideo: target position: " + targetPosition);
// video is already playing so return
if (targetPosition == playPosition) {
return;
}
// set the position of the list-item that is to be played
playPosition = targetPosition;
if (videoSurfaceView == null) {
return;
}
// remove any old surface views from previously playing videos
videoSurfaceView.setVisibility(INVISIBLE);
removeVideoView(videoSurfaceView);
int currentPosition =
targetPosition - ((LinearLayoutManager) Objects.requireNonNull(
getLayoutManager())).findFirstVisibleItemPosition();
View child = getChildAt(currentPosition);
if (child == null) {
return;
}
PlayerViewHolder holder = (PlayerViewHolder) child.getTag();
if (holder == null) {
playPosition = -1;
return;
}
mediaCoverImage = holder.mediaCoverImage;
progressBar = holder.progressBar;
volumeControl = holder.volumeControl;
viewHolderParent = holder.itemView;
requestManager = holder.requestManager;
mediaContainer = holder.mediaContainer;
videoSurfaceView.setPlayer(videoPlayer);
viewHolderParent.setOnClickListener(videoViewClickListener);
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(
context, Util.getUserAgent(context, AppName));
String mediaUrl = mediaObjects.get(targetPosition).getUrl();
if (mediaUrl != null) {
MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(mediaUrl));
videoPlayer.prepare(videoSource);
videoPlayer.setPlayWhenReady(true);
}
}
/**
* Returns the visible region of the video surface on the screen.
* if some is cut off, it will return less than the #videoSurfaceDefaultHeight
*/
private int getVisibleVideoSurfaceHeight(int playPosition) {
int at = playPosition - ((LinearLayoutManager) Objects.requireNonNull(
getLayoutManager())).findFirstVisibleItemPosition();
Log.d(TAG, "getVisibleVideoSurfaceHeight: at: " + at);
View child = getChildAt(at);
if (child == null) {
return 0;
}
int[] location = new int[2];
child.getLocationInWindow(location);
if (location[1] < 0) {
return location[1] + videoSurfaceDefaultHeight;
} else {
return screenDefaultHeight - location[1];
}
}
// Remove the old player
private void removeVideoView(PlayerView videoView) {
ViewGroup parent = (ViewGroup) videoView.getParent();
if (parent == null) {
return;
}
int index = parent.indexOfChild(videoView);
if (index >= 0) {
parent.removeViewAt(index);
isVideoViewAdded = false;
viewHolderParent.setOnClickListener(null);
}
}
private void addVideoView() {
mediaContainer.addView(videoSurfaceView);
isVideoViewAdded = true;
videoSurfaceView.requestFocus();
videoSurfaceView.setVisibility(VISIBLE);
videoSurfaceView.setAlpha(1);
mediaCoverImage.setVisibility(GONE);
}
private void resetVideoView() {
if (isVideoViewAdded) {
removeVideoView(videoSurfaceView);
playPosition = -1;
videoSurfaceView.setVisibility(INVISIBLE);
mediaCoverImage.setVisibility(VISIBLE);
}
}
public void releasePlayer() {
if (videoPlayer != null) {
videoPlayer.release();
videoPlayer = null;
}
viewHolderParent = null;
}
public void onPausePlayer() {
if (videoPlayer != null) {
videoPlayer.stop(true);
}
}
private void toggleVolume() {
if (videoPlayer != null) {
if (volumeState == VolumeState.OFF) {
Log.d(TAG, "togglePlaybackState: enabling volume.");
setVolumeControl(VolumeState.ON);
} else if (volumeState == VolumeState.ON) {
Log.d(TAG, "togglePlaybackState: disabling volume.");
setVolumeControl(VolumeState.OFF);
}
}
}
//public void onRestartPlayer() {
// if (videoPlayer != null) {
// playVideo(true);
// }
//}
private void setVolumeControl(VolumeState state) {
volumeState = state;
if (state == VolumeState.OFF) {
videoPlayer.setVolume(0f);
animateVolumeControl();
} else if (state == VolumeState.ON) {
videoPlayer.setVolume(1f);
animateVolumeControl();
}
}
private void animateVolumeControl() {
if (volumeControl != null) {
volumeControl.bringToFront();
if (volumeState == VolumeState.OFF) {
requestManager.load(R.drawable.ic_volume_off)
.into(volumeControl);
} else if (volumeState == VolumeState.ON) {
requestManager.load(R.drawable.ic_volume_on)
.into(volumeControl);
}
volumeControl.animate().cancel();
volumeControl.setAlpha(1f);
volumeControl.animate()
.alpha(0f)
.setDuration(600).setStartDelay(1000);
}
}
public void setMediaObjects(ArrayList<MediaObject> mediaObjects) {
this.mediaObjects = mediaObjects;
}
/**
* Volume ENUM
*/
private enum VolumeState {
ON, OFF
}
}
I'm devolping an music player application, when user click on an item (song) in the listview in PlayListFragment user redirects to the mediaPlayerFragment and the choosen melody starts to play. When user repeat the scenario i think that a new instance of mediaPlayer is created because there is two melodys playing at the same time.
How to avoid this problem?
(I have tried to place mediaPlayer.create(..) in onCreate() but there is probably something more that is need to be done to make it work correctly. I have also tried to create a singletonObject without success)
MediaPlayerFragment.java
public class MediaPlayerFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private MediaPlayer mediaPlayer;
private double endTime = 0;
private double startTime = 0;
private int forwardTime = 5000;
private int backwardTime = 5000;
public static int oneTimeOnly = 0;
private SeekBar seekBar;
private ImageButton btnPlay;
private ImageButton btnPause;
private ImageButton btnStop;
private ImageButton btnForward;
private ImageButton btnRewind;
public TextView songInfo;
public TextView txtEndTime;
public TextView txtStartTime;
private Handler mediaHandler = new Handler();
private boolean isPausePressed = false;
private boolean isPlayPressed = false;
private boolean isStopPressed = true;
private OnFragmentInteractionListener mListener;
private Song currentSong;
public static MediaPlayerFragment newInstance(String param1, String param2) {
MediaPlayerFragment fragment = new MediaPlayerFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public MediaPlayerFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_media_player, container, false);
getActivity().setTitle("Media Player");
songInfo = (TextView)view.findViewById(R.id.txt_currentsong);
txtEndTime = (TextView)view.findViewById(R.id.txt_time_left);
txtStartTime = (TextView)view.findViewById(R.id.txt_time_start);
seekBar = (SeekBar)view.findViewById(R.id.seek_bar_elapsed_time);
btnPlay = (ImageButton)view.findViewById(R.id.btn_play);
btnPause = (ImageButton)view.findViewById(R.id.btn_pause);
btnStop = (ImageButton)view.findViewById(R.id.btn_stop);
btnRewind = (ImageButton)view.findViewById(R.id.btn_previous);
btnForward = (ImageButton)view.findViewById(R.id.btn_next);
songInfo.setText(currentSong.getArtist() + " - " + currentSong.getTitle());
mediaPlayer = MediaPlayer.create(getActivity(), Uri.parse(currentSong.getUri()));
seekBar.setClickable(false);
btnPause.setEnabled(false);
btnStop.setEnabled(false);
btnForward.setEnabled(false);
btnRewind.setEnabled(false);
//Click events!
btnPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
pause(view);
isPausePressed = true;
isPlayPressed = false;
isStopPressed = false;
}
});
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
play(view);
isPausePressed = false;
isPlayPressed = true;
isStopPressed = false;
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stop(view);
isPausePressed = false;
isPlayPressed = false;
isStopPressed = true;
}
});
btnForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
forward(view);
isPausePressed = false;
isPlayPressed = false;
isStopPressed = false;
}
});
btnRewind.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rewind(view);
isPausePressed = false;
isPlayPressed = false;
isStopPressed = false;
}
});
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStartTrackingTouch(SeekBar s) {
}
#Override
public void onStopTrackingTouch(SeekBar s) {
}
#Override
public void onProgressChanged(SeekBar s, int progress, boolean fromUser) {
if (mediaPlayer != null && fromUser) {
mediaPlayer.seekTo(progress);
// Check if pause, play or stop buttons is pressed
if(!isPausePressed && !isPlayPressed && !isStopPressed) {
play(view);
}
}
}
});
return view;
}
public void play(View view) {
//Check if a track has been choosen from playlist...
if(currentSong.getId() != null) {
mediaPlayer.start();
endTime = mediaPlayer.getDuration();
startTime = mediaPlayer.getCurrentPosition();
if (oneTimeOnly == 0) {
seekBar.setMax((int) endTime);
oneTimeOnly = 1;
}
txtEndTime.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) endTime),
TimeUnit.MILLISECONDS.toSeconds((long) endTime) -
TimeUnit.MILLISECONDS.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) endTime)))
);
txtStartTime.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) startTime),
TimeUnit.MILLISECONDS.toSeconds((long) startTime) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
);
seekBar.setProgress((int) startTime);
mediaHandler.postDelayed(UpdateSongTime, 100);
btnPause.setEnabled(true);
btnStop.setEnabled(true);
btnRewind.setEnabled(true);
btnForward.setEnabled(true);
}
}
private Runnable UpdateSongTime = new Runnable() {
public void run() {
startTime = mediaPlayer.getCurrentPosition();
txtStartTime.setText(String.format("%d min, %d sec",
TimeUnit.MILLISECONDS.toMinutes((long) startTime),
TimeUnit.MILLISECONDS.toSeconds((long) startTime),
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes((long) startTime)))
);
seekBar.setProgress((int) startTime);
mediaHandler.postDelayed(this, 100);
}
};
public void stop(View view) {
btnPause.setEnabled(false);
btnForward.setEnabled(false);
btnRewind.setEnabled(false);
btnStop.setEnabled(false);
mediaPlayer.pause();
mediaPlayer.seekTo(0);
}
public void pause(View view) {
mediaPlayer.pause();
btnPause.setEnabled(false);
btnPlay.setEnabled(true);
}
public void forward(View view) {
int temp = (int)startTime;
if ((temp + forwardTime)<= endTime) {
startTime = startTime + forwardTime;
mediaPlayer.seekTo((int) startTime);
}
}
public void rewind(View view) {
int temp = (int) startTime;
if ((temp-backwardTime)> 0) {
startTime = startTime - backwardTime;
mediaPlayer.seekTo((int)startTime);
}
}
public void setSong(Song song) {
this.currentSong = song;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
PlayListFragment.java
public class PlayListFragment extends Fragment {
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private PlayListAdapter playListAdapter;
private ListView lstPlayList;
public static ArrayList<Song> storeSongs = new ArrayList<>();
private OnFragmentInteractionListener mListener;
public static PlayListFragment newInstance(String param1, String param2) {
PlayListFragment fragment = new PlayListFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
public PlayListFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_play_list, container, false);
getActivity().setTitle("Play List");
getSongList();
sort(storeSongs);
AddToListView(view);
lstPlayList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Song song = new Song();
//Get clicked song from listview.
song = (Song) parent.getAdapter().getItem(position);
changeToMediaPlayerFragment(song);
}
});
return view;
}
private void getSongList() {
ContentResolver musicResolver = getActivity().getContentResolver();
Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
if (musicCursor != null && musicCursor.moveToFirst()) {
//get columns
int titleColumns = musicCursor.getColumnIndex( MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
int uriColumn = musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA);
//Add songs to container (storeSongs).
do {
Long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumns);
String thisArtist = musicCursor.getString(artistColumn);
String thisUri = musicCursor.getString(uriColumn);
storeSongs.add(new Song(thisId, thisTitle, thisArtist, thisUri));
} while (musicCursor.moveToNext());
}
}
public void changeToMediaPlayerFragment(Song song) {
MediaPlayerFragment mediaPlayerFragment = MediaPlayerFragment.newInstance("", "");
mediaPlayerFragment.setSong(song);
FragmentManager fM = getFragmentManager();
FragmentTransaction fT = fM.beginTransaction();
fT.replace(R.id.container, mediaPlayerFragment, null);
fT.addToBackStack("go to mediaPlayer fragmement");
fT.commit();
}
private void AddToListView(View view) {
if (playListAdapter == null) {
playListAdapter = new PlayListAdapter(getActivity(), storeSongs);
}
this.lstPlayList = (ListView) view.findViewById(R.id.listView_play_list);
lstPlayList.setAdapter(playListAdapter);
playListAdapter.notifyDataSetChanged();
}
private void sort(ArrayList<Song> songs) {
Collections.sort(songs, new Comparator<Song>() {
#Override
public int compare(Song lhs, Song rhs) {
return lhs.getArtist().compareTo(rhs.getArtist());
}
});
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
As Dyrborg pointed out i have now made the activity responsible for holding one reference to PlayListFragment and one reference of the MediaPlayerFragment.
public void changeToPlayListFragment() {
if (playListFragment == null) {
playListFragment = PlayListFragment.newInstance("", "");
}
if (getCurrentFragment() == 2) {
return;
} else {
FragmentManager fME = getFragmentManager();
FragmentTransaction fTE = fME.beginTransaction();
fTE.replace(R.id.container, playListFragment, null);
fTE.addToBackStack("go to Playlist fragment");
fTE.commit();
}
}
private int getCurrentFragment() {
Fragment currentFragment = getFragmentManager().findFragmentById(R.id.container);
if (currentFragment instanceof MediaPlayerFragment) {
return 1;
} else if (currentFragment instanceof PlayListFragment) {
return 2;
} else {
return 0;
}
}
Link contains all java code for a simple light weight media player with knocking interaction "http://pastebin.com/BHVZYLGv"