从父活动访问选项卡式片段方法?

时间:2017-07-08 20:59:55

标签: java android android-fragments android-activity

嗨(我是新来的,所以你必须原谅我)

我目前有一个标签式活动,其中MainActivity.java是父类,Absences.javaNotices.java是片段。我在点击选项菜单按钮时运行的MainActivity内有一个日期选择器片段。

当我成功选择了我的日期时,我想将信息传递给Absences片段中的方法。但是,我真的在努力实现这个部分。

我所做的研究似乎表明这是解决方案:

Absences fragment= (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences);
        ((Absences)fragment).updateAbsences();

但是,getSupportFragmentManager()无法从静态上下文中引用,我似乎无法找到我的片段的ID。

在做了一点研究后,似乎发现这种方法不适用于标签活动,所以我现在处于亏损状态。

有人能指出我正确的方向吗? - 我一直在研究这个问题已经有一段时间了!

SectionsPageAdapter类

Fragment one, two;

public class SectionsPagerAdapter extends FragmentPagerAdapter {

    public SectionsPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        // getItem is called to instantiate the fragment for the given page.
        // Return a PlaceholderFragment (defined as a static inner class below).
        switch (position) {
            case 0:
                if(one==null){
                    one = new Absences();
                }
                return one;
            case 1:
                if(two==null){
                    two = new Notices();
                }
                return two;
        }
        return null;
    }

    @Override
    public int getCount() {
        // Show 3 total pages.
        return 2;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "ABSENCES";
            case 1:
                return "NOTICES";
        }
        return null;
    }

}

onOptionsItemSelected

 public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.calendar) {
        DialogFragment newFragment = new DatePickerFragment();
        newFragment.show(getSupportFragmentManager(), "datePicker");
    }
    return super.onOptionsItemSelected(item);
}

DatePickerFragment

public static class DatePickerFragment extends DialogFragment
        implements DatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day);
        dialog.getDatePicker().setMaxDate(c.getTimeInMillis());
        dialog.setTitle("");
        return  dialog;
    }

    public void onDateSet(DatePicker view, int year, int month, int day) {
        Absences fragment= (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences);
        ((Absences)fragment).updateAbsences();
    }
}

- 编辑 -

根据以下建议更新了代码

MainActivity中的方法

public void onDatePicked() {
    Absences fragment = (Absences) getSupportFragmentManager().findFragmentById(R.id.absences);
    fragment.updateAbsences();
}

新的DatePickerFragment类

    package com.alexwoohouse.heartofengland;

import android.annotation.TargetApi;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.icu.util.Calendar;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.util.Log;
import android.widget.DatePicker;

import java.util.Date;

public class DatePickerFragment extends DialogFragment
        implements DatePickerDialog.OnDateSetListener {

    public interface OnDatePickedListener {
        void onDatePicked(); //This method seems to be greyed out!
    }

    @TargetApi(Build.VERSION_CODES.N)
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);
        DatePickerDialog dialog = new DatePickerDialog(getActivity(), this, year, month, day);
        dialog.getDatePicker().setMaxDate(c.getTimeInMillis());
        dialog.setTitle("");
        return  dialog;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public void onDateSet(DatePicker view, int year, int month, int day) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        cal.set(Calendar.MONTH, month);
        cal.set(Calendar.DAY_OF_MONTH, day);
    }
}

1 个答案:

答案 0 :(得分:2)

这是我的建议。

首先,将DatePickerFragment作为自己的顶级类移出。我不知道你是否有充分的理由让它成为一个静态的内部类,但你可能不需要它。

现在,通常你有片段(对话或其他)传递信息的方式是通过接口回调。因此,您不必尝试直接访问当前活动的片段管理器,而是使用您必须发送的数据调用回调。有关详细信息和示例代码,请参阅the android documentation on this,但基本上您在DatePickerFragment中定义了一个在选择日期时将调用的界面:

public interface OnDatePickedListener {
    void onDatePicked(Date date);
}

当您的片段附加到活动时,您将其保存为片段的当前侦听器实例。 当您在对话框片段中选择日期时,您将调用监听器的onDatePicked方法。

然后,您的活动会实现此接口以委派给您要更新的片段:

public class MainActivity implements DatePickerFragment.OnDatePickedListner {
    @Override
    public void onDatePicked(Date date) {
        Absences fragment = (Absences) getSupportFragmentManager().findFragmentById(R.id.Absences);
        fragment.updateAbsences();
    }
}

这种关注的主要好处是分离关注点。您的对话框片段不知道拥有它的Activity的任何信息。它只知道必须向所有实现接口的人报告所选日期。然后,只要它们也实现了正确的界面,您就可以在任何其他活动中显示此对话框片段,只要它们也能实现正确的界面。

希望有所帮助!