0

I am completely new to coding and have been trying to make a drug dosage calculator the idea of the app is that there is a Seekbar on top for user to adjust the body weight so that all the drug will spontaneously show the calculated dosage.

I have a successful attempt when making the first trial using one MainActivity and one XML file (referring to the pic https://i.stack.imgur.com/KhbN4.jpg)

However, when I do my second attempt to make a Tab Layout with Swipeable Views, the app force closed once I touch the Seekbar. (referring to the pic https://i.stack.imgur.com/72SYw.png)

I have been following this tutorial from androidhive.

Should those code for calculation and display done in the MainActivity class or in the fragment class? I guess my main problem is that I don't know how to setText to or findViewById from another class. Any help is appreciated.

Edit with new info: After Deleting these three lines from onProgressChanged method of my second attempt, the Seekbar work again to display the current value of slider. But once I put back these three lines to update the textView, it force close once I touch the Seekbar
mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg Q8H"); maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg Q8H"); zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg Q24H");

I can provide more info on request.

My New logcat after fixing the textView ID

10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: FATAL EXCEPTION: main 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: Process: com.example.android.b, PID: 9910 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at com.example.android.b.MainActivity$1.onProgressChanged(MainActivity.java:58) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.SeekBar.onProgressRefresh(SeekBar.java:93) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.ProgressBar.doRefreshProgress(ProgressBar.java:1303) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.ProgressBar.refreshProgress(ProgressBar.java:1315) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.ProgressBar.setProgress(ProgressBar.java:1361) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.AbsSeekBar.trackTouchEvent(AbsSeekBar.java:666) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.widget.AbsSeekBar.onTouchEvent(AbsSeekBar.java:595) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.View.dispatchTouchEvent(View.java:9294) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2553) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2254) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at com.android.internal.policy.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2403) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1737) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.app.Activity.dispatchTouchEvent(Activity.java:2765) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.support.v7.internal.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:59) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at com.android.internal.policy.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2364) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.View.dispatchPointerEvent(View.java:9514) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4230) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4096) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3787) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3844) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3695) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3661) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3669) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3642) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5922) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5896) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:5857) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6025) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:185) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) 10-24 19:07:31.865 9910-9910/com.example.android.b E/AndroidRuntime: at android.view.InputEventRe

//my success code
public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
TextView BW;
TextView maxcefaclordose;
TextView mincefaclordose;
TextView zithromaxdose;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    seekBar = (SeekBar) findViewById(R.id.seekbar);
    BW = (TextView) findViewById(R.id.textView);
    mincefaclordose = (TextView) findViewById(R.id.cefaclormin);
    maxcefaclordose = (TextView) findViewById(R.id.cefaclormax);
    zithromaxdose = (TextView) findViewById(R.id.zithromaxdose);
    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            double trueBW = (double)(progress)/10;
            long maxCefaclorDose = Math.round(trueBW*40/3);
            long minCefaclorDose = Math.round(trueBW*20/3);
            long zithromaxDose =  Math.round(trueBW*10);

            BW.setText(String.valueOf(trueBW));
            mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg  Q8H");
            maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg  Q8H");
            zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg  Q24H");
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }

    });
};

}

//here start the code I fail on second trial

public class MainActivity extends AppCompatActivity {
SeekBar seekBar;
TextView BW;
TextView maxcefaclordose;
TextView mincefaclordose;
TextView zithromaxdose;

@Override
protected void onCreate(Bundle savedInstanceState) {
    Toolbar toolbar;
    TabLayout tabLayout;
    ViewPager viewPager;

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    seekBar = (SeekBar) findViewById(R.id.seekbar);
    BW = (TextView) findViewById(R.id.textView);
    mincefaclordose = (TextView) findViewById(R.id.cefaclormin);
    maxcefaclordose = (TextView) findViewById(R.id.cefaclormax);
    zithromaxdose = (TextView) findViewById(R.id.zithromaxdose);
    toolbar = (Toolbar) findViewById(R.id.toolbar);

    setSupportActionBar(toolbar);


    seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            double trueBW = (double)(progress)/10;
            long maxCefaclorDose = Math.round(trueBW*40/3);
            long minCefaclorDose = Math.round(trueBW*20/3);
            long zithromaxDose =  Math.round(trueBW*10);

            BW.setText(String.valueOf(trueBW));
            mincefaclordose.setText(String.valueOf(minCefaclorDose)+"mg  Q8H");
            maxcefaclordose.setText(String.valueOf(maxCefaclorDose)+"mg  Q8H");
            zithromaxdose.setText(String.valueOf(zithromaxDose)+"mg  Q24H");

        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {
        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {
        }
    });
    viewPager = (ViewPager) findViewById(R.id.viewpager);
    setupViewPager(viewPager);
    tabLayout = (TabLayout) findViewById(R.id.tabs);
    tabLayout.setupWithViewPager(viewPager);
}

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new URTI(), "URTI");
    adapter.addFragment(new AntimicrobialFragment(), "Anti-\nmicrobials");
    adapter.addFragment(new Others(), "Others");
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}
}

