I just started learning how to create Android app and I'm stuck with methods in MainActivity.java. I don't know where to write my java code because the app is crashing.
package com.cidecode.loveometer;
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
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_main, container, false);
return rootView;
}
}
}
Things you want to be created when the activity is started should be in the onCreate method (buttons and onClickListeners etc). If for example you have a button you have stated an onClick name for in the xml file (rather than put an onClickListener on it) then you can put that function where you like as long as it is not after the last curly brace that finishes the activity. You should try the new boston tutorials on youtube, I found they explained a lot and helped me understand where I actually needed to put things.
Related
I have created an Android Studio project and i have MainActivity, FirstFragment and SecondFragment. On the FirstFragment I have an spinner element. When the app starts the spinner is filled with values, when I switch from the First to the second Fragment and back, the values are gone.
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = 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();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
PublicCameras Cameras = new PublicCameras();
//get the spinner from the xml.
Spinner dropdown = findViewById(R.id.cameraList); // This element loses his values when navigating to SecondFragment and back
ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, Cameras.GetNamesEn());
dropdown.setAdapter(adapter);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
FirstFragment
public class FirstFragment extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_first, container, false);
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_first).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
}
SecondFragment
public class SecondFragment extends Fragment {
#Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_second, container, false);
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.findViewById(R.id.button_second).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
}
I would like to point out that on rotating the values are being set again because of re-entering the function onCreateOptionsMenu. What is the best practice to keep values on a layout change?
Thank you for your time !
You're getting this issue cause when you move from one fragment to other android destorys the fragment and recreates that fragment when returned back this happens in the screen orientation case too. In order to handle this override OnSavedInstance method in you're code
There is a little hack you can make it work.
first override
#Override
public void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putStringArray("YOUR_KEY", "YOUR_OBJECT");//chnage this with you're object name
}
Now in you're onViewCreated use the SavedInstance variable and get that stringArray using the key and pass this to the spinner.
Try this and if you faced any issue do comment.
I'm having trouble implementing a backbutton in the ActionBar in a Fragment. Since this is a Fragment I don't have access to getSupportActionBar(); and each time I use this, or similar code:
ActionBar actionBar = getActivity().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
only results in NullPointerExceptions.
I've looked at numerous similar questions on StackOverflow but most of them are specified to Activities or AppCompatActivities, which do not work in Fragments. Using
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
only results in NullPointerExceptions. The other similar questions and answers have not helped me with this problem so I had to create a new topic.
This is where I get the error:
public class ExampleFragment extends Fragment{
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
ActionBar actionBar = getActivity().getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true); //This results in NullPointerException
inflater.inflate(R.menu.example_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
getActivity().getSupportFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
}
You need to receive supportActionBar.
public class ExampleFragment extends Fragment {
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
setHasOptionsMenu(true);
return super.onCreateView(inflater, container, savedInstanceState);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
ActionBar actionBar = ((AppCompatActivity)requireActivity()).getSupportActionBar();
if (actionBar!=null) {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
requireActivity().getSupportFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
}
I did not get this to work so I changed the structure of the View and made it to an Activity which has more support in dealing with this issue.
#Override
protected void onCreate(#Nullable Bundle savedInstance){
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
finish();
}
return super.onOptionsItemSelected(item);
}
I am creating a listview from the contents of my api, if I click on a listview item I want to show a new view with more details for that clicked item, currently the listview gets shown properly but if I click on an item the app crashed and I get this error message:
> java.lang.RuntimeException: Unable to start activity
> ComponentInfo{de.dev.app/de.dev.app.ui.quote.ArticleDetailActivity}:
> java.lang.NullPointerException: Attempt to invoke virtual method
> 'java.lang.String de.dev.app.jokeapp.entities.Joke.getTitle()' on a null
> object reference ... Caused by: java.lang.NullPointerException:
> Attempt to invoke virtual method 'java.lang.String
> de.dev.app.entities.Joke.getTitle()' on a null object reference
> at
> de.dev.app.ui.quote.ArticleDetailFragment.onCreateView(ArticleDetailFragment.java:100)
The error points to this lines in my ArticleDetailFragment.java:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflateAndBind(inflater, container, R.layout.fragment_article_detail);
if (!((BaseActivity) getActivity()).providesActivityToolbar()) {
((BaseActivity) getActivity()).setToolbar((Toolbar) rootView.findViewById(R.id.toolbar));
}
collapsingToolbar.setTitle(jokeItem.getTitle()); // points here
author.setText(jokeItem.getTitle());
quote.setText(jokeItem.getTitle());
jokeHeader.setText(jokeItem.getTitle());
jokeContent.setText(jokeItem.getContent());
return rootView;
}
This is my onAttach method:
#Override
public void onAttach(Context context) {
super.onAttach(context);
Bundle bundle = getArguments();
if(bundle == null) {
getActivity().finish();
return;
}
jokeItem = (Joke)bundle.getSerializable("joke");
}
This is my ArticleDetailFragment looks like:
public class ArticleDetailFragment extends BaseFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_ITEM_ID)) {
// load dummy item by using the passed item ID.
dummyItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
}
SharedPreferences preferences = this.getActivity().getSharedPreferences("pref", Context.MODE_PRIVATE);
tokenManager = TokenManager.getInstance(preferences);
service = RetrofitBuilder.createServiceWithAuth(ApiService.class, tokenManager);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflateAndBind(inflater, container, R.layout.fragment_article_detail);
if (!((BaseActivity) getActivity()).providesActivityToolbar()) {
// No Toolbar present. Set include_toolbar:
((BaseActivity) getActivity()).setToolbar((Toolbar) rootView.findViewById(R.id.toolbar));
}
collapsingToolbar.setTitle(jokeItem.getTitle());
author.setText(jokeItem.getTitle());
return rootView;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.sample_actions, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
// your logic
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Bundle bundle = getArguments();
if(bundle == null) {
getActivity().finish();
return;
}
jokeItem = (Joke)bundle.getSerializable("joke");
}
}
My ArticleDetailActivity
public class ArticleDetailActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
ArticleDetailFragment fragment = ArticleDetailFragment.newInstance(getIntent().getStringExtra(ArticleDetailFragment.ARG_ITEM_ID));
getFragmentManager().beginTransaction().replace(R.id.article_detail_container, fragment).commit();
}
#Override
public boolean providesActivityToolbar() {
return false;
}
}
Calling the ArticleDetailActivity in my ListActivit like this:
public class ListActivity extends BaseActivity implements ArticleListFragment.Callback {
...
#Override
public void onItemSelected(Joke joke) {
Intent detailIntent = new Intent(this, ArticleDetailActivity.class);
// detailIntent.putExtra(ArticleDetailFragment.ARG_ITEM_ID, id);
startActivity(detailIntent);
}
...
Call DetailActivity like this from your ListActvity,
Intent detailIntent = new Intent(this, ArticleDetailActivity.class);
// detailIntent.putExtra(ArticleDetailFragment.ARG_ITEM_ID, id);
Bundle bundle = new Bundle();
bundle.putSerializable("joke", joke);
detailIntent.putExtras(bundle);
startActivity(detailIntent);
and change your ArticleDetailActivity change like this, we need to send data to fragment
public class ArticleDetailActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
// Show the Up button in the action bar.
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
ArticleDetailFragment fragment = new ArticleDetailFragment();
fragment.setArguments(getIntent().getExtras());
getFragmentManager().beginTransaction().replace(R.id.article_detail_container, fragment).commit();
}
#Override
public boolean providesActivityToolbar() {
return false;
}
}
Add this line of code to your ArticleDetailFragment class
#BindView(R.id.title)
TextView title;
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 am New to Android. I Have Created Tab using android.support.v4.view.ViewPager. When i trying to get data from server using Json Request it give me the Error
AccountActivity is not an enclosing class.
please Any Help will be Appreciated
TAb1.java
public class Tab1 extends Fragment {
private ProgressDialog pDialog;
private UserAddress userAddress;
private TextView txtResponsec;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
new LoadUserAddress().execute();
}
class LoadUserAddress extends AsyncTask<String,String,String> {
private ProgressDialog progressDialog;
#Override
protected String doInBackground(String... params) {
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
JSONHttpClient jsonHttpClient = new JSONHttpClient();
userAddress = jsonHttpClient.Get(ServiceUrl.UserAddress, nameValuePairs, UserAddress.class);
String id = userAddress.GetId();
}
catch (Exception ex){
String message = ex.getMessage();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute(); //To change body of overridden methods use File | Settings | File Templates.
progressDialog = new ProgressDialog(AccountActivity.this);
progressDialog.setMessage("Loading products. Please wait...");
progressDialog.show();
}
#Override
protected void onPostExecute(String s) {
progressDialog.dismiss();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
txtResponsec.setText(userAddress.GetCountry());
}
});
}
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
return v;
}
}
AccountActivity.java
public class AccountActivity extends AppCompatActivity {
Toolbar toolbar;
ActionBar actionBar;
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Info.","Address","Contact","Email"};
int Numboftabs =4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_account);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
assert getSupportActionBar() != null;
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if (toolbar != null) {
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
}
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true); // To make the Tabs Fixed set this true, This makes the tabs Space Evenly in Available width
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_account, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
You should change
progressDialog = new ProgressDialog(AccountActivity.this);
to
progressDialog = new ProgressDialog(getActivity());
in Tab1 Fragment also i see txtResponsec=null you forget to initialized it.
Edit:
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1,container,false);
txtResponsec=(TextView)v.findViewById(R.id.txtResponsecId);
return v;
}