Android: обновить содержимое фрагмента ViewPager после ввода данных из activity



Я просто новичок в android, и я изучал это в течение нескольких недель, но я все еще не могу найти способ заставить его работать. : (



У меня есть 4 фрагментные вкладки (созданные динамически) в моей основной деятельности. Я ввожу сумму из подсказки в основной деятельности и сохраняю ее в базе данных. Я хочу обновить значение в первой вкладке после того, как я нажму кнопку OK из приглашения, чтобы получить сумму, сохраненную в базе данных, и отобразить ее на первом фрагменте вкладки.



Как я могу обновить значения в первый счет?



В моем фрагменте у меня есть этот код для отображения данных. Но это только отображает данные изначально, а не после того, как я ввожу сумму от основной деятельности.



public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View rootview = inflater.inflate(R.layout.home_tab, container, false);
super.onCreate(savedInstanceState);
myDb = new DatabaseHelper(getContext());
viewBudget(rootview);
return rootview;
}
public View viewBudget(final View rootview) {
//get values from database and display in dynamic views
}


Я очень ценю ваши ответы. Заранее спасибо.



EDIT: вот мой полный код для viewBudget:






public View viewBudget(final View rootview) { //display funds dynamically in config layout | LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState
//Cursor res = myDb.getAllData();
//String[] textArray = {"One", "Two", "Three", "Four"};
Double budget, totalpct, temp_pct;

Cursor res2 = myDb.getConfigData();
res2.moveToFirst();

Cursor res3 = myDb.getLatestIncome();
res3.moveToFirst();
//showMessage("Number of rows",Integer.toString(res2.getCount()));

Cursor res4 = myDb.getTotalExpenes();
res4.moveToFirst();

//view contents of config table
if (res2.getCount() == 0) {
// show message
//showMessage("Error","Nothing found");
//return;
}

final ScrollView scrollView = (ScrollView) rootview.findViewById(R.id.scroll_budget);
LinearLayout linearLayout = (LinearLayout) rootview.findViewById(R.id.ll_budget);

LinearLayout llh_texts = new LinearLayout(getActivity());
llh_texts.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout llh_texts2 = new LinearLayout(getActivity());
llh_texts2.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout llh_texts3 = new LinearLayout(getActivity());
llh_texts3.setOrientation(LinearLayout.HORIZONTAL);
LinearLayout llh_texts4 = new LinearLayout(getActivity());
llh_texts4.setOrientation(LinearLayout.HORIZONTAL);

LinearLayout.LayoutParams lp_llh_texts = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
llh_texts.setLayoutParams(lp_llh_texts);

//final View linearLayout = getActivity().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);

//compute for value of budget
budget = 0.0;
totalpct = 0.0;

linearLayout.addView(llh_texts); //add button h.linearlayout to parent linearlayout inside scrollview

TextView textBudget = new TextView(getActivity());
TextView labelBudget = new TextView(getActivity());
labelBudget.setText("Budget: ");
llh_texts.addView(labelBudget);
llh_texts.addView(textBudget);

TextView textIncome = new TextView(getActivity());
TextView labelIncome = new TextView(getActivity());
labelIncome.setText("Income: ");
linearLayout.addView(llh_texts2);
llh_texts2.addView(labelIncome);
llh_texts2.addView(textIncome);

TextView textTotalFunds = new TextView(getActivity());
TextView labelFunds = new TextView(getActivity());
labelFunds.setText("Total Savings Funds: ");
linearLayout.addView(llh_texts3);
llh_texts3.addView(labelFunds);
llh_texts3.addView(textTotalFunds);

TextView textTotalExpenses = new TextView(getActivity());
TextView labelExpenses = new TextView(getActivity());
labelExpenses.setText("Total Scheduled Expenses: ");
linearLayout.addView(llh_texts4);
llh_texts4.addView(labelExpenses);
llh_texts4.addView(textTotalExpenses);

//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.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
llh.setLayoutParams(lp_llh);
//llh.setLayoutParams(lp4,llh.setOrientation(LinearLayout.HORIZONTAL); //for length and width

linearLayout.addView(llh);

//LinearLayout.LayoutParams lp_np = new LinearLayout.LayoutParams(70, LinearLayout.LayoutParams.WRAP_CONTENT);

temp_pct = (Double.valueOf(res2.getString(2)) / 100) * Double.valueOf(res3.getString(3));

EditText editText = new EditText(getActivity());
editText.setText(String.valueOf(temp_pct));
editText.setEnabled(false);

EditText editText2 = new EditText(getActivity());
editText2.setText(String.valueOf(res2.getString(2)) + "%");
editText2.setEnabled(false);

//get total of funds
totalpct = totalpct + temp_pct;

//showMessage("value",res2.getString(3));
TextView textView = new TextView(getActivity());
textView.setText(res2.getString(1));

llh.addView(textView);

llh.addView(editText);
llh.addView(editText2);

res2.moveToNext();
}

//return scrollView;
//create budget text and content
budget = Double.valueOf(res3.getString(3)) - (totalpct + res4.getDouble(0));
textBudget.setText(String.valueOf(budget));
textIncome.setText(String.valueOf(res3.getString(3)));
textTotalFunds.setText(String.valueOf(totalpct));
textTotalExpenses.setText(String.valueOf(res4.getDouble(0)));

return rootview;
}





