0

I have 3 tabs in my app and I update each tab from a prompt (called by a Floating Action Button) in the MainActivity through Interface. The prompt is different according to which tab is displayed.

I want to update the currently displayed tab at once after I click OK from the prompt however what's happening is that only the interface in the first tab is working ,therefore only tab 1 gets updated.

When I click the 2nd tab and call the prompt from the MainActivity’s FAB, the 2nd tab is not updated after clicking OK in the prompt for 2nd tab though this works when the 1st tab is displayed.

How can I fix this? Please help.

Here is my code:

MainActivity FAB:

FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.floatingActionButton_main2);
fab.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {
    int position = tabLayout.getSelectedTabPosition();

    switch (position) {
      case 0:

        // first tab is selected

        AddBudget_Main(); //refresh fragment contents
        break;
      case 1:
        // second tab is selected

        /* DOES NOT WORK - 2nd TAB NOT BEING UPDATED*/
        addFund_Prompt_Main(); //refresh fragment contents 

        break;
      case 2:
        // third tab is selected

        break;

    }

MainActivity interface:

public void setPopupListener(PopupListener popupListener) {
  this.popupListener = popupListener;
}

public interface PopupListener {
  void onDialogClick(String value); //String value
}

Fragment tab:

@Override
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
  super.onViewCreated(view, savedInstanceState);
  ((Main2Activity) getActivity()).setPopupListener(new Main2Activity.PopupListener() {
    @Override
    public void onDialogClick(String value) {

      Toast.makeText(getActivity(), value, Toast.LENGTH_LONG).show();
      if (value == "settings_tab") {  //settings_tab =  2nd fragment. (different content of value variable according to the fragment)
        viewFunds(view); //refresh fragment  display
      }
    }
  });
}

addFund_Prompt_Main:

public void addFund_Prompt_Main() {
  int cnt;
  Cursor res = myDb.getConfigData();
  cnt = res.getCount();

  if (cnt == 40) {
    Toast.makeText(context, "Fund limit of 40 already reached, " +
      "delete some funds to be able to enter new items", Toast.LENGTH_LONG).show();
  } else {
    //code 2
    // get prompts.xml view
    LayoutInflater li = LayoutInflater.from(context);
    View promptsView = li.inflate(R.layout.prompts, null);

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
      context);

    // set prompts.xml to alertdialog builder
    alertDialogBuilder.setView(promptsView);

    final EditText userInput = (EditText) promptsView
      .findViewById(R.id.editTextDialogUserInput);
    final NumberPicker newPercentage = (NumberPicker) promptsView
      .findViewById(R.id.AddPercentage);

    newPercentage.setMinValue(0);
    newPercentage.setMaxValue(100);

    // set dialog message
    alertDialogBuilder
      .setCancelable(false)
      .setPositiveButton("OK",
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            // get user input and set it to result
            // edit text
            //result.setText(userInput.getText());

            //write to database
            String getInput;
            getInput = userInput.getText().toString();
            getInput = userInput.getText().toString().trim();
            if (getInput.matches(" ")) {
              Toast.makeText(context, "Cannot create empty fund name", Toast.LENGTH_LONG).show();
            } else if (getInput.matches("")) {
              Toast.makeText(context, "Cannot create empty fund name", Toast.LENGTH_LONG).show();
            } else {
              //int cntInserted;
              //cntInserted=0;
              boolean isInserted = myDb.insertFund(userInput.getText().toString().trim(), String.valueOf(newPercentage.getValue()));
              if (isInserted == true) {
                Toast.makeText(context, "Fund successfully added", Toast.LENGTH_LONG).show();
              } else {
                Toast.makeText(context, "ERROR: Fund not added", Toast.LENGTH_LONG).show();
              }

              popupListener.onDialogClick("settings_tab");

              //viewFunds(rootview);
              //create dynamic edittext to mainactivity
            }

          }
        })
      .setNegativeButton("Cancel",
        new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dialog, int id) {
            dialog.cancel();
          }
        });

    // create alert dialog
    AlertDialog alertDialog = alertDialogBuilder.create();

    // show it
    alertDialog.show();
  }


}

