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

Java 从父活动访问选项卡式片段方法?,java,android,android-fragments,android-activity,Java,Android,Android Fragments,Android Activity,嗨(我是新手,所以你得原谅我) 我目前有一个选项卡式活动,其中MainActivity.java是父类,Absences.java和Notices.java是片段。我在MainActivity中有一个日期选择器片段,当我点击选项菜单按钮时,该片段会运行 成功选择日期后,我希望将信息传递给缺席片段中的方法。然而,我真的很难实现这一部分 我所做的研究似乎表明这是解决方案: Absences fragment= (Absences) getSupportFragmentManager().findFr

嗨(我是新手,所以你得原谅我)

我目前有一个选项卡式活动,其中
MainActivity.java
是父类,
Absences.java
Notices.java
是片段。我在
MainActivity
中有一个日期选择器片段,当我点击选项菜单按钮时,该片段会运行

成功选择日期后,我希望将信息传递给缺席片段中的方法。然而,我真的很难实现这一部分

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

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

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

根据以下建议更新代码

主活动内的方法

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

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

}
    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);
    }
}
这是我的建议

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

现在,让片段(对话框或其他)传递信息的方式通常是通过接口回调。因此,您不必像您正在做的那样直接访问当前活动的片段管理器,而是使用您必须发送的数据调用回调。有关详细信息和示例代码,请参见,但基本上您需要在
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();
    }
}
这样做的主要好处是分离关注点。您的对话框片段对拥有它的活动一无所知。它只知道必须向实现接口的人报告所选日期。然后,您可以在需要选择日期的任何其他活动中显示此对话框片段,只要它们也实现了正确的接口

希望有帮助

这是我的建议

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

现在,让片段(对话框或其他)传递信息的方式通常是通过接口回调。因此,您不必像您正在做的那样直接访问当前活动的片段管理器,而是使用您必须发送的数据调用回调。有关详细信息和示例代码,请参见,但基本上您需要在
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();
    }
}
这样做的主要好处是分离关注点。您的对话框片段对拥有它的活动一无所知。它只知道必须向实现接口的人报告所选日期。然后,您可以在需要选择日期的任何其他活动中显示此对话框片段,只要它们也实现了正确的接口

希望有帮助

你关于“这是灰色的”的评论——这是因为你没有实际使用这个界面。查看我链接到的文档,它向您展示了如何在附加到活动时将接口实例保存在片段中,然后在需要时调用它(在本例中,在
onDateSet
方法中)您关于“这是灰色的”的注释-这是因为您没有实际使用接口。查看我链接到的文档,它向您展示了如何在附加到活动时将接口实例保存在片段中,然后在需要时调用它(在本例中是在
onDateSet
方法中)