// my activity_main.xml

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    <LinearLayout
        android:id="@+id/top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10sp"
        android:layout_marginBottom="10sp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/textView"
            android:paddingLeft="8sp"
            android:layout_width="40sp"
            android:layout_height="wrap_content"
            android:text="6.0" />

        <TextView
            android:id="@+id/kg"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/textView"
            android:text="kg" />

        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:layout_toRightOf="@+id/kg"
            android:max="500"
            android:progress="60" />
    </LinearLayout>
    <android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabGravity="fill"
        app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>

<android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Simon Ho
  • 588
  • 1
  • 8
  • 21

1 Answers1

1

You are getting NPE(NullPointerException) bcoz of incorrect id for TextView

Taking section of your success code

setContentView(R.layout.activity_main);

seekBar = (SeekBar) findViewById(R.id.seekbar);
BW = (TextView) findViewById(R.id.textView);

Taking section of your fail code

setContentView(R.layout.activity_main);
seekBar = (SeekBar) findViewById(R.id.seekbar);
BW = (TextView) findViewById(R.id.BWtextView);

As you can seen above in both case you have use activiy_main as layout but the id of BW TextView is different so solution is use R.id.textView instead of R.id.BWtextView. But if you want R.id.BWtextView then make sure in activity_main layout you have kept the id as same

SUGGESTION: Please understand exactly what is NPE from here. And you could have fixed it easily because in the logcat report you can clearly the line which is giving this NPE and which leads to crashing of application.

Update Based on the comments below
I do not know you have solved the issue of passing values or not...anyways
Solution 1: Create global variable of required TextViews in fragment and write a method for example...

public class MainActivityFragment extends Fragment {
  //your code
  TextView textView;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
  //your code
  textView = .....findViewById(R.id.texViewId)
  }

  //your code

  void setTextView(String text){
      textView.setText(text);
  }

And then in your Activity instead of doing directly adapter.addFragment(new AntimicrobialFragment(), "Anti-\nmicrobials"); create a global variable for fragment and in Listener you can do as follows.

Fragment antimicrobialFragment;  
//your code 

antimicrobialFragment = new AntimicrobialFragment(); 
//your code 

//Inside setupViewPagerAdapter
adapter.addFragment(antimicrobialFragment, "Anti-\nmicrobials");

//Inside onProgressChanged in onSeekBarChangeListener
if(null != antimicrobialFragment && antimicrobialFragment .isVisible()){
   ((AntimicrobialFragment)antimicrobialFragment ).setTextView("Sample Text");
} else {
   //just to verify 
   Toast.makeText(getBaseContext(),"Fragment is notVisible",Toast.LENGTH_LONG).show();
}

Solution 2 Use custom listener with fragment.

Community
  • 1
  • 1
Shadow Droid
  • 1,696
  • 1
  • 12
  • 26
  • Actually i did change the textview ID to BWtextView in my second attemp. Now I reverted back to the same ID as my first attempt and i still getting force close – Simon Ho Oct 24 '15 at 11:09
  • But this time error might have changed please update the question with the new logcat report – Shadow Droid Oct 24 '15 at 11:12
  • Thank you for you help. I have reverted back the ID to the textView and posted the new logcat – Simon Ho Oct 24 '15 at 11:26
  • To me your new logcat report and old logcat report looked same...but from error I can say on the TextView id doesnot match with TextView present in the layout please check it properly. because when you do findViewById if that is not present in layout then it will return null and when you do null.setText it throws exception – Shadow Droid Oct 24 '15 at 11:37
  • can you post the activity_main in the question – Shadow Droid Oct 24 '15 at 11:40
  • As I told in previous...so in activity you can see you have only 2 TextView where are the TextView with id's cefaclormin, cefaclormax, zithromaxdose – Shadow Droid Oct 24 '15 at 11:50
  • From what I understood those TextViews are in the layout used for AntimicrobialFragment() current me if I am wrong... – Shadow Droid Oct 24 '15 at 11:53
  • Yes, there are AntimicrobialFragment.java. The three TextViews need to be updated are in antimicrobial.xml. Should those calculation be done in AntimicrobialFragment.java? – Simon Ho Oct 24 '15 at 11:58
  • so directly updating from activity will throw error only...you need to pass the calculated value to the fragment and then call setText on those TextView – Shadow Droid Oct 24 '15 at 12:04
  • After many google search, I still don't know how to pass the calculated body weight from mainactivity class to the fragment class. Any more help please? – Simon Ho Oct 24 '15 at 14:29
  • Use a setter method on the fragment class – Andrew Fielden Oct 26 '15 at 13:01