Checkbox's isChecked getting NullPointerException - android

I have an activity with 6 fragments(Swipe disabled). For each fragment I have 2 button( next and previous) which move to 1 fragment next and previous perfectly. I have 2 checkboxes which I need to check if they are checked or not before migrating to next activity. But I get null pointer because checkboxes are initialized in onCreateView Method but the fragment is loaded already due to viewpager. How can I check if checkboxes are checked or not?
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
v = inflater.inflate(R.layout.fragment_step6, container, false);
cb1 = (CheckBox)v.findViewById(R.id.cb1);
next = (Button)v.findViewById(R.id.next);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(cb1.isChecked())
return true;
}
});
}

ViewPager will preload fragments for you and it's not going to remove old fragments from memory immediately. I do not think the problem is that the view is gone when the user clicks on the next button.
Check your layout file and make sure you have a checkbox in res/layout/fragment_step6.xml with the ID cb1.

pager.setOffscreenPageLimit(6);//6 = to the number you included in your question.
this will tell viewpager to retain your fragments while scrolling pages so you dont lost your state.

Related

ListView is not updating in a fragment

I have 5 fragments in an activity. And they are being showed using tabs/viewpager. Suppose they are nameD as ONE, TWO, THREE, FOUR and FIVE. I am displaying data in all fragments as ListView. I am inflating data in ListView from database cursor. The data is updated normally when i perform an add or delete in the same fragment. The problem occurs when i send/move a data from one fragment to another.
EXAMPLE OF PROBLEM:
I send/move data from fragment ONE to fragment TWO. Then I tap on fragment TWO to view data. It is not there. The data is shown when I tap on fragment FOUR or fragment FIVE and then come back to fragment ONE. Or if the app is restarted or any other Activity comes in front and goes back.
The data is not shown by clicking the adjacent tabs or swapping to adjacent tabs. And then coming back to the tab from which data was moved
I am sure someone of you must have an idea whats happening here and tell me how to solve the issue.
onCreateView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_dramas, container, false);
setHasOptionsMenu(true);
list = (ListView) view.findViewById(R.id.mylist);
return view;
}
onResume
#Override
public void onResume() {
super.onResume();
getListView();
}
onViewCreated
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
add();
}
});
}
There are other methods in the fragment too but they are not relevant to the issue. I Think these three methods are relevant. And i have no onCreate() method in the fragment..
If Fragment is already in the memory you should use BroadcastReceiver to notify other fragments whenever any data is added/removed/updated.
You can try EventBus as well.
https://github.com/greenrobot/EventBus

RecyclerView is empty when restoring fragment from backStack

I have a RecyclerView in a Fragment and initially is hidden. When user clicks a button, I set visibility to true for the RecyclerView and I display some data I have on an ArrayList.
The problem starts when I move another fragment on top (I add the previous fragment with the RecyclerView in the backStack) : if I click back from the new fragment the previous fragment (the one with the RecyclerView ) is visible and in onCreateView() I log the values of the dataSet I'm using for the recyclerView and everything is there, but the recyclerView is empty ( only footer item is presented ).
If we call RvFragment the Fragment with the RecyclerView and NextFragment the fragment that comes to the backstack and then leaves the schema is :
(back pressed)
RvFragment ----------> NextFragment ------------> RvFragment
and here's the code from onCreateView() :
#Nullable
#Override
public View onCreateView(final LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_photo_comments, container, false);
ButterKnife.bind(this, view);
Timber.i("onCreateView data.size == %d", commentArrayList.size());
setToolbarTitle();
Picasso.with(getActivity())
.load(photo)
.placeholder(R.drawable.ic_timeline_image_placeholder)
.centerCrop()
.fit()
.into(ivPhoto);
if (hasCommentsVisible) {
Timber.i("comments are visible!! and dataSize == %d", commentArrayList.size());
llFlagsCommentsContainer.setVisibility(View.GONE);
rvCommentsList.setVisibility(View.VISIBLE);
}
tvComments.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
hasCommentsVisible = true;
llFlagsCommentsContainer.setVisibility(View.GONE);
rvCommentsList.setVisibility(View.VISIBLE);
}
});
initRecyclerView();
return view;
}
You can see with the log statements in the code above I can confirm the data exist. Thanks!
I'm not sure I understand how you set up your fragment stack but just to be sure : onCreateView won't be called again when you press the back button if the fragment is still on the stack.
https://developer.android.com/training/basics/fragments/fragment-ui.html#Replace
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
Only onStart() will.
If you want onCreateView to be called again then you need to use the
FragmentTransaction.replace(NextFragment)
without the addToBackStack() but it means the whole fragment will be recreated from scratch. Probably not what you want, especially if you are getting your data from a webservice.
Alternatively, to fully recreate your fragment every time you come back to it, you can simply remove it entirely :
FragmentTransaction.remove(RvFragment)
and then push your next fragment