viewFunds:

public View viewFunds(final View rootview) { //display funds dynamically in config layout | L
  Cursor res2 = myDb.getConfigData();
  res2.moveToFirst();
  //showMessage("Number of rows",Integer.toString(res2.getCount()));

  LinearLayout linearLayout = (LinearLayout) rootview.findViewById(R.id.ll_config);

  linearLayout.removeAllViews(); //clear layout first - LINE WITH ISSUE
  linearLayout.setGravity(Gravity.CENTER);

  LinearLayout.LayoutParams lp2 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  LinearLayout.LayoutParams lp3 = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

  //create dynamic objects inside scrollview and dynamic linear layout - horizontal
  for (int i = 0; i < res2.getCount(); i++) {
    LinearLayout llh = new LinearLayout(getActivity());
    llh.setOrientation(LinearLayout.HORIZONTAL);
    LinearLayout.LayoutParams lp_llh = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    llh.setLayoutParams(lp_llh);
    llh.setBackgroundColor(Color.parseColor("#12ba15"));


    linearLayout.addView(llh);

    NumberPicker numberPicker = new NumberPicker(getActivity());
    numberPicker.setMinValue(0);
    numberPicker.setMaxValue(100);
    LinearLayout.LayoutParams lp_np = new LinearLayout.LayoutParams(70, LinearLayout.LayoutParams.WRAP_CONTENT);
    numberPicker.setLayoutParams(lp_np);
    numberPicker.setGravity(Gravity.CENTER_VERTICAL);

    //showMessage("value",res2.getString(3));
    numberPicker.setValue(Integer.parseInt(res2.getString(2))); //
    TextView textView = new TextView(getActivity());
    textView.setText(res2.getString(1));


    llh.addView(textView);
    linearLayout.addView(numberPicker);

    //create dynamic button
    final Button buttonD = new Button(getActivity());
    final Button buttonD2 = new Button(getActivity());
    buttonD.setLayoutParams(lp2);
    buttonD.setText("-");
    buttonD.setId(Integer.valueOf(res2.getString(0))); //get id from id of corresponding fund row

    buttonD2.setLayoutParams(lp3);
    buttonD2.setText("Edit");
    buttonD2.setId(Integer.valueOf(res2.getString(0)) + 100); //add 100 to separate id of edit from delete button


    ids[i] = Integer.valueOf(res2.getString(0)); //get ids and store to array
    buttonD.setOnClickListener(
      new View.OnClickListener() {
        @Override
        public void onClick(View v) {

          //showMessage("button id", Integer.toString(buttonD.getId()));

          // get prompts.xml view
          LayoutInflater li = LayoutInflater.from(getActivity());
          View promptsView = li.inflate(R.layout.confirm_delete_prompt, null); //assign to layout

          AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
            getActivity());

          // set prompts.xml to alertdialog builder
          alertDialogBuilder.setView(promptsView);

          /*final EditText userInput = (EditText) promptsView
                  .findViewById(R.id.editTextDialogUserInput);*/

          // set dialog message
          alertDialogBuilder
            .setCancelable(false)
            .setPositiveButton("OK",
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {


                  boolean isDelete = myDb.deleteData(String.valueOf(buttonD.getId()));

                  if (isDelete == true) {
                    Toast.makeText(getActivity(), "Fund Deleted", Toast.LENGTH_LONG).show();

                    viewFunds(rootview);
                  } else {
                    Toast.makeText(getActivity(), "Fund Not Deleted", Toast.LENGTH_LONG).show();
                  }
                  //create dynamic edittext to mainactivity
                }
              })
            .setNegativeButton("Cancel",
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                  dialog.cancel();
                }
              });

          // create alert dialog
          AlertDialog alertDialog = alertDialogBuilder.create();

          // show it
          alertDialog.show();

          //deleteData();
          //Cursor res = myDb.getConfigData();
          //cnt=res.getCount();

        }
      }
    );
    //edit button
    buttonD2.setOnClickListener(
      new View.OnClickListener() {
        @Override
        public void onClick(View v) {
          int x;
          x = buttonD2.getId() - 100;
          //showMessage("button id",String.valueOf(x));
          Cursor res3 = myDb.getFundName(x);
          res3.moveToFirst();

          //showMessage("btn id",String.valueOf(buttonD2.getId()));
          // get prompts.xml view
          LayoutInflater li = LayoutInflater.from(getActivity());
          View promptsView = li.inflate(R.layout.update_fund_details, null);

          AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
            getActivity());

          // set prompts.xml to alertdialog builder
          alertDialogBuilder.setView(promptsView);

          final EditText userInput = (EditText) promptsView
            .findViewById(R.id.editText_Fundname);
          final NumberPicker newPct = (NumberPicker) promptsView
            .findViewById(R.id.numberPicker_editPct);

          //FundName=res3.getF
          userInput.setText(res3.getString(1));
          newPct.setMinValue(0);
          newPct.setMaxValue(100);
          newPct.setValue(Integer.valueOf(res3.getString(2)));

          // set dialog message
          alertDialogBuilder
            .setCancelable(false)
            .setPositiveButton("OK",
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                  // get user input and set it to result

                  //write to database
                  String getInput, getInput2;
                  getInput = userInput.getText().toString().trim();
                  getInput2 = String.valueOf(newPct.getValue());

                  if (getInput.matches(" ")) {
                    Toast.makeText(getActivity(), "Cannot create empty fund name", Toast.LENGTH_LONG).show();
                  } else if (getInput.matches("")) {
                    Toast.makeText(getActivity(), "Cannot create empty fund name", Toast.LENGTH_LONG).show();
                  } else if (Double.compare(Double.valueOf(getInput2), 0) == 0) {
                    Toast.makeText(getActivity(), "Cannot create scheduled expense with no amount", Toast.LENGTH_LONG).show();
                  } else {
                    if (CheckTotalPercentage(Integer.valueOf(getInput2), String.valueOf(buttonD2.getId()))) {
                      Toast.makeText(getActivity(), "Total savings funds should not exceed 90% of income", Toast.LENGTH_LONG).show();
                    } else {
                      boolean isUpdated = myDb.updateConfigName(buttonD2.getId() - 100, String.valueOf(userInput.getText()), String.valueOf(newPct.getValue()));
                      if (isUpdated == true)
                        Toast.makeText(getActivity(), "Data Updated", Toast.LENGTH_LONG).show();
                      else
                        Toast.makeText(getActivity(), "Data not Updated", Toast.LENGTH_LONG).show();

                      viewFunds(rootview);
                    }

                  }

                  //create dynamic edittext to mainactivity


                }
              })
            .setNegativeButton("Cancel",
              new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                  dialog.cancel();
                }
              });

          // create alert dialog
          AlertDialog alertDialog = alertDialogBuilder.create();

          // show it
          alertDialog.show();
        }
      }
    );


    llh.addView(buttonD); //delete
    llh.addView(buttonD2); //edit
    //linearLayoutD.addView(button);

    res2.moveToNext();
  }

  //return scrollView;
  return rootview;

}

