【问题标题】:How should a fragment listen for data from an activity?片段应该如何监听来自活动的数据?
【发布时间】:2018-06-26 07:54:08
【问题描述】:

在我的 Android 应用程序中,我有一个名为“TripleTab2”的类。 TripleTab2 是一个片段,它被称为选项卡式活动的一部分。

public class TripleTab2 extends Fragment {

private TextView nameAndNumberText;
private LinearLayout nameAndNumbersLayoutSMS;

private Map<String, String> nameToNumberMapping;
private View view;
private ArrayList<String> chosenSMSContacts;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    view = inflater.inflate(R.layout.assign_pattern_tab_2, container, false);
    nameAndNumberText = (TextView) view.findViewById(R.id.numAndNameView);
    nameAndNumbersLayoutSMS = (LinearLayout) view.findViewById(R.id.nameAndNumbersLayoutSMS);
    chosenSMSContacts = getArguments().getStringArrayList("numbersToMove");
    createTextViews();

    for(String chosenSMSContact : chosenSMSContacts){
        nameAndNumberText.append(chosenSMSContact);
    }

    return view;
}

以下代码行导致问题(NullPointerException)

chosenSMSContacts = getArguments().getStringArrayList("numbersToMove");
        createTextViews();

实际上,这是有道理的,因为在tripleTab2-class 之后调用了名为"ChooseSMSContactActivity"(发送此数据)的活动类。

这里是:

public class ChooseSMSContactActivity extends AppCompatActivity {

private LinearLayout nameAndNumbersLayoutSMS;
private Map<String, String> nameToNumberMapping;
private Button selectedNumberBtn;
private ArrayList<String> selectedNamesAndNumbers;

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

    nameAndNumbersLayoutSMS = (LinearLayout) findViewById(R.id.dropDownMenuLayout);
    selectedNumberBtn = (Button) findViewById(R.id.selectedNumberBtn);
    createCheckboxes();
    selectedNamesAndNumbers = new ArrayList<>();


    selectedNumberBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            for(int i=0; i < nameAndNumbersLayoutSMS.getChildCount(); i++){
                if(nameAndNumbersLayoutSMS.getChildAt(i) instanceof CheckBox){
                    CheckBox checkBox = (CheckBox) nameAndNumbersLayoutSMS.getChildAt(i);

                    if(checkBox.isChecked()){
                        selectedNamesAndNumbers.add(checkBox.getText().toString());
                        Bundle bundle = new Bundle();
                        bundle.putStringArrayList("numbersToMove", selectedNamesAndNumbers);
                        TripleTab2 tripleTab2 = new TripleTab2();
                        tripleTab2.setArguments(bundle);
                    }
                }
            }
        }
    });


}

因此,TripleTab2 在创建时没有此数据,因为它在 ChooseSMSContactActivity 之前调用。

有人对如何解决这个问题有建议吗?我应该使用 BroadcastReceiver 还是类似的东西?

【问题讨论】:

  • 刚刚签入,您正在创建 TripleTab2 类并传递包,但是您没有对您的 tripleTab2 对象做任何事情。它只是坐在那里。您需要在活动中显示该特定对象。我猜你现在通过 XML 创建片段?
  • NullPointerException 是由于没有创建 selectedSMSContacts 的实例。您必须启动实例然后使用它,否则会提示 NullPointerException。
  • 你知道问题的原因。你到底想在这里实现什么。您还可以使用 startActivityForResult() 将结果返回给您的tab2 fragment.
  • 我建议使用片段工厂方法来创建片段的实例。您可以在 Android Studio 中创建 Fragment 时检查Include fragment factory methods? 选项。它会为你生成一个模板。

标签: android android-fragments android-activity


【解决方案1】:

我通过使用 EventBus 库解决了这个问题。

在 TripleTab2 中注册了 EventBus,并创建了一个 onEvent-method:

EventBus.getDefault().register(this);

@Subscribe
public void onEvent(CustomMessageEvent event){
    TextView nameAndNum = new TextView(view.getContext());
    nameAndNum.append(event.getCustomMessage());
    nameAndNumbersLayoutSMS.addView(nameAndNum);
}

CustomMessageEvent 类如下所示:

public class CustomMessageEvent {

private String customMessage;

public String getCustomMessage() {
    return customMessage;
}

public void setCustomMessage(String customMessage) {
    this.customMessage = customMessage;
}

在 ChooseSMSActivity 的 onClickListener 按钮中,我添加了一个 EventBus 事件:

selectedNumberBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            for(int i=0; i < nameAndNumbersLayoutSMS.getChildCount(); i++){
                if(nameAndNumbersLayoutSMS.getChildAt(i) instanceof CheckBox){
                    CheckBox checkBox = (CheckBox) nameAndNumbersLayoutSMS.getChildAt(i);

                    if(checkBox.isChecked()){
                        selectedNamesAndNumbers.add(checkBox.getText().toString());
                        CustomMessageEvent event = new CustomMessageEvent();
                        event.setCustomMessage(checkBox.getText().toString());
                        EventBus.getDefault().post(event);
                    }
                }
            }
        }
    });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多