Place button just on the last page of a viewPager

I'm trying to have a button appear on the last page of a viewPager (which contains images in fragments). In these fragments, I'm creating a button that is invisible until the last page is shown. So far, I've achieved this behavior, but I'm having a bug where in page 2 the button appears, even though I'm "showing" (with setVisibility(View.VISIBLE)) the button only when the current page is greater or equal than 3 (there are 5 pages total, and also, greater or equal than 3 because the viewPager.getCurrentItem() behaves oddly and won't count the last or first page as an index).
My custom fragment's onCreateView() looks like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.imageview, container, false);
ivImage = (ImageView) root.findViewById(R.id.ivImageView);
btn_register = (Button) root.findViewById(R.id.button_register);
if( ((WelcomeActivity) this.getActivity()).test()>=3){
btn_register.setVisibility(View.VISIBLE);
}
setImageInViewPager();
return root;
}
In my main activity, the test() method simply returns the current page the viewPager is in:
public int test(){
return(viewPage.getCurrentItem());
}
How could I better detect the last page of a viewpager and use it so that I only display the button when the user is in the last page of the viewpager? thanks!
EDIT:
Here is a video of the problem.
HEre are the contents of my src folder: WelcomeActivity.java, FragmentPagerAdapter.java, Images.java, FragmentImageView.java.
In onPageSelected(), check the position : if(position==5) then show the button. Here I used
5 because you mention that there are 5 pages.
#Override
public void onPageSelected(int position) {
if(position == 5)
btn_register.setVisibility(View.VISIBLE);
}
Try this hope it will help you :)
You need to somehow tie the count of fragments to the individual fragments. So that each fragment knows its index. Can you add your code on how and when you are creating/adding the fragments to the view-pager?
Basing on that you can add a param to the arguments bundle while initialising the fragment there by fragment knows it's index in the view-pager.
Or else try this,
private int mCurrentPageSelected;
// In your activity
#Override
public void onPageSelected(int position) {
mCurrentPageSelected = position;
}
public int getSelectedPagePosition(){
return mCurrentPageSelected;
}
// In your fragment
public void onAttach(){
Log.d(TAG, "Fragment attached and current selected position is" + etActivity().getSelectedPagePosition());
if(getActivity().getSelectedPagePosition() >= 3){
// show the btn
btn_register.setVisibility(View.VISIBLE);
}else{
//hide the button
btn_register.setVisibility(View.GONE);
}
}

How do I only load one tab into memory at a time in Android?

