简体   繁体   English

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

[英]Accessing a tabbed fragment method from the parent activity?

Hi (I'm new to this so you'll have to forgive me) 嗨(我是新来的,所以你必须原谅我)

I currently have a tabbed activity where MainActivity.java is the parent class and Absences.java and Notices.java are the fragments. 我目前有一个选项卡式活动,其中MainActivity.java是父类,而Absences.javaNotices.java是片段。 I have a date picker fragment inside the MainActivity that is run when I tap on an options menu button. 我在MainActivity中有一个日期选择器片段,当我点击选项菜单按钮时,该片段就会运行。

When I've successfully selected my date I want to pass the information to a method in the Absences fragment. 成功选择日期后,我想将信息传递到“缺勤”片段中的方法中。 However, I'm really struggling with how to implement this part. 但是,我真的在如何实现这一部分上很挣扎。

The research I've done seems to suggest this is the solution: 我所做的研究似乎表明这是解决方案:

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

However, getSupportFragmentManager() can't be referenced from a static context and I can't seem to find the id of my Fragment. 但是,无法从静态上下文中引用getSupportFragmentManager()而且我似乎找不到我的Fragment的ID。

After doing a little more research it seemed to reveal this method doesn't work for a tabbed activity so I'm at a loss at this point. 经过更多的研究之后,似乎发现此方法不适用于选项卡式活动,因此我对此感到茫然。

Would someone be able to point me in the right direction? 有人可以指出正确的方向吗? - I've been working on this for quite some time now! -我已经为此工作了很长时间!

SectionsPageAdapter class 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 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 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();
    }
}

--EDIT-- - 编辑 -

Updated code as per suggestion below 根据以下建议更新了代码

Method inside MainActivity MainActivity内部的方法

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

New DatePickerFragment Class 新的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);
    }
}

Here's my suggestion. 这是我的建议。

First, move DatePickerFragment out as its own top-level class. 首先,将DatePickerFragment移出为其自己的顶级类。 I don't know if you have a good reason for having it be a static inner class, but you likely don't need that. 我不知道您是否有充分的理由将其作为静态内部类,但是您可能不需要。

Now then, generally the way you have fragments (dialog or otherwise) pass information is via interface callbacks. 现在,通常,您具有片段(对话或其他方式)传递信息的方式是通过接口回调。 So instead of trying directly access the current activity's fragment manager as your are doing, you invoke a callback with the data you have to send. 因此,您无需像尝试那样直接访问当前活动的片段管理器,而是使用必须发送的数据调用回调。 See the android documentation on this for details and sample code, but basically you'd define an interface in your DatePickerFragment that will be invoked when a date is picked: 有关详细信息和示例代码,请参见android文档 ,但基本上,您需要在DatePickerFragment中定义一个接口,该接口将在选择日期时被调用:

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

When your fragment is attached to the activity, you save that as the fragment's current listener instance. 将片段附加到活动后,将其另存为片段的当前侦听器实例。 When you pick a date in the dialog fragment, you invoke your listener's onDatePicked method. 在对话框片段中选择日期时,将调用侦听器的onDatePicked方法。

Your activity then implements this interface to delegate down to the fragment you want to update: 然后,您的活动将实现此接口,以委托给您要更新的片段:

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

The main benefit to this being separation of concerns. 这样做的主要好处是关注点分离。 Your dialog fragment does not know anything about the Activity that owns it. 您的对话框片段对拥有它的活动一无所知。 It just knows that it has to report the selected date to whomever implements the interface. 它只知道它必须向实现接口的任何人报告选定的日期。 Then you can show this dialog fragment in any other Activity you need to pick a date in as long as they also implement the correct interface. 然后,您可以在您选择日期的任何其他活动中显示此对话框片段,只要它们还实现了正确的界面即可。

Hope that helps! 希望有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM