1

I've searched a lot on how to communicate between fragments using SlidingTabLayout but haven't really got a good answer. (Although I am still quit new to android) I don't think I am too far from the solution - any help would be appreciated. Currently making a Pedometer project and I am trying to update a TextView in a SlidingTabLayout when a Step is detected. I have a StepListener Interface which is notified when a Step is detected, thought my Tabs could simply implement the interface and be notified thus incrementing my TextView as I go but having no success.

I have tried this. When debuggin noticed that it reaches the stepsChanged Method in the Tab1 but then the App crashes. Any help is appreciated.

My MainActivity....

public class PedometerActivity extends ActionBarActivity implements StepListener, ServiceConnection {

    // applying buissness rules
    public static final int DAILY_GOAL = 10000;

    public float currentSteps;


    // Declaring Your View and Variables for the UI
    Toolbar toolbar;
    ViewPager pager;
    ViewPagerAdapter adapter;
    SlidingTabLayout tabs;
    CharSequence Titles[] = {"Home", "MyStats"};
    int Numboftabs = 2;

    //declaring Variables for acess to Db and Prefs
    UserLocalStore userLocalStore;
    SharedPreferences sharedPreferences;

    //declaring variables for the Step\Service
    private StepService mStepService = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pedometer);
        userLocalStore = new UserLocalStore(this);

        this.startStepService();
        this.bindStepService();

       /* sharedPreferences = getSharedPreferences("steps", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putInt("currentSteps", numSteps); TODO remove this
        editor.commit();*/

        // Creating The Toolbar and setting it as the Toolbar for the activity
        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);


        // Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
        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 void stepsChanged(float numSteps) {


        //TODO /////

        for (int loop = 0; loop < adapter.getCount(); loop++) {

            if (adapter.getItem(0) instanceof StepListener) {
                ((StepListener) adapter.getItem(0)).stepsChanged(numSteps);
            }//end of if
        }// end of for loop

    }

    public float getCurrentSteps(float currentSteps) {

        return currentSteps;

    }


    /**
     * currently unused....code
     *
     * @return
     */
    private boolean authenticate() {
        return userLocalStore.getUserLoggedIn();
    }

    @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_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);
    }


    @Override
    protected void onPostResume() {
        super.onPostResume();
    }

    private void startStepService() {
        this.startService(new Intent(PedometerActivity.this, StepService.class));

    }

    /**
     * binds Pedometer Activity to the Service class
     * (I.e this service is going to communicate to this Activity)
     * must implement the ServiceConnection interface here
     */
    private void bindStepService() {
        this.bindService(new Intent(PedometerActivity.this, StepService.class),
                this, Context.BIND_AUTO_CREATE + Context.BIND_DEBUG_UNBIND);

    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

        mStepService = ((StepService.StepBinder) iBinder).getService();
        mStepService.registerStepListener(this);

    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }


}

my Tab1....

public class Tab1 extends Fragment implements StepListener {

    private static final int DAILY_GOAL = 10000;

    UserLocalStore userLocalStore;

    TextView tvStepValue;

    //float currentSteps;

    Database db;

    private Activity activity;
    private PieChart mPieChart;
    private PieModel sliceGoal, sliceCurrent;

    StepCounter mStepCounter;


    public Tab1() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab_1, container, false);


        tvStepValue = (TextView) v.findViewById(R.id.tvStepValue);


        // mPieChart = (PieChart) v.findViewById(R.id.piechart);
        // load data to PieCHart

        return v;
    }

    /**
     * method needed in Order to give the fragment a context to be used in conjunction with SharedPref/Database
     *
     * @param activity
     */
    @Override
    public void onAttach(Activity activity) {
        this.activity = activity;
        super.onAttach(activity);
    }

    private void loadData(View v) {


    }


    @Override
    public void stepsChanged(float numSteps) {
        tvStepValue.setText(String.valueOf(numSteps));
    }


}

my error message when the App crashes....

   09-10 17:21:29.748  26336-26336/com.example.calum.myslidingtablayout E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
        at com.example.calum.myslidingtablayout.Tab1.stepsChanged(Tab1.java:81)
        at com.example.calum.myslidingtablayout.PedometerActivity.stepsChanged(PedometerActivity.java:100)
        at com.example.calum.myslidingtablayout.StepCounter.onSensorChanged(StepCounter.java:50)
        at android.hardware.SystemSensorManager$ListenerDelegate$1.handleMessage(SystemSensorManager.java:250)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4867)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
        at dalvik.system.NativeStart.main(Native Method)
Community
  • 1
  • 1

1 Answers1

0

Communication between fragments is simple once you're used to it. In Tab 1 you need to setup your interface to and link it to the PedometerActivity class.Google explains how to preform fragment communications via interface

In short you'll end up with something like this in your Fragment's onAttach mCallback = (PedometerActivity) activity;

Alternatively you can use a library that's much easier to use and more versatile. Otto is a library from square, you can think of it like a universal interface. You won't have to register interfaces everywhere, you'll Post your data and a Subscribe method that you define will receive and handle the data in any fashion you'd like. You can communicate between fragments, Activities, class, etc with Otto. I highly recommend you check it out.

VirtualProdigy
  • 1,637
  • 1
  • 20
  • 40