I'm creating an application with a CustomPagerAdapter that can be controlled by ActionBar tabs or horizontal swipe. When you select a tab, a fragment corresponding to that tab is displayed on the screen. When the app is created and when any tab is selected, the adjacent tabs, fragments are loaded into memory. I do not want this to happen. I would like it so that when a tab is selected only that selected tab's fragment is loaded into memory. Is there a way to do this?
Edit: The code I'm currently having trouble with is as follows:
public class fragA extende Fragment
{
private VideoView videoViewA;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_A, container, false);
videoViewA = (VideoView) rootView.findViewById(R.id.videoViewA);
return rootView;
}
#Override
public void setUserVisibleHint(final boolean isVisibleToUser)
{
super.setUserVisibleHint(isVisibleToUser)
if (isVisibleToUser)
{
videoViewA.setVideoURI(LINK);
videoViewA.start();
}
else
{
videoViewA.stopPlayback();
}
}
}
The error I'm receiving is at the videoViewA.setVideoURI(LINK); line. Mind you, the link is actually there, but for privacy reasons I cannot post it.
Edit 2: It's ajava.lang.NullPointerException.
Edit 3: Sorry, but I'm doing this all the hard way. The code now reflects what I have actually written.
Try loading your videos within setUserVisbleHint(), which gets fired by the FragmentPageAdapter upon showing the fragment.
http://developer.android.com/reference/android/support/v4/app/Fragment.html#setUserVisibleHint(boolean)
If that doesn't work for you, you can also try to do check onHiddenChanged(boolean hidden).
http://developer.android.com/reference/android/app/Fragment.html#onHiddenChanged(boolean)

Handling orientation changes with Fragments

I'm currently testing my app with a multipane Fragment-ised view using the HC compatibility package, and having a lot of difficultly handling orientation changes.
My Host activity has 2 panes in landscape (menuFrame and contentFrame), and only menuFrame in portrait, to which appropriate fragments are loaded. If I have something in both panes, but then change the orientation to portrait I get a NPE as it tries to load views in the fragment which would be in the (non-existent) contentFrame. Using the setRetainState() method in the content fragment didn't work. How can I sort this out to prevent the system loading a fragment that won't be shown?
Many thanks!
It seems that the onCreateViewMethod was causing issues; it must return null if the container is null:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) // must put this in
return null;
return inflater.inflate(R.layout.<layout>, container, false);
}
Probably not the ideal answer but if you have contentFrame for portrait and in your activity only load up the menuFrame when the savedInstanceState is null then your content frame fragments will be shown on an orientation change.
Not ideal though as then if you hit the back button (as many times as necessary) then you'll never see the menu fragment as it wasn't loaded into contentFrame.
It is a shame that the FragmentLayout API demos doesn't preserve the right fragment state across an orientation change. Regardless, having thought about this problem a fair bit, and tried out various things, I'm not sure that there is a straightforward answer. The best answer that I have come up with so far (not tested) is to have the same layout in portrait and landscape but hide the menuFrame when there is something in the detailsFrame. Similarly show it, and hide frameLayout when the latter is empty.
Create new Instance only for First Time.
This does the trick:
Create a new Instance of Fragment when the
activity start for the first time else reuse the old fragment.
How can you do this?
FragmentManager is the key
Here is the code snippet:
if(savedInstanceState==null) {
userFragment = UserNameFragment.newInstance();
fragmentManager.beginTransaction().add(R.id.profile, userFragment, "TAG").commit();
}
else {
userFragment = fragmentManager.findFragmentByTag("TAG");
}
Save data on the fragment side
If your fragment has EditText, TextViews or any other class variables
which you want to save while orientation change. Save it
onSaveInstanceState() and Retrieve them in onCreateView() method
Here is the code snippet:
// Saving State
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("USER_NAME", username.getText().toString());
outState.putString("PASSWORD", password.getText().toString());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.user_name_fragment, parent, false);
username = (EditText) view.findViewById(R.id.username);
password = (EditText) view.findViewById(R.id.password);
// Retriving value
if (savedInstanceState != null) {
username.setText(savedInstanceState.getString("USER_NAME"));
password.setText(savedInstanceState.getString("PASSWORD"));
}
return view;
}
You can see the full working code HERE

Categories

Resources