java - 从父 Activity 访问选项卡式 fragment 方法?

标签 java android android-fragments android-activity

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

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

当我成功选择日期后,我想将信息传递给缺勤 fragment 中的方法。然而,我真的很纠结如何实现这一部分。

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

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

但是,getSupportFragmentManager() 无法从静态上下文中引用,而且我似乎找不到我的 Fragment 的 id。

做了更多研究后,似乎发现这种方法不适用于选项卡式 Activity ,所以我现在不知所措。

有人能指出我正确的方向吗? - 我已经为此努力了一段时间了!

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

最佳答案

这是我的建议。

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

现在,通常 fragment (对话框或其他方式)传递信息的方式是通过接口(interface)回调。因此,您不必像您所做的那样直接访问当前 Activity 的 fragment 管理器,而是使用必须发送的数据调用回调。请参阅the android documentation on this有关详细信息和示例代码,但基本上您需要在 DatePickerFragment 中定义一个接口(interface),该接口(interface)将在选择日期时调用:

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

当您的 fragment 附加到 Activity 时,您可以将其保存为 fragment 的当前监听器实例。 当您在对话框 fragment 中选择日期时,您将调用监听器的 onDatePicked 方法。

然后,您的 Activity 会实现此接口(interface)以委托(delegate)给您要更新的 fragment :

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

这样做的主要好处是关注点分离。您的对话框 fragment 对拥有它的 Activity 一无所知。它只知道必须将所选日期报告给实现该接口(interface)的人。然后,您可以在您需要选择日期的任何其他 Activity 中显示此对话框 fragment ,只要它们也实现了正确的接口(interface)。

希望有帮助!

关于java - 从父 Activity 访问选项卡式 fragment 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44990716/

相关文章:

java - IntelliJ 调试器数据 View

java - 类似于ImageMagick的Java图像编辑库

java - 类转换异常 : MainActivity cannot be cast to Listener

java字符串在创建时未附加到文件中

java - 如何从编译中排除某些文件

android - Android应用在HTC 4g上崩溃

java - 多维 ArrayList 初始化

java - Android:从另一个打开 fragment

android - RecyclerView:没有附加适配器;跳过 fragment 中的布局

java - 用Java编写简单的RTF文件