目前正在尝试使用捆绑包将信息从我的IncomeFragment和ExpenseFragment传输到HomeFragment,但我不确定如何操作。我尝试过实施他提供的doubleA代码。
这是我的MainActivity中的onAcceptClicked方法,它从相关片段中获取总收入/费用的值,并将其传输到HomeFragment:
public void onAcceptClicked(String fragment, String total) {
final FragmentManager fm = getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
if (fragment == "income") {
HomeFragment homeFrag = new HomeFragment();
Bundle incomeBundle = new Bundle();
incomeBundle.putString(IncomeFragment.TAG, total);
//homeFrag.newInstance(total);
ft.replace(R.id.content_layout, homeFrag, HomeFragment.TAG);
ft.commit();
}
else if (fragment == "expense"){
HomeFragment homeFragment = new HomeFragment();
Bundle expenseBundle = new Bundle();
expenseBundle.putString("bundleIncome", total);
homeFragment.setArguments(expenseBundle);
ft.replace(R.id.content_layout, homeFragment, HomeFragment.TAG);
ft.commit();
}
}
我的IncomeFragment中有一个界面,我用它来与我的MainActivity进行通信,所以我可以使用onAcceptClicked方法来传输我的总数。我计划用我的ExpenseFragment做同样的事情。下面的代码是我的IncomeFragment的一个片段:
public interface SendIncomeData {
public void onAcceptClicked(String fragment, String total);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_accept:
//Toast.makeText(getActivity(), stringIncomeTotal, Toast.LENGTH_LONG).show();
sendIncomeData.onAcceptClicked("income", stringIncomeTotal);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
不幸的是,我在这行代码中遇到错误
sendIncomeData.onAcceptClicked("income", stringIncomeTotal);
这是错误
java.lang.NullPointerException: Attempt to invoke interface method 'void mos.myapplication.IncomeFragment$SendIncomeData.onAcceptClicked(java.lang.String, java.lang.String)' on a null object reference
我不知道为什么它说有一个空对象引用和/或我如何解决这个错误。
我猜这可能会在我的HomeFragment中显示我的总计时出错,因为我在我的MainActivity或我的IncomeFragment / ExpenseFragment代码中的任何地方都没有调用该方法。我没有使用它的原因是因为我不确定如何获取它以便HomeFragment在应用程序启动时首先打开。
static HomeFragment newInstance(String total)
{
HomeFragment frag = new HomeFragment();
Bundle args = new Bundle();
args.putString(TAG, total);
frag.setArguments(args);
return frag;
}
我知道这真是一团糟,因为我已经对我的进展进行了几次编辑,但如果有人能帮助我,我真的很感激,我甚至不介意从头开始,只要我可以转移总数并从IncomeFragment>中显示它们。 HomeFragment和ExpenseFragment> HomeFragment。感谢。
答案 0 :(得分:0)
您应该使用接口在片段之间进行通信。请阅读本教程有关片段通信的内容。 http://developer.android.com/training/basics/fragments/communicating.html
收入片段不知道Home片段是否存在。如果收入片段存在,Home不知道。只有父活动知道片段是否存在。如果在片段和父活动之间设置接口,则可以使用该接口在片段之间进行通信。
HomeFragment
package com.doublea.myapplication2.app;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
/**
* Created by ShaDynastys on 9/1/2014.
*/
public class HomeFragment extends Fragment {
public static final String TAG = HomeFragment.class.getSimpleName();
private String total;
static HomeFragment newInstance(String total) {
HomeFragment frag = new HomeFragment();
Bundle args = new Bundle();
args.putString(TAG, total);
frag.setArguments(args);
return frag;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View root = inflater.inflate(R.layout.fragment, container, false);
TextView text = (TextView) root.findViewById(R.id.text);
text.setText(TAG);
return root;
}
@Override
public void onResume() {
super.onResume();
Bundle bundle = getArguments();
total = bundle.getString(TAG);
if (total != null)
Toast.makeText(getActivity(), total, Toast.LENGTH_LONG).show();
}
}
IncomeFragment
package com.doublea.myapplication2.app;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
* Created by ShaDynastys on 9/1/2014.
*/
public class IncomeFragment extends Fragment {
public static final String TAG = IncomeFragment.class.getSimpleName();
private SendIncomeData sendIncomeData;
static IncomeFragment newInstance() {
IncomeFragment frag = new IncomeFragment();
return frag;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
sendIncomeData = (SendIncomeData) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement SendIncomeData");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setRetainInstance(true);
View result = inflater.inflate(R.layout.fragment, container, false);
TextView text = (TextView) result.findViewById(R.id.text);
text.setText(TAG);
final EditText editText = (EditText) result.findViewById(R.id.editText);
editText.setVisibility(View.VISIBLE);
Button button = (Button) result.findViewById(R.id.button);
button.setVisibility(View.VISIBLE);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
sendIncomeData.onAcceptClicked("income", editText.getText().toString());
}
});
return result;
}
public interface SendIncomeData {
public void onAcceptClicked(String fragment, String total);
}
}
MainActivity
package com.doublea.myapplication2.app;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends FragmentActivity implements IncomeFragment.SendIncomeData {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupFragment();
}
private void setupFragment() {
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
IncomeFragment incomeFragment = (IncomeFragment) fm.findFragmentByTag(IncomeFragment.TAG);
if (incomeFragment == null) {
incomeFragment = IncomeFragment.newInstance();
ft.add(R.id.fragment_container, incomeFragment, IncomeFragment.TAG);
}
ft.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.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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/*if (fragment == "income") {
HomeFragment homeFragment = new HomeFragment();
Bundle incomeBundle = new Bundle();
incomeBundle.putString("bundleIncome", total);
homeFragment.setArguments(incomeBundle);
}
else if (fragment == "expense"){
HomeFragment homeFragment = new HomeFragment();
Bundle expenseBundle = new Bundle();
expenseBundle.putString("bundleIncome", total);
homeFragment.setArguments(expenseBundle);
}*/
@Override
public void onAcceptClicked(String fragment, String total) {
Bundle incomeBundle = new Bundle();
incomeBundle.putString(IncomeFragment.TAG, total);
if (fragment == "income") {
HomeFragment homeFrag = HomeFragment.newInstance(total);
final FragmentManager fm = getSupportFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.fragment_container, homeFrag, HomeFragment.TAG);
ft.commit();
}
}
}
快乐的编码。
答案 1 :(得分:0)
首先需要检查bundle是否为null:
bundle = this.getArguments();
if (bundle != null)
{
// continue with your logic
}
此外,所有Fragment-to-Fragment通信都是通过相关的Activity完成的。两个碎片永远不应该直接通信。有关详细信息,请参阅以下链接:
答案 2 :(得分:0)
很多人会争辩说使用接口是最好的方法,这并不是真正的错误,但有更简单的方法。 编辑:不一定更简单 - 一种方法是通过调用
来获取片段内活动的引用this.getActivity();
然后在你的活动类中,你可以有一个方法将数据传递给另一个片段,因为它有两个片段的引用。
- 然后实际上有更好的方法(尽管第一部分也可能有用):
在具有需要移动的数据的片段中,您可以从FragmentManager获取对其他片段的引用。这假设您使用字符串ID创建了该片段,如下所示:
Fragment otherFragment;
getSupportFragmentManager().beginTransaction().add(otherFragment, "otherFrag").commit();
然后在包含数据的片段中,您将执行:
FragmentActivity fragmentActivity = (FragmentActivity)getActivity();
OtherFragment otherFragment = (OtherFragment)fragmentActivity.getSupportFragmentManager().findFragmentByTag("otherFrag");
然后引用OtherFragment(在本例中),您可以执行以下操作:
otherFragment.dataString = "myData";
但是你可能想要进行测试以确保其他片段不会返回null,如果它是null,你可能只想创建它然后因为你已经有了参考FragmentManager。
编辑:我只是说我主观上更喜欢这种方法。