How to add action bar in YouTube player?
I'm trying to add action bar in this activity, but because it's not extended to AppCompatActivity that's why I'm getting an error in getSupportActionBar();. I'm also getting error if I replace the YouTubeBaseActivity with AppCompatActivity. Can anyone help me with this?
public class ActivityPlayer extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
public String DEVELOPER_KEY = "key";
public String YOUTUBE_VIDEO_CODE = "5z-Roo_NpI4";
private static final int RECOVERY_DIALOG_REQUEST = 1;
YouTubePlayerView youTubeView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setupActionBar();
setContentView(R.layout.activity_main);
youTubeView = (YouTubePlayerView) findViewById(R.id.youtube_player);
youTubeView.initialize(DEVELOPER_KEY, this);
}
private void setupActionBar() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
}
return true;
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST).show();
} else {
Snackbar.make(youTubeView, "There was an error initializing the video player.", Snackbar.LENGTH_LONG).setDuration(5000).show();
}
}
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasRestored) {
if (!wasRestored) {
player.loadVideo(YOUTUBE_VIDEO_CODE);
player.setPlayerStyle(YouTubePlayer.PlayerStyle.CHROMELESS);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_DIALOG_REQUEST) {
getYouTubePlayerProvider().initialize(DEVELOPER_KEY, this);
}
}
#Override
public void onBackPressed() {
finish();
}
private YouTubePlayer.Provider getYouTubePlayerProvider() {
return (YouTubePlayerView) findViewById(R.id.youtube_player);
}
}
I had the same Problem with you, I'm posting an answer in case you or others still need a work around. Forget about YoutubeBaseActivity and focus on YoutubePlayerSupportFragment because Fragment let you setup your Activity as you wish. There is YoutubePlayerFragment also but the Support version of it work better with android support libraries.
Here's is the Steps I used :
Make your activity Extends AppCompatActivity
public class ActivityPlayer extends AppCompatActivity {
Add a FrameLayout in xml layout of the Current Activity that extends AppCompatActivity (activity_main.xml)
<FrameLayout
android:id="#+id/flYoutube"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:visibility="visible" />
Create a YoutubeFragment extends Fragment, with fragment_youtube.xml layout and a FrameLayout inside of it. And in onCreateView, create a YoutubePlayerSupportFragment instance and replace the FrameLayout within the fragment_youtube.xml with that instance of YoutubePlayerSupportFragment.
public class YoutubeFragment extends Fragment {
private static final String YOUTUBE_API_KEY = "8S7K4hEVhgOQ87501j-FAKE-KEY";
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String VIDEO_ID = "VIDEO_ID";
// TODO: Rename and change types of parameters
private String videoId;
public YoutubeFragment() {
// Required empty public constructor
}
public static YoutubeFragment newInstance(String videoId) {
YoutubeFragment fragment = new YoutubeFragment();
Bundle args = new Bundle();
args.putString(VIDEO_ID, videoId);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
videoId = getArguments().getString(VIDEO_ID);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_youtube, container, false);
YouTubePlayerSupportFragment youTubePlayerFragment = YouTubePlayerSupportFragment.newInstance();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.replace(R.id.flYoutubePlayer, youTubePlayerFragment).commit();
youTubePlayerFragment.initialize(YOUTUBE_API_KEY, new YouTubePlayer.OnInitializedListener() {
#Override
public void onInitializationSuccess(YouTubePlayer.Provider arg0, YouTubePlayer youTubePlayer, boolean b) {
if (!b) {
//youTubePlayer.setFullscreen(true);
youTubePlayer.loadVideo(videoId);
//yoTubePlayer.play();
}
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider arg0, YouTubeInitializationResult arg1) {
// TODO Auto-generated method stub
}
});
return rootView;
}
}
Create a 2nd FrameLayout in fragment_youtube.xml
<RelativeLayout 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"
tools:context="jfsl.ayibopost.fragments.YoutubeFragment">
<FrameLayout
android:id="#+id/flYoutubePlayer"
android:layout_width="match_parent"
android:layout_height="200dp"></FrameLayout>
</RelativeLayout>
Last thing to do in PlayerActivity onCreate(), is to create an instance of your own created YoutubeFragment and replace the Frame Layouts within the activity_main.xml with that YoutubeFragment instance via Fragment Transaction:
// Create Youtube Fragment instance by passing a Youtube Video ID
YoutubeFragment youtubeFragment = YoutubeFragment.newInstance("2zNSgSzhBfM");
getSupportFragmentManager().beginTransaction()
.replace(R.id.flYoutube, youtubeFragment).commit();
And you are done.
You should implement an AppCompatCallback interface.
Please, see my answer.
Related
I have created a bottomNavigation bar which consists of 5 Fragments, so once each tab is clicked it will switch from one fragment to another.
The question is:The second fragment (Search fragment) have 1 TextView with setOnClickListener so once it is been licked a layout activity will open on the top which includes a ListView to allow the user to select/click on a specific Item, so later on this selected item info should be displayed on that TextView within the(Search fragment).
The issue is that this Textview won't be updated, unless I call the mainActivity to so all fragments in bottom Navigation bar will be updated
My question is how I can refresh that specific fragment without calling the MainActivity.
public class MainActivity extends AppCompatActivity {
final Fragment f1 = new HomeFragment();
final Fragment f2 = new SearchFragment();
final Fragment f3 = new CameraFragment();
final Fragment f4 = new ChatFragment();
final Fragment f6 = new LogginFragment();
final FragmentManager fm = getSupportFragmentManager();
Fragment active = f1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationViewEx bnve = (BottomNavigationViewEx) findViewById(R.id.bottom_navigation);
bnve.enableAnimation(false);
bnve.enableShiftingMode(false);
bnve.enableItemShiftingMode(false);
bnve.setOnNavigationItemSelectedListener(navListener);
if(SharePrefManager.getInstance(this).isLoggedin()){
finish();
startActivity(new Intent(this, SuccessActivity.class));
return;
}
fm.beginTransaction().add(R.id.fragment_container, f6, "6").hide(f6).commit();
//fm.beginTransaction().add(R.id.fragment_container, f5, "5").hide(f5).commit();
fm.beginTransaction().add(R.id.fragment_container, f4, "4").hide(f4).commit();
fm.beginTransaction().add(R.id.fragment_container, f3, "3").hide(f3).commit();
fm.beginTransaction().add(R.id.fragment_container, f2, "2").hide(f2).commit();
fm.beginTransaction().add(R.id.fragment_container, f1, "1").commit();
}
public BottomNavigationViewEx.OnNavigationItemSelectedListener navListener =
new BottomNavigationViewEx.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.nav_home:
fm.beginTransaction().hide(active).show(f1).commit();
active = f1;
return true;
case R.id.nav_search:
fm.beginTransaction().hide(active).show(f2).commit();
active = f2;
return true;
case R.id.nav_camera:
fm.beginTransaction().hide(active).show(f3).commit();
active = f3;
return true;
case R.id.nav_chat:
fm.beginTransaction().hide(active).show(f4).commit();
active = f4;
return true;
case R.id.nav_account:
fm.beginTransaction().hide(active).show(f6).commit();
active = f6;
return true;
}
return false;
}
};
}
------------------------SearchFragment Class----------------------------------
This is the search fragment which has the textView (Categories) which supposed to be updated/be refershed without calling the MainActivity
public class SearchFragment extends Fragment {
private Context mContext;
TextView Categories;
static boolean status = false;
String SelectedItem;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_search,container,false);
Categories = (TextView) v.findViewById(R.id.categories);
SelectedItem = DataHolder.getInstance().getItem();
Categories.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(mContext, AllCateActivity.class));
}
});
if(status){Categories.setText(SelectedItem);}
return v;
}
public void ChangeStatus(Boolean status){
this.status = status;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
}
--------------------------DataHolder Class---------------------------------
This works as a design pattern to share arguments between the search fragment and Categories_Activity
public class DataHolder {
private static DataHolder dataHolder = null;
private DataHolder() {
}
public static DataHolder getInstance() {
if (dataHolder == null)
{
dataHolder = new DataHolder();
}
return dataHolder;
}
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
--------------------------Categories_Activity---------------------------------
This Activity once it's being called a listview will show allowing user to select an item. So once an Item has been selected it will start the MainActivity in order to refresh the Text field in the search Fragment
public class Categories_Activity extends AppCompatActivity implements View.OnClickListener {
ImageView BacktoMainCate;
ListView subCate;
public String selectedItem;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_subcategory);
subCate = (ListView)findViewById(R.id.listview_subcate);
BacktoMainCate = (ImageView)findViewById(R.id.BacktoMainCate);
BacktoMainCate.setOnClickListener(this);
final SearchFragment SF = new SearchFragment();
subCate.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectedItem = String.valueOf(parent.getItemAtPosition(position));
DataHolder.getInstance().setItem(selectedItem);
SF.ChangeStatus(true);
Intent in = new Intent(Categories_Activity.this,SuccessActivity.class);
startActivity(in);
});
}
#Override
public void onClick(View v) {
if (v == BacktoMainCate){
//startActivity(new Intent(this,AllCateActivity.class));
finish();
}
}
}
I have used SharedPreferences on both Fragment/Activity life cycle.
So once the Categories_Activity get started, Main Activity will go in onPause and with it all its Fragments will be put in onPause. When user clicks on one of the ListView items in the Categories_Activity, data of that selected item will be store inside SharedPreferences like:
PreferenceManager.getDefaultSharedPreferences(Categories_Activity .this)
.edit().putString(key, selectedItemInfo).apply();
Then override onResume() method inside MainActivity and SearchFragment:
#Override
public void onResume() {
super.onResume();
String value = PreferenceManager.getDefaultSharedPreferences(getContext())
.getString(key, "");
if (value != null && !value.isEmpty()) {
Categories.setText(value);
PreferenceManager.getDefaultSharedPreferences(getContext()).edit().remove(key);
}
}
I have a fragment which displays a mapview.
I have to inflate a menu layout from the fragment and I have added setHasOptionsMenu(true) in the code so that menu bar can inflated from the fragment.
But the interesting thing is that it doesn't show up when the fragment loads the first time. But if I switch over to some other fragment and comes back to this fragment the menu bar show up again. I have no idea why doesn't it show up in the first place.
What needs to be done ? Can some one help ?
The following is the content of the fragment layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.google.android.gms.maps.MapView android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
This is the java class.
public class SearchFragment extends Fragment implements GoogleMap.InfoWindowAdapter,
GoogleMap.OnInfoWindowClickListener, LocationListener, OnMapReadyCallback {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.i(TAG, "onCreateView()");
rootView = inflater.inflate(R.layout.fragment_search, container, false);
setHasOptionsMenu(true);
MapsInitializer.initialize(this.getActivity());
mMapView = (MapView) rootView.findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
this.markers = new HashMap<>();
this.activity = (MainActivity) this.getActivity();
return rootView;
}
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
Log.i(TAG, "onCreateOptionsMenu()");
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
this.activity.getMenuInflater().inflate(R.menu.menu_search, menu);
}
#Override
public void onMapReady(GoogleMap map) {
Log.i(TAG, "onMapReady");
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
try {
if (checkScanPermissions()) {
map.setMyLocationEnabled(true);
map.animateCamera(CameraUpdateFactory.newLatLngZoom(getLocation(), 18));
}
} catch (SecurityException e) {
Log.e(TAG, "Permission to location not granted");
}
map.setBuildingsEnabled(true);
map.getUiSettings().setZoomControlsEnabled(true);
map.setInfoWindowAdapter(this);
map.setOnInfoWindowClickListener(this);
this.mMap = map;
setUpMap(false);
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
#Override
public void onLocationChanged(Location location) {
Log.i(TAG, "onLocationChanged");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "onCreate()");
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onSaveInstanceState(Bundle outState) {
Log.i(TAG, "onSaveInstanceState()");
super.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
Log.i(TAG, "onLowMemory()");
super.onLowMemory();
mMapView.onLowMemory();
}
#Override
public void onResume() {
Log.i(TAG, "onResume()");
super.onResume();
setHasOptionsMenu(true);
mMapView.onResume();
}
}
Have You tried to remove menu.clear(); from onCreateOptionsMenu?
This line:
setHasOptionsMenu(true);
is in the wrong method. Should be in onCreate instead.
add this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
I am building an OpenGL live wallpaper. I decided to have a Navigation Drawer in my main activity since there are a lot of features the user will have access to.
The problem/issue
If I press the "hardware" back button to normally close an app the initial fragment that is shown just refreshes and the app never closes. If I hit the home button and go back to the app everything is a black screen. I've searched all throughout Google thinking that maybe I wasn't destroying the MainActivity properly or for a way to terminate a fragment. I've tried calling finish() in the main activity's onDestroy method. I've tried utilizing the remove method from fragment manager in each fragments onDetach method per posts that I've found online. Nothing has worked. I'm stumped. I've set debug points in the main activity on the onDestroy method and on the fragments onDetach method with no error being produced or any information being given. At this point I am clueless. Here's my MainActivity class.
public class MainActivity extends AppCompatActivity implements OnNavigationItemSelectedListener, OnPostSelectedListener{
FragmentManager mFragmentManager;
FragmentTransaction mFragmentTransaction;
TextView usrTag, tagrEmail;
CircleImageView tagrPic;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.add(R.id.cLMain, new PreviewFragment()).addToBackStack("PreviewFragment").commit();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
View header = navigationView.getHeaderView(0);
usrTag = (TextView)header.findViewById(R.id.usrName);
tagrEmail = (TextView)header.findViewById(R.id.usrEmail);
tagrPic = (CircleImageView)header.findViewById(R.id.usrImg);
Log.i("MainActivity: ", "User Photo: " + getProfilePic(this));
usrTag.setText(getUserName(getBaseContext()));
tagrEmail.setText(getUserEmail(getBaseContext()));
GlideUtils.loadProfileIcon(getProfilePic(getBaseContext()), tagrPic);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
Fragment fragment = null;
Class fragmentClass = null;
int id = item.getItemId();
if (id == R.id.nav_home) {
fragmentClass = PreviewFragment.class;
} else if (id == R.id.nav_custom) {
startCustomLabelCreator();
} else if (id == R.id.nav_mylabels) {
} else if (id == R.id.nav_commLabels) {
fragmentClass = PostsFragment.class;
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
}
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
// Insert the fragment by replacing any existing fragment
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.cLMain, fragment).commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
public void startCustomLabelCreator(){
Intent cLC = new Intent(getBaseContext(), CreateLabel.class);
startActivity(cLC);
}
#Override
public void onPostComment(String postKey) {
}
#Override
public void onPostLike(String postKey) {
}
#Override
public void onPhotoSelected(String photoUrl) {
}
#Override
protected void onDestroy() {
super.onDestroy();
finish();
}
}
My Fragments
public class PostsFragment extends Fragment implements ConfirmSelectedPhotoListener{
public static final String TAG = "PostsFragment";
private static final String KEY_LAYOUT_POSITION = "layoutPosition";
private int mRecyclerViewPosition = 0;
private OnPostSelectedListener mListener;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter<PostViewHolder> mAdapter;
public PostsFragment() {
// Required empty public constructor
}
public static PostsFragment newInstance() {
PostsFragment fragment = new PostsFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_posts, container, false);
rootView.setTag(TAG);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.my_recycler_view);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setReverseLayout(true);
linearLayoutManager.setStackFromEnd(true);
mRecyclerView.setLayoutManager(linearLayoutManager);
Log.d(TAG, "Restoring recycler view position (all): " + mRecyclerViewPosition);
Query allPostsQuery = FirebaseUtil.getPostsRef();
mAdapter = getFirebaseRecyclerAdapter(allPostsQuery);
mAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
#Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
// TODO: Refresh feed view.
}
});
mRecyclerView.setAdapter(mAdapter);
}
private FirebaseRecyclerAdapter<Post, PostViewHolder> getFirebaseRecyclerAdapter(Query query) {
return new FirebaseRecyclerAdapter<Post, PostViewHolder>(
Post.class, R.layout.post_item, PostViewHolder.class, query) {
#Override
public void populateViewHolder(final PostViewHolder postViewHolder,
final Post post, final int position) {
setupPost(postViewHolder, post, position, null);
}
#Override
public void onViewRecycled(PostViewHolder holder) {
super.onViewRecycled(holder);
// FirebaseUtil.getLikesRef().child(holder.mPostKey).removeEventListener(holder.mLikeListener);
}
};
}
private void setupPost(final PostViewHolder postViewHolder, final Post post, final int position, final String inPostKey) {
postViewHolder.setPhoto(post.getThumb_url());
Log.d(TAG, post.getThumb_url());
postViewHolder.setText(post.getText());
postViewHolder.setTimestamp(DateUtils.getRelativeTimeSpanString(
(long) post.getTimestamp()).toString());
final String postKey;
if (mAdapter instanceof FirebaseRecyclerAdapter) {
postKey = ((FirebaseRecyclerAdapter) mAdapter).getRef(position).getKey();
} else {
postKey = inPostKey;
}
Author author = post.getAuthor();
postViewHolder.setAuthor(author.getFull_name(), author.getUid());
postViewHolder.setIcon(author.getProfile_picture(), author.getUid());
ValueEventListener likeListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
postViewHolder.setNumLikes(dataSnapshot.getChildrenCount());
if (dataSnapshot.hasChild(FirebaseUtil.getCurrentUserId())) {
postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.LIKED, getActivity());
} else {
postViewHolder.setLikeStatus(PostViewHolder.LikeStatus.NOT_LIKED, getActivity());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
FirebaseUtil.getLikesRef().child(postKey).addValueEventListener(likeListener);
postViewHolder.mLikeListener = likeListener;
postViewHolder.setPostClickListener(new PostViewHolder.PostClickListener() {
#Override
public void showComments() {
Log.d(TAG, "Comment position: " + position);
mListener.onPostComment(postKey);
}
#Override
public void toggleLike() {
Log.d(TAG, "Like position: " + position);
mListener.onPostLike(postKey);
}
#Override
public void savePhotoUrl() {
//mListener.onPhotoSelected(post.getFull_url());
showLabelConfirm(post.getFull_url());
}
});
}
#Override
public void onDestroy() {
super.onDestroy();
if (mAdapter != null && mAdapter instanceof FirebaseRecyclerAdapter) {
((FirebaseRecyclerAdapter) mAdapter).cleanup();
}
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save currently selected layout manager.
int recyclerViewScrollPosition = getRecyclerViewScrollPosition();
Log.d(TAG, "Recycler view scroll position: " + recyclerViewScrollPosition);
savedInstanceState.putSerializable(KEY_LAYOUT_POSITION, recyclerViewScrollPosition);
super.onSaveInstanceState(savedInstanceState);
}
private int getRecyclerViewScrollPosition() {
int scrollPosition = 0;
// TODO: Is null check necessary?
if (mRecyclerView != null && mRecyclerView.getLayoutManager() != null) {
scrollPosition = ((LinearLayoutManager) mRecyclerView.getLayoutManager())
.findFirstCompletelyVisibleItemPosition();
}
return scrollPosition;
}
#Override
public void onSelectedPhoto(String selectPhoto) {
mListener.onPhotoSelected(selectPhoto);
}
public interface OnPostSelectedListener {
void onPostComment(String postKey);
void onPostLike(String postKey);
void onPhotoSelected(String photoUrl);
}
private void showLabelConfirm(String uriBmp) {
FragmentManager fm = getFragmentManager();
PhotoDialogFragment editNameDialogFragment = PhotoDialogFragment.newInstance(uriBmp);
// SETS the target fragment for use later when sending results
editNameDialogFragment.setTargetFragment(PostsFragment.this, 300);
editNameDialogFragment.show(fm, "fragment_edit_name");
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnPostSelectedListener) {
mListener = (OnPostSelectedListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnPostSelectedListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
}
Second Fragment:
public class PreviewFragment extends RajBaseFragment {
#Override
public ISurfaceRenderer createRenderer() {
return new PreviewRenderer(getContext());
}
}
Which extends:
public abstract class RajBaseFragment extends Fragment implements IDisplay, View.OnClickListener {
protected FrameLayout mLayout;
protected ISurface mRajawaliSurface;
protected ISurfaceRenderer mRenderer;
public RajBaseFragment(){
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
// Inflate the view
mLayout = (FrameLayout) inflater.inflate(getLayoutID(), container, false);
mLayout.findViewById(R.id.relative_layout_loader_container).bringToFront();
// Find the TextureView
mRajawaliSurface = (ISurface) mLayout.findViewById(R.id.rajwali_surface);
// Create the loader
mRenderer = createRenderer();
onBeforeApplyRenderer();
applyRenderer();
return mLayout;
}
protected void onBeforeApplyRenderer() {
}
protected void applyRenderer() {
mRajawaliSurface.setSurfaceRenderer(mRenderer);
}
#Override
public void onClick(View v) {
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (mLayout != null)
mLayout.removeView((View) mRajawaliSurface);
}
#Override
public int getLayoutID() {
return R.layout.rajawali_textureview_fragment;
}
}
I've tried all the recommendations below so far and the primary fragment that is set in the MainActivity's onCreate method still gets refreshed/reloaded when the back button is pressed rather than the app exiting/closing.
In your onNavigationItemSelected method, you are replacing the current fragment with fragment even in cases where fragment is null, which has undefined effects. You should not do that.
One fix is to replace this code block:
try {
fragment = (Fragment) fragmentClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
with this one:
if (fragmentClass != null) {
fragment = fragmentClass.newInstance();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.cLMain, fragment).addToBackStack().commit();
}
(and then leave out the fragment transaction below this point).
Also, there is a call to finish in the onDestroy method, which probably is not causing the problem but should be taken out because it does not make any sense there.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
replace your onOptionsItemSelected() with mine.
Don't include your first fragment into backstack.
Try to change you fragment transaction line code without addToBackStack
as below:
mFragmentTransaction.add(R.id.cLMain, new PreviewFragment()).commit();
While adding fragment with addToBackStack, this allows back
navigation for added fragment.Because of fragment in backstack,
empty(black) activity layout will be displayed.
Change onBackPressed() as below which automatically close app after if no any Fragment found in FragmentManager:
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getSupportFragmentManager().popBackStack();
}
}
Also you can see some similar Q/A on below links which helps you get more idea to solve your problem:
Fragment pressing back button
In Fragment on back button pressed Activity is blank
Transaction of fragments in android results in blank screen
It's solved my blank screen problem. Hope its helps you.
Try this code, hope this helps you, take necessary stuffs which are required for you. Also, try running this project in Android studio, it works.
https://github.com/asifali22/Navigation_Health/blob/master/app/src/main/java/com/thenewboston/mynavigation/MainActivity.java
When user press to back button it'll check fragment manager's backstack and if backstack entity count is bigger than 0 (this means there's a fragment in backstack) it'll popBackStack else it'll finish activity.
If you add your initial fragment to backstack, when user press back button they'll see a blank screen.
Also when you init your activity if you need to put a fragment it's a best practice to check if saved instance state is null. Here i modified some part of your code.
if(savedInstanceState == null){
mFragmentManager = getSupportFragmentManager();
mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.add(R.id.cLMain, new PreviewFragment()).commit();
}
I hope this'll help you. If you still have problem let me know.
Good luck.
create subclass for ISurface and override onKeyDown method like this
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.e("Custom View", "onKeyDown");
//return super.onKeyDown(keyCode, event);
return false;
}
Could be related with the lifecycle...
Try using GLSurfaceView. I believe is easier for what you want, is special for OpenGL rendering and there is plenty information about it. Examples, lifecycle among others. Let me know if helped. If not, please, provide more info.
i have loads of links that open specific webpages. at the moment they are opening in browser.They are in many different classes, what i want to do is have one web View i can inflate or run that will respond to which ever activity i am running. ie so i can open downloads.class webpages, tutorials.class webpages. all from one web View. instead of a web view for every class. i think im explaining my self correctly but i am unsure of how to even start doing this my self. hoped you guys could help thanks
this is some of the code im using so far. but because its a fragment i cant do a public constructor. i want to be able to use the String url init to change the Url from another class
public class WebViewFragment extends Fragment {
private String curURL;
public void init(String url) {
curURL = url;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater
.inflate(R.layout.webviewlayout, container, false);
init("http://www.mediafire.com/download/ezbkyava2qz44b5/AllCast.apk");
if (curURL != null) {
WebView webview = (WebView) view.findViewById(R.id.DownloadWebNav);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new webClient());
webview.loadUrl(curURL);
webview.setDownloadListener(new DownloadListener() {
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
}
});
}
return view;
}
private class webClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
}
}
you can achieve this with a simple java enum technique.Lets say you have three web views that you wish to trigger from the same activity one at a time.
public enum MenuType {
ABOUTUS, FAQS, TERMSANDCONDITION
}
Activity/fragment having three buttons that launches the webview
// in OnCreate
Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
// somewhere else in your code
public void onClick(View v) {
switch (v.getId()) {
case R.id.clickButton1: {
// launch ABOUT US webview.
startWebViewActivity(MenuType.ABOUTUS);
break;
}
case R.id.clickButton2: {
// launch FAQS webview.
startWebViewActivity(MenuType.FAQS);
break;
}
case R.id.clickButton3: {
// launch TERMSANDCONDITION webview.
startWebViewActivity(MenuType.TERMSANDCONDITION);
break;
}
default:
break;
}
// method triggered when button clicked
private void startWebViewActivity(MenuType menuType) {
Intent intent = new Intent(this, WebViewActivity.class);
intent.putExtra(WebViewActivity.INTENT_MENUTYPE, menuType);
startActivity(intent);
}
WebViewActivity.java class
public class WebViewActivity extends AppCompactActivity {
public static final String INTENT_MENUTYPE = "intent_menu_type";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/* webview layout with <Framelayout> as a child having id =container
that gets replaced by a fragment at run time.
[make your own layout here]
*/
setContentView(R.layout.activity_webview);
Bundle bundle = getIntent().getExtras();
if (bundle != null && bundle.containsKey(INTENT_MENUTYPE)) {
MenuType menuType = (MenuType) bundle.getSerializable(INTENT_MENUTYPE);
openFragment(WebViewFragment.newInstance(menuType));
}
}
public void openFragment(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction();
ft.replace(R.id.container,
fragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.addToBackStack(null);
ft.commitAllowingStateLoss();
}
}
WebViewFragment.java
public class WebViewFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {
private static final String TAG = WebViewFragment.class.getSimpleName();
WebView mWebView;
private MenuType mMenuType;
private String mUrl;
SwipeRefreshLayout mPullToLoad;
public static WebViewFragment newInstance(MenuType menuType) {
WebViewFragment fragment = new WebViewFragment();
fragment.setMenuType(menuType);
return fragment;
}
public void setMenuType(MenuType menuType) {
this.mMenuType = menuType;
}
public WebViewFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
if (mMenuType == MenuType.ABOUTUS) {
mUrl = " valid about us url";
} else if (mMenuType == MenuType.FAQS) {
mUrl = " valid FAQS url";
} else if (mMenuType == MenuType.TERMSANDCONDITION) {
mUrl = "valid terms and conditions url";
}
View view = inflater.inflate(R.layout.fragment_webview,
container, false);
// initialize views here.
int progressColor1 = ContextCompat.getColor(mContext, R.color.primary_color);
int progressColor2 = ContextCompat.getColor(mContext, R.color.primary_color_dark);
int progressColor3 = ContextCompat.getColor(mContext, R.color.dark_blue);
int progressColor4 = ContextCompat.getColor(mContext, R.color.light_orange);
mPullToLoad.setColorSchemeColors(progressColor2,progressColor3,progressColor4,progressColor1);
mPullToLoad.setOnRefreshListener(this);
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDisplayZoomControls(true);
webSettings.setSupportZoom(true);
webSettings.setUseWideViewPort(true);
webSettings.setBuiltInZoomControls(true);
mWebView.setWebViewClient(new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
showRefreshDialog();
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
dismissRefreshDialog();
}
});
mWebView.loadUrl(mUrl);
}
#Override
public void onRefresh() {
if(mWebView !=null) {
mWebView.loadUrl(mUrl);
}
}
public void showRefreshDialog() {
mPullToLoad.post(new Runnable() {
#Override
public void run() {
if(mPullToLoad != null)
mPullToLoad.setRefreshing(true);
}
});
}
public void dismissRefreshDialog() {
if(mPullToLoad!=null && mPullToLoad.isShown() )
mPullToLoad.setRefreshing(false);
}
}
fragment_webview.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/pull_to_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
hope this helps!!
I am learning about Fragments in Android and I have a problem with Logcat.
I have 2 Activities and 2 Fragments, with their Layouts:
PlayerActivity - PlayerFragment / activity_player - fragment_player
LibraryActivity - LibraryFragment / activity_library - fragment_library
I have a button in PlayerFragment to LibraryActivity, where I inflate LibraryFragment. The problem is when I am in LibraryFragment Logcat doesn't show anything.
This is the Intent that I use to call to LibraryActivity (This button is in PlayerFragment in the method onActivityCreated)
final Button to_library = (Button) getView().findViewById(R.id.library);
to_library.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent newIntent = new Intent(getActivity(), LibraryActivity.class);
startActivity(newIntent);
}
});
LibraryActivity:
public class LibraryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_library);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.library, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_library,
container, false);
return rootView;
}
}
}
LibraryFragment
public class LibraryFragment extends Fragment {
private final String LOG_TAG = "test";
public LibraryFragment() {
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
Log.v(LOG_TAG, "onAttach");
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.v(LOG_TAG, "onCreate");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_library, container,
false);
Log.v(LOG_TAG, "onCreateViewLibraryFragment");
/*
* AquĆ podemos seleccionar las Views contenidas en el Layout para
* trabajar con ellas, por ejemplo con: TipoView miView = (TipoView)
* rootView.findViewById(R.id.miViewXML);
*/
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Log.v(LOG_TAG, "onActivityCreatedLibraryFragment");
}
#Override
public void onStart() {
super.onStart();
Log.v(LOG_TAG, "onStart");
}
#Override
public void onResume() {
super.onResume();
Log.v(LOG_TAG, "onResume");
}
#Override
public void onPause() {
super.onPause();
Log.v(LOG_TAG, "onPause");
}
#Override
public void onStop() {
super.onStop();
Log.v(LOG_TAG, "onStop");
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.v(LOG_TAG, "onDestroyView");
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v(LOG_TAG, "onDestroy");
}
#Override
public void onDetach() {
super.onDetach();
Log.v(LOG_TAG, "onDetach");
}
}
Here is where I have the problem.
Logcat doesn't show the message "onActivityCreatedLibraryFragment". I have the methods onStart(), onResume(), onStop(), etc., with their "Log.v" and I have the same problem.
Thank you in advance for your help.
activity_library.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jgutierrezgil.bmusic.LibraryActivity"
tools:ignore="MergeRootFrame" />
fragment_library.xml
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.jgutierrezgil.bmusic.LibraryActivity$PlaceholderFragment" >
</RelativeLayout>
EDIT 1: I have completed the code of LibraryFragment and I have added activity_library.xml and fragment_library.xml
It looks like you never actually add LibraryFragment to your code. You are only adding PlaceholderFragment, which is leftover from the tutorial you did.
In the onCreate() of your LibraryActivity, make the following changes:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_library);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
//.add(R.id.container, new PlaceholderFragment()).commit();
.add(R.id.container, new LibraryFragment()).commit();
}
}
The PlaceholderFragment is defined at the bottom of LibraryActivity and is meant as a dummy. The reason the proper layout is showing up is because you changed the inputted layout file to R.layout.fragment_library for the PlaceholderFragment, giving the appearance that it inflated the proper Fragment.