有没有一种方法可以在一个片段中实现setOnDateListener并将其发送数据到另一个片段?

时间:2019-08-25 22:20:12

标签: java android android-fragments event-listener

我在android studio中工作,想为setOnDateListener对象设置CalendarViewCalendarView对象位于以编程方式生成的片段的内部。唯一的问题是当尝试将数据从日历发送到MainActivity文件时。它总是说一些关于空对象引用的事情。

我已经尝试了一切。目前,我正在尝试使用我没有经验的界面。我已经尝试过将听众转移到任何地方。似乎没有任何作用。这是最低要求(非常抱歉)

MainActivity:

public class MainActivity extends AppCompatActivity implements FragmentEntry.Callback {

    FragmentHome fragmentHome;

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

        ViewPager viewPager = findViewById(R.id.viewpager);
        ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());

        // add the fragments
        adapter.addFragment(new FragmentHome(), "Home");
        adapter.addFragment(new FragmentEntry(), "Entry");
        viewPager.setAdapter(adapter);

        TabLayout tabLayout = findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(viewPager);
    }

    public void sendDate(int day, int month, int year)
    {
        fragmentHome.text(day, month, year);
    }
}

FragmentHome:

    public class FragmentHome extends Fragment {

        // empty constructor, onCreate, and onCreateView

        public void text(int day, int month, int year) {
            TextView textView = getText().findViewById(R.id.textView);
            String text = String.format(R.string.month + "/" + R.string.day + "/" + R.string.year, month, day, year);
            textView.setText(text);
        }
    }

FragmentEntry:

    public class FragmentEntry extends Fragment {

        public Callback callback;

        // empty constructor, onCreate

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View v = inflater.inflate(R.layout.fragment_entry, container, false);

            CalendarView calendarView = v.findViewById(R.id.calendarView);
            calendarView.setOnDateChangeListener(new CalendarView.OnDateChangeListener() {
                @Override
                public void onSelectedDayChange(@NonNull CalendarView calendarView, int y, int m, int d) {
                    callback.sendDate(d, m, y);
        }

        return v;
    }

就像我说过的,我尝试过移动日期监听器,但是它现在在这里。我希望sendDate函数调用能正常运行,但Logcat会相反。一直在说

E/MessageQueue-JNI: java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.fragmentcommunicationtest.FragmentEntry$Callback.sendDate(int, int, int)' on a null object reference

即使不使用接口,我对整个null对象的引用也有完全相同的问题。我不知道要去哪里。我已经尝试了所有方法,并且希望在这一点上它会被我忽略。帮助

2 个答案:

答案 0 :(得分:0)

您没有初始化callback对象,请尝试从MainActivity

adapter.addFragment(new FragmentEntry(this), "Entry");

然后在FragmentEntry中创建一个构造函数,并以callback为参数(我认为这是您要从中进行回调的地方)。

public FragmentEntry(Callback callback) 
{
 this.callback = callback
}

现在回调已初始化。

修改

对于第二期TextView textView = getView().findViewById(R.id.textView);,这是错误的,因为您正在尝试从TextView查找视图。

尝试一下:

创建一个全局TextView,从onCreateView获取视图并将其设置在 回调。

TextView textView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View v = inflater.inflate(R.layout.fragment_home, container, false);
    textView = v.findViewById(R.id.textView);
    return v;
}

然后像这样设置值。

public void text(int day, int month, int year) {
    String text = String.format(R.string.month + "/" + R.string.day + "/" + R.string.year, month, day, year);
    textView.setText(text);
}

编辑2 您说得对fragmentHome确实为空。试试这个

fragmentHome = new FragmentHome(); 
adapter.addFragment(fragmentHome, "Home");

答案 1 :(得分:0)

在片段之间或活动之间进行通信的推荐方法是通过ViewModel组件。请参阅下面的内容,以了解VieModel在您的情况下相对于接口通信方式的优势: https://developer.android.com/topic/libraries/architecture/viewmodel.html#sharing