EDIT: добавлен код на 3-й фрагмент вкладки, основанный на ответе Бхуванеша:






@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true); //Make sure you have this line of code.
setUserVisibleHint(false);
}

//@Override /*<-- this returned "method does not override method in its superclass" so I commented out*/
public void setUserVisibleHint(final View view, boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
//get data from database and refresh view.
viewFunds(view); //this method refreshes the rootview of the 3rd fragment
}
}

@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) {
//After clicking dialog ok button in Activity
// you will get value here.
//viewFunds(view);
setUserVisibleHint(view, true);
}
});
}
989   3  

3 ответов:

Вы можете сделать это с помощью интерфейса.

Создайте объект интерфейса в своей деятельности и установите объект из своего фрагмента.

В вашейдеятельности создайте объект Lister следующим образом:

public class MyActivity extends AppCompatActivity {

    private PopupListener popupListener;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Your dialog code.
         setPositiveButton("Ok", new DialogInterface.OnClickListener() {
              @Override
              public void onClick(DialogInterface dialog, int which) {
                 popupListener.onDialogClick(your_value);
              }
         })
    }

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

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

В вашем фрагменте Вы должны установить слушателя следующим образом:

public class MyFragment extends Fragment{

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ((MyActivity)getActivity()).setPopupListener(new MyActivity.PopupListener() {
            @Override
            public void onDialogClick(String value) {
                //After clicking dialog ok button in Activity
                // you will get value here.
            }
        });
    }
}

Для обновления содержимого другого фрагмента вашего viewPager переопределите приведенный ниже метод во всех ваших viewPager фрагментах.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) { 
      //get data from database and refresh view.
    }
}

Перед этим добавьте в свои фрагменты следующий код onCreate().

public void onCreate(@Nullable Bundle savedInstanceState) {
    setUserVisibleHint(false);
}

Надеюсь, это поможет:)

Сначала определите открытый метод во фрагменте, который будет повторно запрашивать базу данных, и обновите пользовательский интерфейс:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  final View rootview = inflater.inflate(R.layout.home_tab, container, false);
  super.onCreate(savedInstanceState);
  myDb = new DatabaseHelper(getContext());
  viewBudget(rootview);
  return rootview;
}

public View viewBudget(final View rootview) {
  getUpdatedDatabaseData();
}

public void getUpdatedDatabaseData() {
  //get values from database and display in dynamic views
}
Затем добавьте переопределение instantiateItem() к вашему FragmentPagerAdapter и сохраните массив ссылок на фрагменты для всех фрагментов в ViewPager. Вот простой пример:
class PagerAdapter extends FragmentPagerAdapter {
        String tabTitles[] = new String[] { "One", "Two", "Three", "Four"};
        Context context;

        //This will contain your Fragment references:
        public Fragment[] fragments = new Fragment[tabTitles.length];

        public PagerAdapter(FragmentManager fm, Context context) {
            super(fm);
            this.context = context;
        }
        @Override
        public int getCount() {
            return tabTitles.length;
        }
        @Override
        public Fragment getItem(int position) {
            switch (position) {
            case 0:
                return new FragmentOne();
            case 1:
                return new FragmentTwo();
            case 2:
                return new FragmentThree();   
            case 3:
                return new FragmentFour();
            }
            return null;
        }

        //This populates your Fragment reference array:
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment createdFragment = (Fragment) super.instantiateItem(container, position);
            fragments[position]  = createdFragment;
            return createdFragment;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            // Generate title based on item position
            return tabTitles[position];
        }         
 }

Затем, когда пользователь использовал диалоговое окно для добавления данных в базу данных, вы можете использовать этот код в действии для обновления фрагмента в первой вкладке (если это одна из активных в данный момент вкладок в базе данных). ViewPager)

    Fragment frag = mAdapter.fragments[0];
    if (frag != null && frag instanceof FragmentOne) {
      ((FragmentOne)frag).getUpdatedDatabaseData();
    }

Вы можете использовать broadcastReceiver в своем фрагменте и отправлять данные из Activity через broadcasting intent

При сохранении в базу данных в MainActivity отправьте эту широковещательную передачу

Intent intent = new Intent("key_to_identify_the_broadcast");
intent.putExtra("refresh", true);
context.sendBroadcast(intent);

А затем для вашего первого фрагмента создайте широковещательный приемник

private final BroadcastReceiver mHandleMessageReceiver = new 
BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Boolean refresh = 
            intent.getBooleanExtra("refresh",false);
        if(refresh){
           notifyDataSetChanged();
        }
        //you can call any of your methods for using this value for your use case
  }
};

Вам нужно зарегистрировать эту трансляцию в onCreateView () фрагмента

IntentFilter filter = new 
      IntentFilter("key_to_identify_the_broadcast");
       getActivity().getApplicationContext().
              registerReceiver(mHandleMessageReceiver, filter);

Вам нужно отменить регистрацию в onDestroy () вашего фрагмента

@Override
public void onDestroy() {
    try {

     getActivity().getApplicationContext().
         unregisterReceiver(mHandleMessageReceiver);

   } catch (Exception e) {
      Log.e("UnRegister Error", "> " + e.getMessage());
   }
   super.onDestroy();
}

Вы можете реализовать один и тот же широковещательный приемник для всех ваши фрагменты, где вы хотите обновить список

Comments

    Ничего не найдено.