Sample display of viewFunds:

========================================

Fund 1 [Edit button] [Delete button]

Amount: 100

Fund 2 [Edit button] [Delete button]

Amount: 200

Fund 3 [Edit button] [Delete button]

Amount: 300

========================================

Kishan Viramgama
  • 893
  • 1
  • 11
  • 23
Glenn P
  • 37
  • 8
  • https://stackoverflow.com/questions/19677218/refresh-a-fragment-from-its-parent-activity – Zohra Khan Oct 07 '17 at 11:14
  • can you add code for `addFund_Prompt_Main();`, just wanted to see how you pass data to second fragment – Aswin P Ashok Oct 07 '17 at 11:17
  • I just added the code in the question, please see above. Thank you. – Glenn P Oct 07 '17 at 11:22
  • 1
    I dont think you really need an interface for this. Just add a method like `onDataUpdated(String updatedValue)` in all the fragments. Create a reference of all fragments before adding to tab, then when ok is prompted call `fragment.onDataUpdated(String updatedValue)` on the current fragment and update that fragment in `onDataUpdated(String updatedValue)` method. I assume you are getting the correct fragment with `tabLayout.getSelectedTabPosition();` If you want more detailed explanation as answer, let me know. – Aswin P Ashok Oct 07 '17 at 11:28
  • Yes the `getSelectedTabPosition` works fine. Can you give sample code by adding an answer? Thanks – Glenn P Oct 07 '17 at 13:14

