Android:从活动输入数据后刷新ViewPager片段内容

时间:2017-09-11 16:59:22

标签: android android-fragments android-fragmentactivity

我刚刚刚接触到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
}

我非常感谢你的回答。提前谢谢。

编辑:这是我的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;
}
&#13;
&#13;
&#13;

编辑:根据Bhuvanesh的回答在第3个片段标签中添加了代码:

&#13;
&#13;
@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);
    }
  });
}
&#13;
&#13;
&#13;

3 个答案:

答案 0 :(得分:1)

首先,在Fragment中定义一个将重新查询数据库的公共方法,并更新UI:

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
}

然后向FragmentPagerAdapter添加instantiateItem()覆盖,并为ViewPager中的所有片段保留一组Fragment引用。 这是一个简单的例子:

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];
        }         
 }

然后,当用户使用该对话框向数据库添加数据时,您可以在Activity中使用此代码来更新第一个选项卡中的片段(如果它是ViewPager中当前活动的选项卡之一)< / p>

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

答案 1 :(得分:0)

你可以通过Interface完成。

在您的活动中创建接口对象,并从您的片段中设置对象。

活动中创建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);
}

希望有所帮助:)

答案 2 :(得分:0)

您可以在片段中使用broadcastReceiver,并通过广播意图从Activity发送数据

在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();
}

您可以为要刷新列表的所有片段实现相同的广播接收器