2

I have a listview in one fragment and a textview in another fragment. I have to display the square of the number in the listview in the textview. However, I am getting Zero no matter what and the text doesn't change even on click of an item in the list.

Here is the code...

MainActivity.Java

package com.example.fragmentdemo;

public class MainActivity extends Activity implements Prime.onItemListSelectedListener{

    boolean mDualPane;
    int n;

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

        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }

            Prime fragmentPrime = new Prime();
            fragmentPrime.setArguments(getIntent().getExtras());
            getFragmentManager().beginTransaction()
            .add(R.id.fragment_container, fragmentPrime).commit();
        }


        Square square = (Square) getFragmentManager().findFragmentById(R.id.fragment_content_2);

        if(square != null)
        {
            // In Dual Pane Mode

            square.setSquare(n);
        }

        else
        {
            Square newFragment = (Square) getFragmentManager().findFragmentById(R.id.fragment_content_2);

            Bundle args = new Bundle();
            args.putInt("number", n);
            newFragment.setArguments(args);

            FragmentTransaction transaction = getFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.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.activity_main, menu);
        return true;
    }

    @Override
    public void onItemSelected(int number) {
        // TODO Auto-generated method stub

        n = number;
    }

}

Prime.Java - First Fragment

package com.example.fragmentdemo;

public class Prime extends Fragment{

    ArrayList<String> alPrime = new ArrayList<String>();
    ArrayAdapter<String> ad;

    onItemListSelectedListener mCallback;

    public interface onItemListSelectedListener{
        public void onItemSelected(int number);
    }


    @Override
    public void onAttach(Activity activity) {
        // TODO Auto-generated method stub
        super.onAttach(activity);


        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (onItemListSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement onItemListSelectedListener");
        }
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        View view = inflater.inflate(R.layout.fragment_prime_list, container, false);   

        setNumbers();

        final ListView lv = (ListView) view.findViewById(R.id.lvPrime);
        ad = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, alPrime);
        lv.setAdapter(ad);

        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                    long arg3) {
                // TODO Auto-generated method stub

                mCallback.onItemSelected(Integer.parseInt(lv.getItemAtPosition(arg2).toString()));
            }
        });

        return view;
    }

    private void setNumbers() {
        // TODO Auto-generated method stub
        // Will replace this code with the logic of Prime Numbers later
        for(int i = 2; i <= 10; i++)
        {
            alPrime.add(String.valueOf(i));
        }
    }

}

Square.Java - Second Fragment

package com.example.fragmentdemo;

public class Square extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub

        View view = inflater.inflate(R.layout.fragment_prime_list, container, false);
        return view;
    }

    public void setSquare(int number)
    {
           // The toast displays zero
        Toast.makeText(getActivity(), String.valueOf(number), Toast.LENGTH_LONG).show();
        TextView txtSquare = (TextView) getView().findViewById(R.id.txtViewSquare);
        int square = number * number;

    txtSquare.setText(String.valueOf(square));      
    }

}
Vamsi Challa
  • 11,038
  • 31
  • 99
  • 149

1 Answers1

3

When you activity receives the event onItemSelected, it should not only store the number, but also pass it to the second fragment if the fragment has been created, otherwise, it should create the fragment and pass it the number n via its arguments bundle.

@Override
public void onItemSelected(int number) {
    // TODO Auto-generated method stub

    n = number;

    //remove this code from onCreate and put it here
    Square square = (Square) getFragmentManager().findFragmentById(R.id.fragment_content_2);

    if(square != null)
    {
        // In Dual Pane Mode
        square.setSquare(n);
    }
    else
    {
        Square newFragment = Square.newInstance(n); 

        FragmentTransaction transaction = getFragmentManager().beginTransaction();

        // Replace whatever is in the fragment_container view with this fragment,
        // and add the transaction to the back stack so the user can navigate back
        transaction.replace(R.id.fragment_container, newFragment);
        transaction.addToBackStack(null);

        // Commit the transaction
        transaction.commit();
    }
  }

Square fragment :

public Square newInstance( int n ) {
        Square newFragment = new Square();
        Bundle args = new Bundle();
        //create a constant instead of the string 'number'
        args.putInt("number", n);
        newFragment.setArguments(args);
        return newFragment;
}
Snicolas
  • 37,840
  • 15
  • 114
  • 173
  • Yeah. I think i have done that in the onCreate() of MainActivity.java. If not could you post the place where i should. – Vamsi Challa Apr 17 '13 at 05:38
  • onCreate will execute much before the item list is clicked. – Snicolas Apr 17 '13 at 05:39
  • Oh ok.. I will give it a try and get back to you. – Vamsi Challa Apr 17 '13 at 05:39
  • Btw, your architecture is quite clean. You should neverthless consider using a bus to communicate between fragments and activities, a nice one is Otto from Square. It will give you tools to get a more flexible communication system between activities and fragments, even nested fragments. – Snicolas Apr 17 '13 at 05:41
  • You should also consider adopting a static factory method inside Square fragment to automatically put the argument n inside your arguments bundle : http://stackoverflow.com/a/9245510/693752 – Snicolas Apr 17 '13 at 05:43
  • Okie. I will go through those. Dual mode works fine now, but when it comes to single pane mode in the else part, I get an exception at newFragment.setArguments(args); Can you help me with this? – Vamsi Challa Apr 17 '13 at 05:44
  • That is my last comment, create a fragment there using a static factory method. – Snicolas Apr 17 '13 at 05:46
  • can we continue this on chat? – Vamsi Challa Apr 17 '13 at 05:58
  • Sorry I don't know how to use the tchat and I am pretty busy. You got all you need now. – Snicolas Apr 17 '13 at 10:15
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/28369/discussion-between-vamsi-challa-and-snicolas) – Vamsi Challa Apr 17 '13 at 10:32
  • Yeah, i got it sorted out.. Thanks a lot for your time and help.. Really appreciate it. – Vamsi Challa Apr 17 '13 at 10:33