2 Answers2

1

your this code not getting correct tab position...it always give 0 position as a result that's why only first case is executing every time.. int position = tabLayout.getSelectedTabPosition();

Use OnTabSelectedListener.... i.e

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){
@Override
    public void onTabSelected(TabLayout.Tab tab){
        int position = tab.getPosition();
}
});

using above code you will get correct tab position.... then your switch case will fall in proper case and you will get correct result...

Aswin P Ashok
  • 702
  • 8
  • 27
  • Sorry but my code is working in `int position = tabLayout.getSelectedTabPosition();`. I think this is not the issue. Thanks – Glenn P Oct 08 '17 at 03:18
1

In your activity,

Create fragment references globally.

FirstFragment firstFragment;
SecondFragment secondFragment;
ThirdFragment thirdFragment;

Then in onCreate,

firstFragment=new FirstFragment();
secondFragment=new SecondFragment();
thirdFragment=new ThirdFragment();

Then add this method in each of the fragment classes (all three of them).

public void dataUpdated(String newData){
    //Update UI with newData
}

In AddBudget_Main(), when new data is available, call firstFragment.dataUpdated(updated_data);.

In addFund_Prompt_Main() call secondFragment.dataUpdated(updated_data);. Do the same for third fragment.

Aswin P Ashok
  • 702
  • 8
  • 27
  • I get your point. Can you give sample code like this to put inside `dataUpdated`? How can I make the new data display in the 2nd fragment? Thank you. – Glenn P Oct 08 '17 at 03:13
  • Actually, I already have this method: `public View viewFunds(final View rootview)` as seen in the codes in my question. I just cannot call it in MainActivity since it has a `View` in the parameter. How can I call a method with a View parameter in `MainActivity`? – Glenn P Oct 08 '17 at 03:21
  • What component of the fragment do you want to update? TextView? – Aswin P Ashok Oct 08 '17 at 05:21
  • I need to refresh the all the views inside the fragment. I have dynamic textboxes and buttons in a linearlayout inside the fragment. That is why I used `viewFunds(final View rootview)` to refresh. – Glenn P Oct 08 '17 at 05:38
  • So what I get from all of this is, you are adding some kind of fund, with that alertDialog and you want the newly added fund to be displayed in the fragment. Is that right? How are you displaying all the funds? ListView? RecyclerView? – Aswin P Ashok Oct 08 '17 at 05:46
  • Yes that is correct. I am adding funds and listing them all in the second fragment. I added the viewFunds code (for displaying funds) in the question above, please see. I am not yet familiar with RecyclerView. Thank you. – Glenn P Oct 08 '17 at 06:53
  • What exactly does the viewFunds function do? Why are you programmatically adding views? A screenshot will help a lot – Aswin P Ashok Oct 08 '17 at 08:19
  • viewFunds lists all the funds that are saved in the database, then adds dynamic buttons beside each fund. I have added a sample in the question above. Please check. Thanks! – Glenn P Oct 09 '17 at 14:25
  • You could simply use a listView for that. Thats the best way. (RecyclerView, even better, its not that difficult). And it will make new items insertion and deletion easier – Aswin P Ashok Oct 10 '17 at 04:53
  • I see, thanks for introducing these to me since I am quite new to Android/Java. So if I use any of these I can now partner this with your code right? -> `firstFragment.dataUpdated(updated_data);.` – Glenn P Oct 10 '17 at 10:20
  • [This](http://www.vogella.com/tutorials/AndroidRecyclerView/article.html) will get you started with recyclerView – Aswin P Ashok Oct 10 '17 at 10:47
  • Thanks Aswin! I'll study this first and implement in my code together with your original answer. I'll mark your answer as correct one I am able to make it work. Thank you so much! – Glenn P Oct 11 '17 at 06:48