【问题标题】:Android Fragment class variables not available from onOptionsItemSelected() methodAndroid Fragment 类变量在 onOptionsItemSelected() 方法中不可用
【发布时间】:2015-07-27 23:12:45
【问题描述】:

我在 Activity 中有一个片段,如下所示,

   public class ViewRecordFragment extends Fragment {

    private Integer recordId;

    public ViewRecordFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        if (recordId != null) {
            new ViewRecordActivity.GetRecordToDisplay(getActivity()).execute(recordId);
            loadImageResourcesAsync(recordId);
        }

        return inflater.inflate(R.layout.fragment_view_record, container, false);
    }

    public static ViewRecordFragment newInstance(Integer recordId) {
        ViewRecordFragment fragment = new ViewRecordFragment();
        Bundle bundle = new Bundle();
        bundle.putInt(BundleHelper.RECORD_ID, recordId);
        fragment.setArguments(bundle);
        fragment.setRetainInstance(true);
        return fragment;
    }

    private void loadImageResourcesAsync(Integer recordId) {
        new LoadImageResourcesAsync(getActivity()).execute(recordId);
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

        if (getArguments() != null) {
            recordId = getArguments().getInt(BundleHelper.RECORD_ID);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        menu.clear();
        inflater.inflate(R.menu.menu_view_record, menu);
        //super.onCreateOptionsMenu(menu, inflater);
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // handle item selection
        switch (item.getItemId()) {
            case R.id.action_new_photo:

                //Integer recordId = getArguments().getInt(BundleHelper.RECORD_ID);

                Intent intent = new Intent(getActivity(), CameraActivity.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                Bundle bundle = new Bundle();
                bundle.putInt(BundleHelper.RECORD_ID, recordId);
                bundle.putString(BundleHelper.UNIQUE_IDENTIFIER, UUID.randomUUID().toString());
                intent.putExtras(bundle);
                getActivity().startActivity(intent);
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

并且活动使用这个片段来显示单个记录,

public class ViewRecordActivity extends AppCompatActivity {

    private Toolbar toolbar = null;
    private Integer recordId;
    private String patientNo;

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


        toolbar = (Toolbar) findViewById(R.id.header);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Record");

        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            recordId = extras.getInt(BundleHelper.RECORD_ID);
            patientNo = extras.getString(BundleHelper.PATIENT_NO);
            getSupportActionBar().setSubtitle("Patient Id: " + patientNo);
        }

        if (savedInstanceState == null) {
            ViewRecordFragment viewRecordFragment = ViewRecordFragment.newInstance(recordId);
            FragmentManager fragmentManager = getSupportFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .replace(R.id.view_record_fragment, viewRecordFragment
                    ).commit();
        }
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                this.finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    public static class GetRecordToDisplay extends GetRecordAsync {

        private TextView dos;
        private TextView facultyName;
        private TextView patientName;
        private TextView patientId;

        public GetRecordToDisplay(Activity activity) {
            super(activity);
            this.dos = (TextView) activity.findViewById(R.id.date_submitted_text);
            this.facultyName = (TextView) activity.findViewById(R.id.name_text);
            this.patientName = (TextView) activity.findViewById(R.id.customer_name_text);
            this.patientId = (TextView) activity.findViewById(R.id.customer_id_text);
        }


        @Override
        protected void onPostExecute(Customer customer) {

            if (customer != null) {
                this.dos.setText(customer.getDOS_D());
                this.facultyName.setText(customer.getDOS_R());
                this.patientName.setText(customer.getCUSTOMER_N());
                this.patientId.setText(customer.getCUSTOMER_C());
            }
        }

    }

当我尝试通过单击菜单项来启动新活动时,就会出现问题。单击菜单项时,我传递的这个recordId 为空。

我不确定我在这里缺少什么。我可以看到 recordId 在 Activity 内创建片段时被分配(在调试模式下)。

但是当我单击菜单项并进入该特定菜单项案例时,recordId 为空。但我期待在创建片段时分配给它的 recordId。

【问题讨论】:

  • 根据您提供的代码,当您创建一个新的片段实例时,您的recordId 为空,因此您将null 传递给参数,因此它在您的片段中是null..跨度>
  • 很抱歉我没有添加oncreate方法。在那里我可以看到这个rec​​ordId被分配并且它们被传递到片段中
  • 请注意你在这里发布的代码。你说你有一个ViewRecordFragmentonCreate 你把它当作活动。片段没有getIntent() 方法.. 我认为您在这里发布代码时遗漏了一些东西
  • 感谢 Gennadii,我已经添加了完整的代码,这样我就不会错过任何东西。我仍然有这个问题。是否有一种特殊的方式将变量传递给片段并将它们保存在片段对象中?

标签: java android android-fragments android-actionbar android-menu


【解决方案1】:

您正在为您的片段设置参数,但您没有使用它们。在片段的 onCreate 方法中执行此操作:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
    recordId = getArguments().getInt(BundleHelper.RECORD_ID);
}

【讨论】:

  • 非常感谢@Gennadii,我正在使用newInstance() 方法进行设置。作为fragment.setRecordId(recordId);。我也这样做了。但我可能错过了一些东西。我会再做一次,看看:)
  • 不要这样做:fragment.setRecordId(recordId) 因为片段会经常在屏幕旋转时重新创建,并且每次都会失去价值。 Android为此提供了参数。如果您设置它们,它们将始终可用。
  • 我在代码中添加了这个,但是问题依旧,但是我可以看到onCreate,onViewCreated,方法在实际显示视图之前执行了两次
  • recordId 仍然为空吗?
  • 这真的很奇怪,recordId 的值不应该是null,如果你的活动是通过Intent 接收的。请确保此时不是nullViewRecordFragment.newInstance(recordId); 在调用getArguments() 时还要下断点,看看值是否存在。
猜你喜欢
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 2017-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多